code: def forward(self, bl_hidden, graph_hidden):
      # Compute Eq. 4 from Iterative Answer Prediction with
      # Pointer-Augmented Multimodal Transformers for TextVQA
      # bl_hidden is bs x hidden_size
      # graph_hidden is bs x graph_hidden_size
  
      # Compute BL half
      bl_hidden = self.bl_w(bl_hidden)
      assert bl_hidden.dim() == 2
      bl_hidden = bl_hidden.unsqueeze(1)
  
      # Compute graph hidden half
      # Assume we've already subsampled to only valid answer nodes
      graph_hidden = self.graph_w(graph_hidden)
  
      # Now we have bl_hidden as a bs x 1 x hid vec
      # graph_hidden as a bs x num_nodes x hid vec
  
      # Combine
      scores = torch.matmul(bl_hidden, graph_hidden.transpose(-1, -2))
  
      # Normalize
      scores = scores / math.sqrt(self.hidden_size)
      scores = scores.squeeze(1)
  
      # Scores is now a bs x #nodes matrix
      return scores
  
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 2 for calling the GraphPtrNet obj's underlying member method code with example usage: obj.forward(bl_hidden, graph_hidden) and returns: scores