code: def forward(
      self,
      input_ids,
      input_mask,
      attention_mask=None,
      token_type_ids=None,
      visual_embeddings=None,
      position_embeddings_visual=None,
      visual_embeddings_type=None,
      image_text_alignment=None,
      masked_lm_labels=None,
      graph_input=None,
  ):
      # If we have a graph input, do the embedding first
      if self.feed_graph_to_vb:
          # Sanity check sizes
          if self.graph_feed_mode == "feed_graph_hid_to_vb":
              assert (
                  graph_input.dim() == 2
                  and graph_input.size(0) == input_ids.size(0)
                  and graph_input.size(1) == self.graph_node_hid_dim
              )
              graph_input = graph_input.unsqueeze(1)  # Add extra dim
          elif self.graph_feed_mode == "feed_top_node_to_vb":
              assert (
                  graph_input.dim() == 3
                  and graph_input.size(0) == input_ids.size(0)
                  and graph_input.size(1) == self.graph_topk
                  and graph_input.size(1) == self.graph_node_hid_dim
              )
          # Do the graph embedding
          graph_input = self.graph_embedding(graph_input)
  
      sequence_output, pooled_output, attention_weights = self.bert(
          input_ids,
          attention_mask,
          token_type_ids,
          visual_embeddings,
          position_embeddings_visual,
          visual_embeddings_type,
          image_text_alignment,
          graph_input,
      )
  
      if self.training_head_type == "nlvr2":
          # 2B * H => B * 2H
          b, h = pooled_output.size()
          pooled_output = torch.cat(
              [pooled_output[: b // 2], pooled_output[b // 2 :]], dim=1
          )
  
      output_dict = {}
      if self.output_attentions:
          output_dict["attention_weights"] = attention_weights
  
      if self.output_hidden_states:
          output_dict["sequence_output"] = sequence_output
          output_dict["pooled_output"] = pooled_output
  
      if self.pooler_strategy == "vqa":
          # In VQA2 pooling strategy, we use representation from second last token
          index_to_gather = input_mask.sum(1) - 2
          pooled_output = torch.gather(
              sequence_output,
              1,
              index_to_gather.unsqueeze(-1)
              .unsqueeze(-1)
              .expand(
                  index_to_gather.size(0), 1, sequence_output.size(-1)
              ),
          )
  
      pooled_output = self.dropout(pooled_output)
      output = self.classifier(pooled_output).squeeze(1)
      return output
  
imports: import logging
  import math
  import os
  import torch
  from mmf.common.registry import registry
  from mmf.models import BaseModel
  from mmf.modules.embeddings import BertVisioLinguisticEmbeddings
  from mmf.utils.configuration import get_mmf_cache_dir
  from mmf.utils.file_io import PathManager
  from mmf.utils.modeling import get_optimizer_parameters_for_bert
  from mmf.utils.transform import transform_to_batch_sequence, transform_to_batch_sequence_dim
  from omegaconf import OmegaConf
  from torch import nn
label_desc: Use image node_id 3 for calling the VisualBERTForClassification obj's underlying member method code with example usage: obj.forward(input_ids, input_mask, attention_mask, token_type_ids, visual_embeddings, position_embeddings_visual, visual_embeddings_type, image_text_alignment, masked_lm_labels, graph_input) and returns: output