code: def forward(self, image_feat, question_embedding, image_locs=None):
      # N x K x joint_dim
      joint_feature = self.combination_layer(
          image_feat, question_embedding
      )
      # N x K x n_att
      raw_attn = self.transform(joint_feature)
  
      if self.normalization.lower() == "softmax":
          attention = nn.functional.softmax(raw_attn, dim=1)
          if image_locs is not None:
              masked_attention = self._mask_attentions(
                  attention, image_locs
              )
              masked_attention_sum = torch.sum(
                  masked_attention, dim=1, keepdim=True
              )
              masked_attention_sum += (
                  masked_attention_sum.eq(0).float() + self.EPS
              )
              masked_attention = masked_attention / masked_attention_sum
          else:
              masked_attention = attention
  
      elif self.normalization.lower() == "sigmoid":
          attention = torch.sigmoid(raw_attn)
          masked_attention = attention
          if image_locs is not None:
              masked_attention = self._mask_attentions(
                  attention, image_locs
              )
  
      return masked_attention
  
imports: import math
  from typing import Optional, Tuple, Type
  import torch
  from mmf.modules.layers import GatedTanh, ModalCombineLayer, TransformLayer
  from torch import nn
label_desc: Use image node_id 3 for calling the TopDownAttention obj's underlying member method code with example usage: obj.forward(image_feat, question_embedding, image_locs) and returns: masked_attention