class_docstr: Given sequences X and Y, match sequence Y to each element in X.
  * o_i = sum(alpha_j * y_j) for i in X
  * alpha_j = softmax(y_j * x_i)
docstr: Input shapes:
      x = batch * len1 * h
      y = batch * len2 * h
      y_mask = batch * len2
  Output shapes:
      matched_seq = batch * len1 * h
docstr_tok: ["Input","shapes",":","x","=","batch","*","len1","*","h","y","=","batch","*","len2","*","h","y_mask","=","batch","*","len2","Output","shapes",":","matched_seq","=","batch","*","len1","*","h"]
code: def forward(self, x, y, y_mask):
      """Input shapes:
          x = batch * len1 * h
          y = batch * len2 * h
          y_mask = batch * len2
      Output shapes:
          matched_seq = batch * len1 * h
      """
      # Project vectors
      if self.linear:
          x_proj = self.linear(x.view(-1, x.size(2))).view(x.size())
          x_proj = F.relu(x_proj)
          y_proj = self.linear(y.view(-1, y.size(2))).view(y.size())
          y_proj = F.relu(y_proj)
      else:
          x_proj = x
          y_proj = y
  
      # Compute scores
      scores = x_proj.bmm(y_proj.transpose(2, 1))
  
      # Mask padding
      y_mask = y_mask.unsqueeze(1).expand(scores.size())
      scores.data.masked_fill_(y_mask.data, -float("inf"))
  
      # Normalize with softmax
      alpha_flat = F.softmax(scores.view(-1, y.size(1)))
      alpha = alpha_flat.view(-1, x.size(1), y.size(1))
  
      # Take weighted average
      matched_seq = alpha.bmm(y)
      return matched_seq
  
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 SeqAttnMatch obj's underlying member method code with example usage: obj.forward(x, y, y_mask) and returns: matched_seq