序列到序列第2部分模型

大家好!

我们在几周前发布了翻译的第二部分,以准备启动“数据科学家”课程的第二部分。 未来是另一种有趣的材料,也是一个公开的课程。

同时,我们进一步深入了模型的丛林。

神经翻译模型

虽然序列到序列模型的核心是由tensorflow/tensorflow/python/ops/seq2seq.py的函数创建的,但在models/tutorials/rnn/translate/seq2seq_model.py ,我们的翻译模型中仍使用了一些技巧值得一提。



采样的softmax和输出投影

如上所述,我们希望使用采样的softmax处理大型输出字典。 要从中解码,您必须跟踪输出的投影。 采样的softmax损耗和输出投影都是由seq2seq_model.py的以下代码生成的。

 if num_samples > 0 and num_samples < self.target_vocab_size: w_t = tf.get_variable("proj_w", [self.target_vocab_size, size], dtype=dtype) w = tf.transpose(w_t) b = tf.get_variable("proj_b", [self.target_vocab_size], dtype=dtype) output_projection = (w, b) def sampled_loss(labels, inputs): labels = tf.reshape(labels, [-1, 1]) # We need to compute the sampled_softmax_loss using 32bit floats to # avoid numerical instabilities. local_w_t = tf.cast(w_t, tf.float32) local_b = tf.cast(b, tf.float32) local_inputs = tf.cast(inputs, tf.float32) return tf.cast( tf.nn.sampled_softmax_loss( weights=local_w_t, biases=local_b, labels=labels, inputs=local_inputs, num_sampled=num_samples, num_classes=self.target_vocab_size), dtype) 

首先,请注意,只有在样本数(默认为512)小于目标字典大小的情况下,我们才创建样本softmax。 对于小于512的字典,最好使用标准softmax损失。

然后,创建输出的投影。 这是一对由权重矩阵和位移向量组成的对。 当使用rnn单元格时,返回按size排列的训练样本数的形状矢量,而不是按target_vocab_size返回训练样本数的形状向量。 要恢复logit,您需要将其乘以权重矩阵并添加一个偏移量,这发生在seq2seq_model.py中的第124-126行中。

 if output_projection is not None: for b in xrange(len(buckets)): self.outputs[b] = [tf.matmul(output, output_projection[0]) + output_projection[1] for ...] 

桶装和填充

除了采样的softmax之外,我们的翻译模型还使用了bucketing(存储桶)功能 ,该方法可让您有效地管理不同长度的句子。 首先,说明问题。 从英语翻译成法语时,我们在入口处使用长度为L1的英语句子,在出口处使用长度为L1的法语句子。 由于英语句子是作为encoder_inputs传输的,而法语句子则是作为decoder_inputs (带有GO符号前缀)显示的,因此有必要为英语和法语句子的每对长度(L1,L2 + 1)创建一个seq2seq模型。 结果,我们得到了一个包含许多相似子图的巨大图。 另一方面,我们可以用特殊的PAD字符“填充”每个句子。 然后,对于“打包”长度,我们只需要一个seq2seq模型。 但是,这样的模型在短句子中将无效-您必须编码和解码许多无用的PAD字符。

在为每对长度创建一个图和填充为单个长度之间的折衷方案中,我们使用一定数量的存储桶,并将每个句子填充至上述组的长度。 默认情况下,在translate.py我们使用以下组。

 buckets = [(5, 10), (10, 15), (20, 25), (40, 50)] 


因此,如果一个带有3个标记的英语句子到达输入,而对应的法语句子在输出处包含6个标记,则它们将进入第一组,并在编码器的输入处填充为长度5,在解码器的输入处填充为长度10。 如果英语报价中有8个令牌,而对应的法语18中,则不会落入组(10、15)中,而是将其转移到组(20、25)中,即英语报价将增加到20个令牌,而法语报价将增加到25个令牌。

请记住,在创建解码器输入时,我们会在输入中添加特殊的GO字符。 这发生在get_batch()中的get_batch()函数中,该函数还会翻转英语句子。 输入的翻转有助于改善Sutskever等人(2014)(pdf)的神经翻译模型的结果 为了弄清楚,想像一下有一个句子“ I go”。在输入处,将其分解为标记["I", "go", "."] ,在输出处则是一个句子“ Je vais。”,将其分解为标记["Je", "vais", "."] 。 它们将以输入编码器[PAD PAD "." "go" "I"]形式添加到组(5,10)中[PAD PAD "." "go" "I"] [PAD PAD "." "go" "I"]和解码器输入[GO "Je" "vais" "." EOS PAD PAD PAD PAD PAD] [GO "Je" "vais" "." EOS PAD PAD PAD PAD PAD]

