class_docstr: This class implements content-based attention module for seq2seq
  learning.
  
  Reference: NEURAL MACHINE TRANSLATION BY JOINTLY LEARNING TO ALIGN
  AND TRANSLATE, Bahdanau et.al. https://arxiv.org/pdf/1409.0473.pdf
  
  Arguments
  ---------
  attn_dim : int
      Size of the attention feature.
  output_dim : int
      Size of the output context vector.
  scaling : float
      The factor controls the sharpening degree (default: 1.0).
  
  Example
  -------
  >>> enc_tensor = torch.rand([4, 10, 20])
  >>> enc_len = torch.ones([4]) * 10
  >>> dec_tensor = torch.rand([4, 25])
  >>> net = ContentBasedAttention(enc_dim=20, dec_dim=25, attn_dim=30, output_dim=5)
  >>> out_tensor, out_weight = net(enc_tensor, enc_len, dec_tensor)
  >>> out_tensor.shape
  torch.Size([4, 5])
docstr: Returns the output of the attention module.
  
  Arguments
  ---------
  enc_states : torch.Tensor
      The tensor to be attended.
  enc_len : torch.Tensor
      The real length (without padding) of enc_states for each sentence.
  dec_states : torch.Tensor
      The query tensor.
docstr_tok: ["Returns","the","output","of","the","attention","module",".","Arguments","--","--","--","--","-","enc_states",":","torch.Tensor","The","tensor","to","be","attended",".","enc_len",":","torch.Tensor","The","real","length","(","without","padding",")","of","enc_states","for","each","sentence",".","dec_states",":","torch.Tensor","The","query","tensor","."]
code: def forward(self, enc_states, enc_len, dec_states):
      """Returns the output of the attention module.
  
      Arguments
      ---------
      enc_states : torch.Tensor
          The tensor to be attended.
      enc_len : torch.Tensor
          The real length (without padding) of enc_states for each sentence.
      dec_states : torch.Tensor
          The query tensor.
  
      """
  
      if self.precomputed_enc_h is None:
          self.precomputed_enc_h = self.mlp_enc(enc_states)
          self.mask = length_to_mask(
              enc_len,
              max_len=enc_states.size(1),
              device=enc_states.device,
          )
  
      dec_h = self.mlp_dec(dec_states.unsqueeze(1))
      attn = self.mlp_attn(
          torch.tanh(self.precomputed_enc_h + dec_h)
      ).squeeze(-1)
  
      # mask the padded frames
      attn = attn.masked_fill(self.mask == 0, -np.inf)
      attn = self.softmax(attn * self.scaling)
  
      # compute context vectors
      # [B, 1, L] X [B, L, F]
      context = torch.bmm(attn.unsqueeze(1), enc_states).squeeze(1)
      context = self.mlp_out(context)
  
      return context, attn
  
imports: import torch
  import logging
  import torch.nn
  import numpy
  from typing import Optional
  from speechbrain.dataio.dataio import length_to_mask
  import torch.nn.functional
  import math
label_desc: Use image node_id 3 for calling the ContentBasedAttention obj's underlying member method code with example usage: obj.forward(enc_states, enc_len, dec_states) and returns: context,  attn