'Input shapes:
x = batch * len1 * h
y = batch * len2 * h
y_mask = batch * len2
Output shapes:
matched_seq = batch * len1 * h'

def forward(self, x, y, y_mask):

    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
    scores = x_proj.bmm(y_proj.transpose(2, 1))
    y_mask = y_mask.unsqueeze(1).expand(scores.size())
    scores.data.masked_fill_(y_mask.data, (- float('inf')))
    alpha_flat = F.softmax(scores.view((-1), y.size(1)))
    alpha = alpha_flat.view((-1), x.size(1), y.size(1))
    matched_seq = alpha.bmm(y)
    return matched_seq
