class_docstr: Use MLP to fuse different models' features (single-modal and multimodal).
  Specifically, it adapts the features of each model to specified dimensions,
  concatenates the adapted features, and fuses the features through MLP.
docstr: Parameters
  ----------
  prefix
      The fusion model's prefix
  models
      The individual models whose output features will be fused.
  hidden_features
      A list of integers representing the hidden feature dimensions. For example,
      [512, 128, 64] indicates three hidden MLP layers with their corresponding output
      feature dimensions.
  num_classes
      The number of classes.
  adapt_in_features
      Choice of how to adapt the features of each model. We now support
      - min
          Adapt all features to the minimum dimension. For example, if three models have
          feature dimensions [512, 768, 64], it will linearly map all the features to
          dimension 64.
      - max
          Adapt all features to the maximum dimension. For example, if three models have
          feature dimensions are [512, 768, 64], it will linearly map all the features to
          dimension 768.
  activation
      Name of activation function.
  dropout_prob
      Dropout probability.
  normalization
      Name of normalization function.
  loss_weight
      The weight of individual models. For example, if we fuse the features of ViT, CLIP, and BERT,
      The loss will be computed as "loss = fusion_loss + loss_weight(vit_loss + clip_loss + bert_loss)".
      Basically, it supports adding an auxiliary loss for each individual model.
docstr_tok: ["Parameters","--","--","--","--","--","prefix","The","fusion","model","'s","prefix","models","The","individual","models","whose","output","features","will","be","fused",".","hidden_features","A","list","of","integers","representing","the","hidden","feature","dimensions",".","For","example",",","[","512",",","128",",","64","]","indicates","three","hidden","MLP","layers","with","their","corresponding","output","feature","dimensions",".","num_classes","The","number","of","classes",".","adapt_in_features","Choice","of","how","to","adapt","the","features","of","each","model",".","We","now","support","-","min","Adapt","all","features","to","the","minimum","dimension",".","For","example",",","if","three","models","have","feature","dimensions","[","512",",","768",",","64","]",",","it","will","linearly","map","all","the","features","to","dimension","64",".","-","max","Adapt","all","features","to","the","maximum","dimension",".","For","example",",","if","three","models","have","feature","dimensions","are","[","512",",","768",",","64","]",",","it","will","linearly","map","all","the","features","to","dimension","768.","activation","Name","of","activation","function",".","dropout_prob","Dropout","probability",".","normalization","Name","of","normalization","function",".","loss_weight","The","weight","of","individual","models",".","For","example",",","if","we","fuse","the","features","of","ViT",",","CLIP",",","and","BERT",",","The","loss","will","be","computed","as","``","loss","=","fusion_loss","+","loss_weight","(","vit_loss","+","clip_loss","+","bert_loss",")","''",".","Basically",",","it","supports","adding","an","auxiliary","loss","for","each","individual","model","."]
code: def __init__(
      self,
      prefix: str,
      models: list,
      hidden_features: List[int],
      num_classes: int,
      adapt_in_features: Optional[str] = None,
      activation: Optional[str] = "gelu",
      dropout_prob: Optional[float] = 0.5,
      normalization: Optional[str] = "layer_norm",
      loss_weight: Optional[float] = None,
  ):
      """
      Parameters
      ----------
      prefix
          The fusion model's prefix
      models
          The individual models whose output features will be fused.
      hidden_features
          A list of integers representing the hidden feature dimensions. For example,
          [512, 128, 64] indicates three hidden MLP layers with their corresponding output
          feature dimensions.
      num_classes
          The number of classes.
      adapt_in_features
          Choice of how to adapt the features of each model. We now support
          - min
              Adapt all features to the minimum dimension. For example, if three models have
              feature dimensions [512, 768, 64], it will linearly map all the features to
              dimension 64.
          - max
              Adapt all features to the maximum dimension. For example, if three models have
              feature dimensions are [512, 768, 64], it will linearly map all the features to
              dimension 768.
      activation
          Name of activation function.
      dropout_prob
          Dropout probability.
      normalization
          Name of normalization function.
      loss_weight
          The weight of individual models. For example, if we fuse the features of ViT, CLIP, and BERT,
          The loss will be computed as "loss = fusion_loss + loss_weight(vit_loss + clip_loss + bert_loss)".
          Basically, it supports adding an auxiliary loss for each individual model.
      """
      super().__init__(
          prefix=prefix,
          models=models,
          loss_weight=loss_weight,
      )
      logger.debug("initializing MultimodalFusionMLP")
      if loss_weight is not None:
          assert loss_weight > 0
      self.num_classes = num_classes
  
      raw_in_features = [per_model.out_features for per_model in models]
      if adapt_in_features is not None:
          if adapt_in_features == "min":
              base_in_feat = min(raw_in_features)
          elif adapt_in_features == "max":
              base_in_feat = max(raw_in_features)
          else:
              raise ValueError(
                  f"unknown adapt_in_features: {adapt_in_features}"
              )
  
          self.adapter = nn.ModuleList(
              [
                  nn.Linear(in_feat, base_in_feat)
                  for in_feat in raw_in_features
              ]
          )
  
          in_features = base_in_feat * len(raw_in_features)
      else:
          self.adapter = nn.ModuleList(
              [nn.Identity() for _ in range(len(raw_in_features))]
          )
          in_features = sum(raw_in_features)
  
      assert len(self.adapter) == len(self.model)
  
      fusion_mlp = []
      for per_hidden_features in hidden_features:
          fusion_mlp.append(
              MLP(
                  in_features=in_features,
                  hidden_features=per_hidden_features,
                  out_features=per_hidden_features,
                  num_layers=1,
                  activation=activation,
                  dropout_prob=dropout_prob,
                  normalization=normalization,
              )
          )
          in_features = per_hidden_features
      self.fusion_mlp = nn.Sequential(*fusion_mlp)
      # in_features has become the latest hidden size
      self.head = nn.Linear(in_features, num_classes)
      # init weights
      self.adapter.apply(init_weights)
      self.fusion_mlp.apply(init_weights)
      self.head.apply(init_weights)
  
      self.out_features = in_features
      self.name_to_id = self.get_layer_ids()
      self.head_layer_names = [
          n for n, layer_id in self.name_to_id.items() if layer_id == 0
      ]
  
file_path: autogluon/multimodal/src/autogluon/multimodal/models/fusion/fusion_mlp.py
imports: import logging
  from typing import List, Optional
  import torch
  from torch import nn
  from ...constants import AUTOMM, FEATURES, LABEL, LOGITS, WEIGHT
  from ..mlp import MLP
  from ..utils import init_weights, run_model
  from .base import AbstractMultimodalFusionModel
label_desc: Use image node_id 1 to create a new MultimodalFusionMLP object from inherited base classes: AbstractMultimodalFusionModel with example: obj = MultimodalFusionMLP(prefix, models, hidden_features, num_classes, adapt_in_features, activation, dropout_prob, normalization, loss_weight)