python-pytorch seq2seq+luong attention笔记1.0.10

本文详细记录了使用PyTorch实现Seq2Seq模型结合Luong Attention的过程,包括LSTM数据尺寸、Attention机制的三种算法、模型的编码器和解码器设计以及训练和预测中的数据处理。还提到了在实现过程中可能遇到的问题及解决方案。
摘要由CSDN通过智能技术生成

记录

  • 2024年5月14日09:27:39----0.5.10
  • 2024年5月14日11:32:47----0.5.12
  • 2024年5月14日11:51:03----1.0.0
  • 2024年5月15日13:57:25----1.0.3
  • 2024年5月19日16:21:17----1.0.10

1. LSTM模型的数据size

一定是按这个来:维度(batch_size, seq_length, embedding_dim) 是一个三维的tensor;其中,batch_size指每次输入的文本数量;seq_length指每个文本的词语数或者单字数;embedding_dim指每个词语或者每个字的向量长度。

2. 关于LSTM的输入数据包含hn和cn时,hn和cn的size

LSTM的输入数据是上个时间窗的hn和cn时,hn和cn的size要求一定是和LSTM模型参数吻合。公式是(laynum,batchsize,hidden or embeding size)或者(batchsize,hidden or embeding size)。

3. LSTM参数中默认batch_first

其实改变的是模型的hn和cn的size,不改变output的size。因为,cn和hn的size是和batch_size有关系的,是layernum、batch_size、hidden_size

4. Attention机制的三种算法

这里使用的是luong的attention,计算权重的方法有dot 、general、concat三种,常见使用general算法。

general大概思路是:
计算分数:decoder中LSTM的output和encoder的output做bmm计算
计算权重:将计算出来的分数做softmax,得到行上的概率分布或者权重
计算新向量:将权重和encoder的outpu再做bmm计算
拼接decoder的output和新向量
对新的拼接结果做tanh计算
最后全连接到vocab_size

5. decoder中使用注意力的步骤

  • 计算分数score
  • 计算权重at
  • 计算新的context向量ct
  • 拼接ct和decoder_ht
  • 做tanh计算
  • 使用tanh结果做全连接预测

6. 模型的编码器

思路很简单,就是将word2index后,通过embedding,将数据给LSTM模型就可以了,返回的是 LSTM的output、hn、cn。
当前你可以根据自己的习惯,在使用LSTM时候增加参数batch_fist或者bidirectional。

此时inputx的是word2index后的数据。

class encoder(nn.Module):
    def __init__(self):
        super(encoder, self).__init__()
        self.embedding=nn.Embedding(vocab_size,n_hidden)
        self.lstm=nn.LSTM(n_hidden,n_hidden*2,batch_first=False)
        
    def forward(self, inputx):
        embeded=self.embedding(inputx.long())
        output,(encoder_h_n, encoder_c_n)=self.lstm(embeded.permute(1,0,2))
        return output,(encoder_h_n,encoder_c_n)

7. 模型的解码器

将解码器的输入embedding后,加上编码器的outout、hn、cn,给LSTM模型输出ouput、hn、cn,做general的attention,最终返回新的LSTM的output、hn、cn。

class lstm_decoder(nn.Module):
    def __init__(self):
        super(lstm_decoder, self).__init__()
        self.embedding=nn.Embedding(vocab_size,embedding_size)
        self.decoder = nn.LSTM(embedding_size, n_hidden * 2, 1,batch_first=False)
        self.fc = nn.Linear(n_hidden * 2, num_classes)
 
    def forward(self, input_x, encoder_output, hn, cn):
        embeded=self.embedding(input_x)
        decoder_output, (decoder_h_n, decoder_c_n) = self.decoder(embeded.float().permute(1,0,2), (hn, cn))
       
        decoder_output = decoder_output.permute(1, 0, 2)
        encoder_output = encoder_output.permute(1, 0, 2)

		# 下面是实现attention编码
		
        # 计算分数score
        decoder_output_score = decoder_output.bmm(encoder_output.permute(0,2,1))
        # 计算权重at
        at = nn.functional.softmax(decoder_output_score, dim=2)
        # 计算新的context向量ct
        ct = at.bmm(encoder_output)
        # 拼接ct和decoder_ht
        ht_joint = torch.cat((ct, decoder_output), dim=2)
        # 做tanh计算
        fc_joint = torch.tanh(self.att_joint(ht_joint))
        # 全连接做预测
        fc_out = self.fc(fc_joint)
        
		# 实现attention编码结束
        return fc_out, decoder_h_n, decoder_c_n

8. 最终模型

在训练时候,encoder的output、hn、cn作为decoder的的输入一部分。最终模型的输出和target数据(view(-1))计算loss。

pred = model(encoder_input, decoder_input, 1)
loss = criterion(pred.reshape(-1, vocab_size), decoder_t
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值