code: def forward(self, features, mask, lengths):
      batch_size, seq_len, input_dim = features.shape
      b1 = torch.matmul(
          features.unsqueeze(1), self.genpool_w1_head.unsqueeze(0)
      )
      b1 += self.genpool_b1_head.unsqueeze(1).unsqueeze(0)
      b1 = self.activation(self.dropout1(b1))
      b1 = torch.matmul(b1, self.genpool_w2_head.unsqueeze(0))
      b1 += self.genpool_b2_head.unsqueeze(1).unsqueeze(0)
      b1 = self.dropout2(b1)
      b1.masked_fill_((mask == 0).unsqueeze(1).unsqueeze(-1), -1e19)
  
      smweights = self.softmax(b1 / self.softmax_temp)
      smweights = self.dropout3(smweights)
      smweights = smweights.transpose(1, 2).reshape(
          -1, seq_len, input_dim
      )
      return (features * smweights).sum(dim=1)
  
imports: from collections import OrderedDict
  import os
  import numpy
  import torch
  from torch import nn
  from gluoncv.torch.utils.coot_utils import truncated_normal_fill
label_desc: Use image node_id 3 for calling the AtnPool obj's underlying member method code with example usage: obj.forward(features, mask, lengths) and returns: unknown