class_docstr: Poly-encoder model.
  
  See https://arxiv.org/abs/1905.01969 for more details
class_docstr_tok: ["Poly-encoder","model",".","See","https",":","\/\/arxiv.org\/abs\/1905.01969","for","more","details"]
code: def __init__(self, opt, dict_, null_idx):
      super(PolyEncoderModule, self).__init__()
      self.null_idx = null_idx
      self.encoder_ctxt = self.get_encoder(
          opt=opt,
          dict_=dict_,
          null_idx=null_idx,
          reduction_type=None,
          for_context=True,
      )
      self.encoder_cand = self.get_encoder(
          opt=opt,
          dict_=dict_,
          null_idx=null_idx,
          reduction_type=opt["reduction_type"],
          for_context=False,
      )
  
      self.type = opt["polyencoder_type"]
      self.n_codes = opt["poly_n_codes"]
      self.attention_type = opt["poly_attention_type"]
      self.attention_num_heads = opt["poly_attention_num_heads"]
      self.codes_attention_type = opt["codes_attention_type"]
      self.codes_attention_num_heads = opt["codes_attention_num_heads"]
      embed_dim = opt["embedding_size"]
  
      # In case it's a polyencoder with code.
      if self.type == "codes":
          # experimentally it seems that random with size = 1 was good.
          codes = torch.empty(self.n_codes, embed_dim)
          codes = torch.nn.init.uniform_(codes)
          self.codes = torch.nn.Parameter(codes)
  
          # The attention for the codes.
          if self.codes_attention_type == "multihead":
              self.code_attention = MultiHeadAttention(
                  opt,
                  self.codes_attention_num_heads,
                  embed_dim,
                  opt["dropout"],
              )
          elif self.codes_attention_type == "sqrt":
              self.code_attention = PolyBasicAttention(
                  self.type,
                  self.n_codes,
                  dim=2,
                  attn="sqrt",
                  get_weights=False,
              )
          elif self.codes_attention_type == "basic":
              self.code_attention = PolyBasicAttention(
                  self.type,
                  self.n_codes,
                  dim=2,
                  attn="basic",
                  get_weights=False,
              )
  
      # The final attention (the one that takes the candidate as key)
      if self.attention_type == "multihead":
          self.attention = MultiHeadAttention(
              opt,
              self.attention_num_heads,
              opt["embedding_size"],
              opt["dropout"],
          )
      else:
          self.attention = PolyBasicAttention(
              self.type,
              self.n_codes,
              dim=2,
              attn=self.attention_type,
              get_weights=False,
          )
  
imports: from parlai.core.params import ParlaiParser
  from typing import Any, Dict, Optional, Tuple
  import torch
  from parlai.core.opt import Opt
  from parlai.core.torch_ranker_agent import TorchRankerAgent
  from parlai.core.torch_agent import Batch
  from parlai.utils.misc import recursive_getattr
  from parlai.utils.logging import logging
  from .biencoder import AddLabelFixedCandsTRA
  from .modules import BasicAttention, MultiHeadAttention, TransformerEncoder
  from .transformer import TransformerRankerAgent
label_desc: Use image node_id 1 to create a new PolyEncoderModule object from inherited base classes: torch.nn with example: obj = PolyEncoderModule(opt, dict_, null_idx)