class_docstr: Implements a 'two-tower' MLPDecoder: one for left and one for right
class_docstr_tok: ["Implements","a","'two-tower","'","MLPDecoder",":","one","for","left","and","one","for","right"]
code: def __init__(
      self,
      config: Config,
      right_dim: int,
      left_dim: int,
      to_dim: int,
      export_type=ExportType.NONE,
  ) -> None:
      super().__init__(config)
  
      self.mlp_for_right = MLPDecoderTwoTower.get_mlp(
          right_dim,
          0,
          config.right_hidden_dims,
          config.layer_norm,
          config.dropout,
          config.activation,
          export_embedding=True,
      )
      self.mlp_for_left = MLPDecoderTwoTower.get_mlp(
          left_dim,
          0,
          config.left_hidden_dims,
          config.layer_norm,
          config.dropout,
          config.activation,
          export_embedding=True,
      )
  
      if config.dense_tower_dims is None:
          from_dim = (
              config.right_hidden_dims[-1] + config.left_hidden_dims[-1]
          )
          self.concat_dense = False
      else:
          self.mlp_for_dense = MLPDecoderTwoTower.get_mlp(
              from_dim=config.dense_tower_dims[0],
              to_dim=config.dense_tower_dims[-1],
              hidden_dims=config.dense_tower_dims[1:-1],
              layer_norm=config.layer_norm,
              dropout=config.dropout,
              activation=config.activation,
          )
          from_dim = (
              config.right_hidden_dims[-1]
              + config.left_hidden_dims[-1]
              + config.dense_tower_dims[-1]
          )
          self.concat_dense = True
  
      self.mlp = MLPDecoderTwoTower.get_mlp(
          from_dim,
          to_dim,
          config.hidden_dims,
          config.layer_norm,
          config.dropout,
          config.activation,
      )
  
      # load model
      if config.load_model_path:
          with PathManager.open(config.load_model_path, "rb") as f:
              model = torch.load(
                  f,
                  map_location=lambda s, l: default_restore_location(
                      s, "cpu"
                  ),
              )
          mlp_state = {
              k.replace("decoder.", ""): v
              for k, v in model["model_state"].items()
              if k.startswith("decoder.mlp")
              or k.startswith("decoder.mlp_for_right")
              or k.startswith("decoder.mlp_for_left")
              or k.startswith("decoder.mlp_for_dense")
          }
          if mlp_state["mlp.0.weight"].shape[1] != from_dim:
              mlp_state = {
                  k: v
                  for k, v in mlp_state.items()
                  if not k.startswith("mlp.")
              }
              print("top mlp weights not loaded")
          self.load_state_dict(mlp_state, strict=config.load_strict)
          print("loaded mlp state")
  
      self.out_dim = to_dim
      self.export_type = export_type
      log_class_usage
  
file_path: pytext/pytext/models/decoders/mlp_decoder_two_tower.py
imports: from enum import Enum
  from typing import List, Optional
  import torch
  import torch.nn
  from pytext.config.module_config import Activation
  from pytext.models.decoders.decoder_base import DecoderBase
  from pytext.optimizer import get_activation
  from pytext.utils import precision
  from pytext.utils.file_io import PathManager
  from pytext.utils.usage import log_class_usage
  from torch.serialization import default_restore_location
label_desc: Use image node_id 1 to create a new MLPDecoderTwoTower object from inherited base classes: DecoderBase with example: obj = MLPDecoderTwoTower(config, right_dim, left_dim, to_dim, export_type)