class_docstr: A bilinear attention layer over a sequence X w.r.t y:
  * o_i = softmax(x_i'Wy) for x_i in X.
  
  Optionally don't normalize output weights.
docstr: x = batch * len * h1
  y = batch * h2
  x_mask = batch * len
docstr_tok: ["x","=","batch","*","len","*","h1","y","=","batch","*","h2","x_mask","=","batch","*","len"]
code: def forward(self, x, y, x_mask):
      """
      x = batch * len * h1
      y = batch * h2
      x_mask = batch * len
      """
      Wy = self.linear(y) if self.linear is not None else y
      xWy = x.bmm(Wy.unsqueeze(2)).squeeze(2)
      xWy.data.masked_fill_(x_mask.data, -float("inf"))
      if self.training:
          # In training we output log-softmax for NLL
          alpha = F.log_softmax(xWy)
      else:
          # ...Otherwise 0-1 probabilities
          alpha = F.softmax(xWy)
      return alpha
  
imports: import torch
  import torch.nn
  import torch.nn.functional
  from torch.autograd import Variable
  import sru
label_desc: Use image node_id 2 for calling the BilinearSeqAttn obj's underlying member method code with example usage: obj.forward(x, y, x_mask) and returns: alpha