class_docstr: ImageSeq2seqAgent Agent.
  
  Combines a transformer generator with images.
class_docstr_tok: ["ImageSeq2seqAgent","Agent",".","Combines","a","transformer","generator","with","images","."]
docstr: Override for custom loading.
  
  Reasons:
      1. When using an init model without an image encoder
      2. We decide to add segment embeddings after the fact.
      3. When using an init model with only an encoder provided
          In this case, we may need to add the START token to the state_dict
      4. When using an init model without image tokens in the embeddings.
          This is only the case if the embs differ by 2 in dimension 0
docstr_tok: ["Override","for","custom","loading",".","Reasons",":","1",".","When","using","an","init","model","without","an","image","encoder","2",".","We","decide","to","add","segment","embeddings","after","the","fact",".","3",".","When","using","an","init","model","with","only","an","encoder","provided","In","this","case",",","we","may","need","to","add","the","START","token","to","the","state_dict","4",".","When","using","an","init","model","without","image","tokens","in","the","embeddings",".","This","is","only","the","case","if","the","embs","differ","by","2","in","dimension","0"]
code: def load_state_dict(self, state_dict: Dict[str, torch.Tensor]):
      """
      Override for custom loading.
  
      Reasons:
          1. When using an init model without an image encoder
          2. We decide to add segment embeddings after the fact.
          3. When using an init model with only an encoder provided
              In this case, we may need to add the START token to the state_dict
          4. When using an init model without image tokens in the embeddings.
              This is only the case if the embs differ by 2 in dimension 0
      """
      state_dict[
          "encoder.dummy_image_enc"
      ] = self.model.encoder.dummy_image_enc
      state_dict["encoder.ones_mask"] = self.model.encoder.ones_mask
      # Case 1 -> No Image Encoder
      if "encoder.image_encoder.0.weight" not in state_dict:
          for (
              k,
              v,
          ) in self.model.encoder.image_encoder.state_dict().items():
              state_dict[f"encoder.image_encoder.{k}"] = v
  
      # case 2 -> Segment embeddings in new model
      if (
          self.opt.get("n_segments", 0) >= 1
          and "encoder.segment_embeddings.weight" not in state_dict
      ):
          state_dict[
              "encoder.segment_embeddings.weight"
          ] = self.model.encoder.segment_embeddings.weight
  
      # Case 3 -> Only an Encoder provided
      if not (any("decoder" in state_key for state_key in state_dict)):
          for k, v in self.model.decoder.state_dict().items():
              state_dict[f"decoder.{k}"] = v
          state_dict["decoder.embeddings.weight"] = state_dict[
              "embeddings.weight"
          ]
          if "START" not in state_dict:
              state_dict["START"] = self.model.START
  
      if self.opt["init_model"] is not None:
          try:
              self.model.load_state_dict(state_dict)
              return
          except RuntimeError as e:
              # Case 4 --> Check for Embedding Diffs. Make sure dims match up
              embs = state_dict["embeddings.weight"]
              enc_embs = state_dict["encoder.embeddings.weight"]
              dec_embs = state_dict["decoder.embeddings.weight"]
              init_embs = self.model.embeddings.weight
              if (
                  embs.shape[0] + 2 != init_embs.shape[0]
                  or embs.shape[1] != init_embs.shape[1]
              ):
                  raise e
  
              state_dict.update(
                  {
                      "embeddings.weight": torch.cat(
                          (
                              embs.to(
                                  init_embs.device,
                                  dtype=init_embs.dtype,
                              ),
                              init_embs[-2:, :],
                          )
                      ),
                      "encoder.embeddings.weight": torch.cat(
                          (
                              enc_embs.to(
                                  init_embs.device,
                                  dtype=init_embs.dtype,
                              ),
                              init_embs[-2:, :],
                          )
                      ),
                      "decoder.embeddings.weight": torch.cat(
                          (
                              dec_embs.to(
                                  init_embs.device,
                                  dtype=init_embs.dtype,
                              ),
                              init_embs[-2:, :],
                          )
                      ),
                  }
              )
              pct_init = round(embs.shape[0] / len(self.dict) * 100, 1)
              print(
                  f"Initialized embeddings for {embs.shape[0]} tokens ({pct_init}%)"
              )
  
      self.model.load_state_dict(state_dict)
  
imports: from typing import Optional
  from parlai.core.params import ParlaiParser
  from parlai.core.opt import Opt
  from typing import Dict, List, Tuple
  import torch
  from .modules import ImageSeq2seqModel, FusionType
  from parlai.agents.transformer.transformer import TransformerGeneratorAgent
  from parlai.core.dict import DictionaryAgent
  from parlai.core.torch_agent import Batch
  from parlai.core.torch_image_agent import TorchImageAgent
label_desc: Use image node_id 8 for calling the ImageSeq2seqAgent obj's underlying member method code with example usage: obj.load_state_dict(state_dict) without return types