神经网络中的Attention-4.Seq2Seq的实现
作者:互联网
在上一篇文章中,我们看到了如何为Seq2Seq准备机器翻译数据。在这篇文章中,让我们用Pytorch和准备好的数据来实现Cho et al. (2014) 描述的Seq2Seq模型。
数据预处理
在数据处理之后,我们有四个包含学习Seq2Seq模型的关键信息的变量。在之前的文章中,我们将它们命名为eng_words, deu_words, eng_sentences, deu_sentences。eng_words和deu_words包含源语(英语)和目标语(德语)句子中独特的单词。在我处理过的数据中,有9253个英语单词和16393个德语单词,但请注意,结果可能有所不同,因为我们随机抽取了5万个句子。
eng_sentences和deu_sentences包含源(英语)和目标(德语)的句子,其中的单词根据eng_words和deu_words列表中的位置被索引。例如,列表中的第一个元素是[8837, 1306, 1530, 792, 7046, 2340, 5584, 6017, 2727, 3900, 8326]和[15642, 5568, 2353, 3004, 14139, 3635, 15381, 11161, 15616, 14728]。它们对应于英语和德语句子['<sos>', 'i', 'would', 'rather', 'let', 'him', 'have', 'his', 'own', 'way', '<eos>']和['<sos>', 'ich', 'würde', 'ihn', 'lieber', 'seinem', 'eigenen', 'weg', 'überlassen', '<eos>']。
参数设置
现在,让我们继续为Seq2Seq模型设置超参数。关键参数及其说明如下。
-
MAX_SENT_LEN: 源(英文)句子的最大句子长度
-
ENG_VOCAB_SIZE, DEU_VOCAB_SIZE: 分别用英语和德语表示的唯一标记(单词)的数量
-
NUM_EPOCHS: 训练Seq2Seq模型的轮数
-
HIDDEN_SIZE: LSTM(或任意RNN变体)中隐藏空间的维数
-
EMBEDDING_DIM: 词嵌入空间的维数
我们设置如下参数。注意,NUM_EPOCHS、HIDDEN_SIZE和embeddding_dim变量可以像在任何其他神经网络体系结构中一样由用户任意设置。强烈建议您测试其他参数设置并比较结果。
Pytorch中的RNN
在实现编码器和解码器之前,让我们简要回顾一下RNNr的内部工作原理以及它们在Pytorch中是如何实现的。我们将实现 Long Short-Term Memory(LSTM),它是RNN的一种流行变体。
rnn通常用于在连续的时间步中对输入之间的时间依赖性进行建模。与前馈神经网络不同,它们在网络中有“循环”,让信息在时间步之间流动。这些信息以“隐藏状态”的形式存储和传递。“对于每个输入(xi),都有一个对应的隐藏状态(hi),它保存了第i步的信息。这个隐藏状态也是下一个xi+1步的输入。”在第一个时间步(0)时,它们被随机初始化。
除了隐藏状态之外,还有一些附加信息被传递到下一个状态,即单元状态(ci)。它背后的数学运算很复杂,但我不会详细讲。为了简单起见,我们可以将其视为本文中另一种类型的隐藏状态。更多信息,请参阅Hochreiter et al. (1997)。
一旦我们理解了RNN的内部工作原理,用Pytorch实现它就相当简单了。
创建LSTM层:有几个参数需要确定。一些基本的参数包括input_size、hidden_size和num_layers。input_size可以看作是一些特征。每个时间戳中的每个输入都是一个n维向量,n = input_size。hidden_size是隐藏状态的维度。每个隐藏状态都是一个m维向量,m = hidden_size。最后num_layers决定LSTM层的层数。将其设置为3将使其成为一个深度LSTM。
确定输入大小:LSTM层输入的形状是(seq_len, batch_size, input_size)。seq_len确定序列的长度或时间步长。在机器翻译任务中,这应该是实例中的源(或目标)单词的数量。input_size应该与创建LSTM层时定义的大小相同。
初始化隐藏状态和单元格状态:隐藏状态和单元格状态通常具有相同的形状(num_layers, batch_size, hidden_size)。注意,我们不需要考虑seq_len,因为隐藏的单元状态在每个时间步都会刷新。
将输入和隐藏/神经元状态传递给LSTM:现在我们只需要将输入和状态传递给LSTM层。注意,隐藏状态和神经元状态是在一个元组中提供的(h0, c0)。输出大小与输入相同。
编码器
现在,我们要为Seq2Seq构建神经网络体系结构。这里,我们分别构建编码器和解码器网络,因为这样可以更好地理解它。
编码器是一种相对简单的神经网络,由嵌入层和RNN层组成。我们将源句中的每个单词(本例中是英语单词)嵌入到LSTM中。注意,我们必须为编码器网络设置三个参数——vocab_size、hidden_size和embeddding_dim。它们将对应于上面定义的ENG_VOCAB_SIZE、HIDDEN_SIZE和EMBEDDING_DIM变量。
来自最终源单词的“隐藏状态”(h0)将被记忆并作为输入传递到解码器。这是一个固定大小的向量“整个输入序列的摘要c”。
解码器
最后,我们必须定义解码器网络。解码器与编码器非常相似,只是有一点不同。除隐藏状态外的其他信息在编码器网络中被丢弃。换句话说,来自输入句子的所有信息都在隐藏状态下进行汇总。
然而,在解码器中,前一个(预测的)字应该被传递到下一个LSTM单元,以进行下一个预测。因此,我们生成了另一个密集层,然后是一个softmax激活函数来跟踪预测的词,并将它们传递到下一步。
既然我们定义了生成编码器和解码器的类,现在我们只需要创建和训练它们!
在这篇文章中,我们使用Pytorch实现了Seq2Seq模型。在下一篇文章中,让我们看看如何用准备好的数据来训练和评估他们。感谢您的阅读。
更多的文章,请订阅下面的公众号。
参考文献
-
Cho et al. (2014)
-
Hochreiter et al. (1997)
-
NLP FROM SCRATCH: TRANSLATION WITH A SEQUENCE TO SEQUENCE NETWORK AND ATTENTION
-
Understanding LSTM Networks
标签:状态,编码器,Attention,Seq2Seq,神经网络,解码器,LSTM,隐藏,size 来源: https://blog.csdn.net/xinxiangbobby/article/details/121195649