class_docstr: A basic MLP attention layer.
class_docstr_tok: ["A","basic","MLP","attention","layer","."]
docstr: input: batch x dim
  context: batch x sourceL x dim
docstr_tok: ["input",":","batch","x","dim","context",":","batch","x","sourceL","x","dim"]
code: def forward(self, input, context, mask=None, attn_only=False):
      """
      input: batch x dim
      context: batch x sourceL x dim
      """
      batch_size = context.size(0)
      source_len = context.size(1)
      dim = context.size(2)
      target = self.linear_in(input)  # batch x dim
      source = self.linear_c(context.contiguous().view(-1, dim)).view(
          batch_size, source_len, dim
      )
      attn = target.unsqueeze(1).expand_as(context) + source
      attn = self.tanh(attn)  # batch x sourceL x dim
      attn = self.linear_v(attn.view(-1, dim)).view(
          batch_size, source_len
      )
  
      if mask is not None:
          attn.masked_fill_(mask, -constant.INFINITY_NUMBER)
  
      attn = self.sm(attn)
      if attn_only:
          return attn
  
      weighted_context = torch.bmm(attn.unsqueeze(1), context).squeeze(
          1
      )
      h_tilde = torch.cat((weighted_context, input), 1)
      h_tilde = self.tanh(self.linear_out(h_tilde))
  
      return h_tilde, attn
  
imports: import logging
  import torch
  import torch.nn
  import math
  import numpy
  import stanza.models.common.seq2seq_constant
label_desc: Use image node_id 2 for calling the BasicAttention obj's underlying member method code with example usage: obj.forward(input, context, mask, attn_only) and returns: h_tilde,  attn, attn