def forward(self, decoder_hidden, encoder_outputs, input):
    seq = 0
    weights = []
    i = 0
    output = torch.zeros(self.batch_size, self.vocab_size)
    for i in range(len(encoder_outputs)):
        weights.append(self.attn(torch.cat((decoder_hidden[0][:].squeeze(0), encoder_outputs[i], output), dim=1)))
    normalized_weight = F.softmax(torch.cat(weights, 1), 1)
    normalized_weights = normalized_weight
    attn_applied = torch.bmm(normalized_weight.unsqueeze(1), encoder_outputs.transpose(0, 1))
    input_lstm = torch.cat((attn_applied.transpose(0, 1)[0], output), dim=1)
    (output_, hidden) = self.lstm(input_lstm.unsqueeze(0), decoder_hidden)
    output = self.final(output_[0])
    out = F.softmax(output, 1)
    return out
def forward(self, decoder_hidden, encoder_outputs, input):
    seq = 0
    weights = []
    i = 0
    output = torch.zeros(self.batch_size, self.vocab_size)
    for i in range(len(encoder_outputs)):
        weights.append(self.attn(torch.cat((decoder_hidden[0][:].squeeze(0), encoder_outputs[i], output), dim=1)))
    normalized_weight = F.softmax(torch.cat(weights, 1), 1)
    normalized_weights = normalized_weight
    attn_applied = torch.bmm(normalized_weight.unsqueeze(1), encoder_outputs.transpose(0, 1))
    input_lstm = torch.cat((attn_applied.transpose(0, 1)[0], output), dim=1)
    (output_, hidden) = self.lstm(input_lstm.unsqueeze(0), decoder_hidden)
    output = self.final(output_[0])
    out = F.softmax(output, 1)
    return out