运行它

要训​​练上述模型,您将需要一个大型的英法军团。 为了进行培训,我们将使用来自WMT'15网站的10 ^ 9法语-英语军,并将来自同一站点的新闻作为工作样本进行测试。 当运行下一个命令时,两个数据集都将被加载到train_dir

 python translate.py --data_dir [your_data_directory] --train_dir [checkpoints_directory] --en_vocab_size=40000 --fr_vocab_size=40000 

您将需要18GB的硬盘空间和几个小时来准备培训大楼。 对该案例进行解压缩,在data_dir,中创建字典文件data_dir,然后对该案例进行标记并转换为整数标识符。 请注意负责字典大小的参数。 在上面的示例中,40,000个最常用词之外的所有词都将转换为代表未知词的UNK令牌。 因此,当更改字典的大小时,二进制文件将通过令牌ID重新更改外壳。 数据准备培训开始之后。

默认情况下, translate中指定的值非常高。 长时间学习的大型模型显示出良好的效果,但是可能会花费太多时间或GPU内存过多。 您可以指定一个较小的模型锻炼,如下例所示。

 python translate.py --data_dir [your_data_directory] --train_dir [checkpoints_directory] --size=256 --num_layers=2 --steps_per_checkpoint=50 

上面的命令将训练模型分为两层(默认为3层),每层有256个单位(默认为1024个),每50步带有一个检查点(默认为200个)。 尝试使用这些选项,以查看哪种尺寸模型适合您的GPU。

在训练过程中, steps_per_checkpoin t二进制文件的每个步骤都会提供有关过去步骤的统计信息。 使用默认参数(3层,大小为1024),第一条消息如下:

 global step 200 learning rate 0.5000 step-time 1.39 perplexity 1720.62 eval: bucket 0 perplexity 184.97 eval: bucket 1 perplexity 248.81 eval: bucket 2 perplexity 341.64 eval: bucket 3 perplexity 469.04 global step 400 learning rate 0.5000 step-time 1.38 perplexity 379.89 eval: bucket 0 perplexity 151.32 eval: bucket 1 perplexity 190.36 eval: bucket 2 perplexity 227.46 eval: bucket 3 perplexity 238.66 

请注意,每个步骤花费的时间不到1.4秒,这使训练样本感到困惑,并使每个组的工作样本感到困惑。 经过大约3万步,我们看到了简短句子(第0组和第1组)的困惑如何变得清晰。 培训大楼包含约2200万个句子,一次迭代(一次运行的训练数据)大约需要34万步,训练样本的数量为64个。在此阶段,该模型可用于使用--decode选项将英语句子翻译为法语。

 python translate.py --decode --data_dir [your_data_directory] --train_dir [checkpoints_directory] Reading model parameters from /tmp/translate.ckpt-340000 > Who is the president of the United States? Qui est le président des États-Unis ? 

接下来是什么?

上面的示例显示了如何端到端创建自己的英语-法语翻译器。 运行它,看看模型如何工作。 质量是可以接受的,但是无法使用默认参数获得理想的翻译模型。 这是您可以改进的几件事。

首先,我们使用原始标记化,即basic_tokenizerdata_utils的基本功能。 在WMT'15网站上可以找到更好的令牌生成器。 如果使用它和大型词典,则可以实现更好的翻译。

此外,转换模型的默认参数配置不完善。 您可以尝试更改学习速度,衰减,模型权重的初始化。 您还可以使用更高级的功能(例如AdagradOptimizer替换seq2seq_model.py的标准GradientDescentOptimizer 。 尝试观察更好的结果!

最后,以上介绍的模型不仅可以用于翻译,还可以用于任何其他序列到序列的任务。 例如,即使您要将序列变成树,生成分析树,该模型也可以产生最新的结果,如Vinyals&Kaiser等人,2014(pdf)所示 。 因此,您不仅可以创建翻译器,还可以创建解析器,聊天机器人或您想要的任何其他程序。 实验!

仅此而已!

我们在这里等待您的评论和问题,或者我们邀请您在公开课中向他们的老师提问。

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


All Articles