0、引言:
承接上一篇,现在继续对于seq2seq模型进行讲解,decoder部分是和encoder部分对应的,层数、隐藏层、单元数都要对应。
1、LSTM Seq2Seq Decoder
Decoder只执行一个解码步骤。第一层将从前一个时间步接收隐藏和单元状态,并通过将当前的token 传给LSTM,进一步产生一个新的隐藏和单元状态。
Decoder的初始隐藏和单元状态是我们的上下文向量,它们是来自同一层的Encoder的最终隐藏和单元状态。接下来将隐藏状态传递给Linear层,预测目标序列下一个标记应该是什么。
Encoder输入参数:
- output_dim将要输入到Decoder的one-hot向量,这个和输出词汇大小一致,就是输出字典长度
- emb_dim嵌入层的维度,这一层将one-hot向量转为密度向量,256
词嵌入在 pytorch 中只需要调用 torch.nn.Embedding(m, n) 就可以了,m 表示单词的总数目,n 表示词嵌入的维度,是一种降维,相当于是一个大矩阵,矩阵的每一行表示一个单词。 - hid_dim隐藏和cell的状态维度,512
- n_layers RNN层数,这里就是2
- dropout是要使用的丢失量。这是一个防止过度拟合的正则化参数,0.5
Encoder返回参数:
- prediction,预测
- hidden,隐藏状态
- cell,单元状态
看一下实现
class Decoder(nn.Module):
def __init__(self, output_dim, emb_dim, hid_dim, n_layers, dropout):
super(Decoder,self).__init__()
self.emb_dim=emb_dim
self.hid_dim=hid_dim
self.output_dim=output_dim
self.n_layers=n_layers
self.dropout=dropout
self.embedding=nn.Embedding(output_dim,emb_dim)
self.rnn=nn.LSTM(emb_dim,hid_dim,n_layers,dropout=dropout)
self.out=nn.Linear(hid_dim,output_dim)
self.dropout=nn.Dropout(dropout)
def forward(self, input,hidden,cell):
# torch.unsqueeze()这个函数主要是对数据维度进行扩充。给指定位置加上维数为一的维度,比如原本有个三行的数据(3),在0的位置加了一维就变成一行三列(1,3)
input=input.unsqueeze(0)
embedded=self.dropout