序列到序列第1部分模型

祝大家有美好的一天!

我们再次为修订后的“ 数据科学家”课程开辟了新渠道 :另一位优秀的老师 ,基于更新的稍有改进的程序。 好吧,像往常一样,有趣的公开课和有趣的资料集。 今天,我们将开始分析Tensor Flow中的seq2seq模型。

走吧

正如RNN教程中已经讨论过的(建议您在阅读本文之前先熟悉它),可以教递归神经网络对语言进行建模。 随之而来的是一个有趣的问题:是否有可能在某些数据上训练网络以产生有意义的答案? 例如,我们可以教一个神经网络将英语翻译成法语吗? 事实证明,我们可以做到。

本指南将向您展示如何创建和培训这种端到端系统。 从GitHub复制Tensor Flow核心存储库TensorFlow模型存储库 。 然后,您可以通过启动翻译程序开始:

cd models/tutorials/rnn/translate python translate.py --data_dir [your_data_directory] 



她将从WMT'15网站上下载数据,将其从英语翻译为法语, 备培训和培训之用。 这将需要大约20GB的硬盘驱动器,并且需要大量的时间进行下载和准备,因此您可以立即开始该过程并继续阅读本教程。

该手册将访问以下文件:

档案文件里面有什么?
tensorflow /张量流/ python / ops / seq2seq.py用于创建序列到序列模型的库
模型/教程/ rnn /翻译/ seq2seq_model.py序列到序列的神经翻译模型
模型/教程/ rnn /翻译/ data_utils.py用于准备翻译数据的辅助功能
模型/教程/rnn/translate/translate.py训练和运行翻译模型的二进制文件

序列到序列的基础知识

Cho et al。,2014pdf )提出的基本序列到序列模型由两个递归神经网络(RNN)组成:处理输入数据的编码器(encoder)和生成数据的解码器(decoder)输出。 基本架构如下所示:



上图中的每个矩形代表RNN中的一个单元,通常是一个GRU单元-一个受控的递归块或一个LSTM单元-长期短期记忆(请阅读RNN教程以了解更多信息)。 编码器和解码器可以具有相同的权重,或更常见的是,使用不同的参数集。 多层细胞已成功用于序列到序列模型中,例如,翻译Sutskever等人,2014pdf )。

在上述基本模型中,必须将每个输入编码为固定大小的状态向量,因为这是唯一传输到解码器的内容。 为了使解码器更直接地访问输入数据, Bahdanau等人(2014年 )引入了一种注意力机制( pdf )。 我们将不涉及注意力机制的细节(为此,您可以在这里熟悉自己的工作); 可以说,它允许解码器在每个解码步骤中查看输入数据。 具有LSTM单元和解码器中的注意机制的多层序列到序列网络如下:



TensorFlow库seq2seq

从上面可以看到,有不同的序列到序列模型。 它们都可以使用不同的RNN单元,但是它们都接受编码器输入数据和解码器输入数据。 这是TensorFlow seq2seq库接口(tensorflow / tensorflow / python / ops / seq2seq.py)的基础。 这种基本的RNN,编解码器,序列到序列模型的工作原理如下。

 outputs, states = basic_rnn_seq2seq(encoder_inputs, decoder_inputs, cell) 

在上面的调用中, encoder_inputs是代表编码器输入数据的张量列表,对应于上图中的字母A,B,C。 类似地, decoder_inputs是表示解码器输入数据的张量。 从第一张图片开始GO,W,X,Y,Z。

cell参数是tf.contrib.rnn.RNNCell类的实例,该类确定将在模型中使用哪个单元格。 您可以使用现有的单元格,例如GRUCellLSTMCell ,也可以编写自己的单元格。 另外, tf.contrib.rnn提供了用于创建多层单元的外壳,为单元输入和输出或其他转换添加了例外。 查看RNN教程中的示例。

basic_rnn_seq2seq调用返回两个参数: outputsstates 。 它们都表示与decoder_inputs输入相同长度的张量列表。 outputs对应于每个时间步长的解码器输出数据,在第一张图片中是W,X,Y,Z,EOS。 返回的states表示每个时间步解码器的内部状态。

在使用序列到序列模型的许多应用中,时间t处的解码器输出在时间t +1处被传输回输入到解码器。 在测试过程中,在序列解码过程中,这就是构造新序列的方式。 另一方面,在训练期间,习惯上在每个时间步长将正确的输入数据发送到解码器,即使先前解码器被弄错了。 seq2seq.py函数通过feed_previous参数支持两种模式。 例如,考虑以下对嵌套RNN模型的使用。

 outputs, states = embedding_rnn_seq2seq( encoder_inputs, decoder_inputs, cell, num_encoder_symbols, num_decoder_symbols, embedding_size, output_projection=None, feed_previous=False) 

embedding_rnn_seq2seq模型中,所有输入数据( decoder_inputs输入和decoder_inputs输入)都是反映离散值的整数张量。 它们将嵌套在一个紧密的表示形式中(有关附件的详细信息,请参见“ 向量视图指南” ),但是要创建这些附件,您需要指定最大离散字符数:在编码器端为num_decoder_symbols ,在解码器端为num_decoder_symbols

在上面的调用中,我们将feed_previous设置为False。 这意味着解码器将以提供它们的形式使用解码器decoder_inputs张量。 如果将feed_previous设置为True,则解码器将仅使用第一个decoder_inputs元素。 列表中的所有其他张量将被忽略,而将使用解码器输出的先前值代替。 这用于解码翻译模型中的翻译,但也可以在训练过程中使用,以提高模型对其错误的稳定性。 大致与Bengio et al。,2015pdf )相同。

上面使用的另一个重要参数是output_projection 。 无需澄清,嵌入式模型的结论将为张量,其形式为每num_decoder_symbols训练样本的数量,因为它们表示每个生成符号的对数。 当训练具有大输出字典的模型(例如,具有大num_decoder_symbols ,存储这些大张量变得不切实际。 相反,最好返回较小的张量,随后将使用output_projection将其投影到较大的张量上。 这使我们可以使用seq2seq模型和采样的softmax损失,如Jean等人所述。 等人,2014年pdf )。

除了basic_rnn_seq2seqembedding_rnn_seq2seq之外, basic_rnn_seq2seq还有更多的序列到序列模型。 注意他们。 它们都具有相似的界面,因此我们将不深入研究它们的细节。 对于下面的翻译模型,请使用embedding_attention_seq2seq

待续。

Source: https://habr.com/ru/post/zh-CN430780/


All Articles