code: def process_feature_embedding(
      self,
      attr,
      sample_list,
      text_embedding_total,
      extra=None,
      batch_size_t=None,
  ):
      if extra is None:
          extra = []
      feature_embeddings = []
      feature_attentions = []
      features = []
      batch_size_t = (
          sample_list.get_batch_size()
          if batch_size_t is None
          else batch_size_t
      )
  
      # Convert list of keys to the actual values
      extra = sample_list.get_fields(extra)
  
      feature_idx = 0
  
      # Get all of the features, which are in the form, "image_feature_0"
      # "image_feature_1" ...
      while True:
          feature = getattr(
              sample_list, f"{attr}_feature_{feature_idx:d}", None
          )
          if feature is None:
              break
          feature_idx += 1
          feature = feature[:batch_size_t]
          features.append(feature)
  
      feature_encoders = getattr(self, attr + "_feature_encoders")
      # Each feature should have a separate image feature encoders
      assert len(features) == len(feature_encoders), (
          "Number of feature encoders, {} are not equal "
          "to number of features, {}.".format(
              len(feature_encoders), len(features)
          )
      )
  
      # Now, iterate to get final attended image features
      for i, feature in enumerate(features):
          # Get info related to the current feature. info is generally
          # in key of format "image_info_0" for 0th feature
          feature_info = getattr(sample_list, f"{attr}_info_{i:d}", {})
          # For Pythia, we need max_features to mask attention
          feature_dim = getattr(feature_info, "max_features", None)
          if feature_dim is not None:
              feature_dim = feature_dim[:batch_size_t]
  
          # Attribute in which encoders are saved, for "image" it
          # will be "image_feature_encoders", other example is
          # "context_feature_encoders"
          encoders_attr = attr + "_feature_encoders"
          feature_encoder = getattr(self, encoders_attr)[i]
  
          # Encode the features
          encoded_feature = feature_encoder(feature)
  
          projector_attr = attr + "_feature_projectors"
          feature_projector = getattr(self, projector_attr)[i]
  
          encoded_feature = feature_projector(encoded_feature)
          # Get all of the feature embeddings
          list_attr = attr + "_feature_embeddings_list"
          feature_embedding_models = getattr(self, list_attr)[i]
  
          # Forward through these embeddings one by one
          for feature_embedding_model in feature_embedding_models:
              inp = (
                  encoded_feature,
                  text_embedding_total,
                  feature_dim,
                  extra,
              )
  
              embedding, attention = feature_embedding_model(*inp)
              feature_embeddings.append(embedding)
              feature_attentions.append(attention.squeeze(-1))
  
      # Concatenate all features embeddings and return along with attention
      feature_embedding_total = torch.cat(feature_embeddings, dim=1)
      return feature_embedding_total, feature_attentions
  
imports: import copy
  import omegaconf
  import torch
  from mmf.common.registry import registry
  from mmf.models.base_model import BaseModel
  from mmf.modules.embeddings import ImageFeatureEmbedding, MultiHeadImageFeatureEmbedding, PreExtractedEmbedding, TextEmbedding
  from mmf.modules.layers import ClassifierLayer, ModalCombineLayer
  from mmf.utils.build import build_image_encoder
  from torch import nn
label_desc: Use image node_id 6 for calling the PythiaMultiHead obj's underlying member method code with example usage: obj.process_feature_embedding(attr, sample_list, text_embedding_total, extra, batch_size_t) and returns: feature_embedding_total,  feature_attentions