快捷搜索:

基于PaddlePaddle的机器翻译教程,神经机器翻译

日期:2019-11-20编辑作者:澳门新葡8455最新网站

原标题:EMNLP 2018 | 结合通用和专用NMT的优势,CMU为NMT引入「语境参数生成器」

原文:https://www.tensorflow.org/versions/r1.5/tutorials/seq2seq

近日,谷歌官方在 Github开放了一份神经机器翻译教程,该教程从基本概念实现开始,首先搭建了一个简单的NMT模型,随后更进一步引进注意力机制和多层 LSTM加强系统的性能,最后谷歌根据 GNMT提供了更进一步改进的技巧和细节,这些技巧能令该NMT系统达到极其高的精度。机器之心对该教程进行简要的描述,跟详细和精确的内容请查看项目原网站。

本文转载自PaddlePaddle

选自arXiv

(全文99.9%由google翻译,自学使用)

GitHub 链接:

量子位 编辑 | 公众号 QbitAI

作者:Emmanouil Antonios Platanios等

作者:Thang Luong,Eugene Brevdo,Rui Zhao(Google Research Blogpost,Github)

机器翻译,即跨语言间的自动翻译,是机器学习社区最活跃的研究领域。在机器翻译的众多方法中,序列到序列(sequence-to-sequence,seq2seq)模型[1, 2] 近期获得巨大成功。由于其可以使用深度神经网络获取句义,该模型成为谷歌翻译等多数商业翻译系统事实上的标准模型。但是,尽管有关OpenNMT 或 tf-seq2seq 等 seq2seq模型的资料已经非常丰富,但能够指导人们快速构建高质量翻译系统的知识和技能仍然略显不足。

机器翻译(machine translation, MT)是用计算机来实现不同语言之间翻译的技术。需要翻译的语言通常称为源语言(source language),翻译成的结果语言称为目标语言(target language)。机器翻译即实现从源语言到目标语言转换的过程,是自然语言处理的重要研究领域之一。

参与:白悦、刘晓坤

本教程的这个版本需要TensorFlow Nightly。 为了使用稳定的TensorFlow版本,请考虑其他分支,如tf-1.4。

今天,我们很高兴能够发布最新的TensorFlow 神经机器翻译教程,帮助读者全面了解 seq2seq模型,并介绍如何从头开始构建有竞争力的翻译模型。该教程尽可能简单地呈现该过程,教程首先介绍神经机器翻译的背景知识,并讲述构建 vanilla系统的具体代码。然后介绍注意力机制 [3, 4] 这一帮助 NMT 系统处理长句的重要工具。最后,本教程将讲解如何复制谷歌NMT(GNMT)系统 [5] 的关键特征,以实现在多个 GPU 上训练模型。

本文将带领大家了解经典的端到端神经网络机器翻译Seq2Seq模型,以及如何用PaddlePaddle来训练。如果想要实践效果更佳的翻译模型,请参考GitHub模型库中Transformer实现。

通用和专用 NMT 模型分别在相似语言对和罕见语言对的翻译中具有优势,但这也反映了各自的劣势,取决于参数共享的程度。为此,CMU 的研究者在本文中提出了一种在两者之间取得平衡方法,不需要改变 NMT 原有架构,而是引入新的组件 CPG,来可控地实现不同语言对模型之间的参数共享。该组件可无缝整合不同的 NMT,并在基准数据集上取得当前最佳。研究者强调,该方法使我们更接近普适的中间语言。

如果使用这个代码库进行研究,请引用此。

本教程包括具体的基准测试结果,用户可自行复制。我们的模型提供强大的开源基准,其性能不亚于 GNMT 的结果 [5]。我们在 WMT 2014 的英语转德语翻译任务中取得了 BLEU 得分 24.4 的成绩。

Seq2Seq项目地址:

神经机器翻译(NMT)无需单独训练或调整系统的任何部分就可以直接建模源语言到目标语言的映射。这使得 NMT 快速发展,并在许多大规模环境中成功应用 (Wu et al., 2016; Crego et al., 2016)。编码器-解码器抽象使构建将任何语言的源句映射到向量表示,再将向量表示解码到任何目标语言的系统在概念上变得可行。因此,人们提出了各种方法来扩展这种多语言机器翻译的抽象 (Luong et al., 2016; Dong et al., 2015; Johnson et al., 2017; Ha et al., 2016; Firat et al., 2016a)。

介绍(Introduction)

序列 - 序列(seq2seq)模型(Sutskever et al., 2014, Cho et al., 2014
)在机器翻译,语音识别和文本摘要等各种任务中取得了巨大的成功。 本教程为读者提供了seq2seq模型的全面理解,并展示了如何从头构建一个有竞争力的seq2seq模型。 我们专注于神经机器翻译(NMT)的任务,它是seq2seq模型的第一个测试平台。 包含的代码是轻量级的,高质量的,生产就绪,并结合最新的研究思路。 我们通过以下方式达到这个:

  1. 使用最近的解码器/注意力包装器(decoder / attention wrapper)API,TensorFlow 1.2数据迭代器
  2. 结合我们强大的专业知识,建立循环和seq2seq模型
  3. 为建立最好的NMT模型和重现Google’s NMT (GNMT)系统提供技巧和窍门。

我们相信提供人们可以轻松重现的benchmarks是非常重要的。 因此,我们提供了完整的实验结果,并在以下公开可用的数据集上对模型进行预训练:

  1. 小规模:IWSLT Evaluation Campaign提供的英语 - 越南语TED对话语料库(133K个句子对)。
  2. 大规模:WMT Evaluation Campaign提供的德英平行语料库(4.5M句子对)。

我们首先建立一些关于NMT的seq2seq模型的基本知识,解释如何建立和训练一个vanilla NMT模型。 第二部分将着重于构建具有注意力机制的竞争性NMT模型。 然后,我们将讨论一些技巧和诀窍,以建立最佳NMT模型(包括速度和翻译质量),如TensorFlow最佳实践(批处理,分段),双向RNN,波束搜索(beam search [这个是啥?])以及使用GNMT注意力扩展到多个GPU。

本教程还包括其他的基准测试结果(英语转越南语、德语转英语)。

Transformer项目地址:

多语言 NMT 之前的工作可大致分为两种范式。第一个通用 NMT (Johnson et al., 2017; Ha et al., 2016) 对所有语言使用单一模型。通用 NMT 没有任何特定语言的参数化,在翻译截然不同的语言和数据有限的情况下,这种模式过于简单化且非常不利。通过实验验证,Johnson 等人的方法(2017)在高样本复杂度情况下性能变差,因此在有限的数据设置中表现不佳。Ha 等人提出的通用模型(2016)需要输入句子的新编码方案,这会导致过大的词汇量从而难以扩展。第二种范式,特定于每种语言的编码器-解码器 (Luong et al., 2016; Firat et al., 2016a),每种语言使用独立的编码器和解码器。这不允许跨语言共享信息,可能导致过度参数化,且在语言相似的情况下可能有害。

基础知识(Basic)

另外,本教程将开放全动态的 seq2seq API(随 TensorFlow 1.2 发布),该 API 使 seq2seq 模型的构建过程干净、简单、易读:

背景介绍

在本文中,CMU 的研究者在这两种方法之间取得了平衡,提出了一种能够分别为每种语言学习参数的模型,同时也能在相似语言之间共享信息。研究者使用了新的语境相关的参数生成器(CPG),它可以(a)泛化所有这些方法;(b)缓解上述通用和独立语言编码器-解码器系统的问题。它将语言嵌入作为翻译的语境进行学习,并用它们为所有语言对生成共享翻译模型的参数。因此,它为这些模型提供了每种语言单独学习参数的能力,同时也在相似语言之间共享信息。参数生成器是通用的,允许以这种方式增强任何现有的 NMT 模型。此外,它具有以下所期望的特征:

神经机器翻译的背景(Background on Neural Machine Translation)

在过去,传统的基于短语的翻译系统通过将源语句拆分成多个片段然后将其逐句翻译来执行他们的任务。 这导致了翻译产出的不流畅,并不像我们人类翻译的那样。 我们阅读整个源句子,理解它的意思,然后产生一个翻译。 神经机器翻译(NMT)模仿的就是这种方式!

图片 1

图1.编码器 - 解码器架构 - 用于NMT的一般方法的例子。 编码器将源语句转换为通过解码器传递的“意义”向量以产生翻译。

具体而言,NMT系统首先使用编码器读取源句子来构建“思想”向量,表示句子含义的数字序列; 解码器然后处理句子向量以发出翻译,如图1所示。这通常被称为编码器 - 解码器体系结构。 NMT以这种方式解决了传统的基于短语的方法中的局部翻译问题:它可以捕捉语言的长期依赖性,例如性别协议; 语法结构等; 并通过谷歌神经机器翻译系统(Google Neural Machine Translation systems)展示了更流利的翻译。

NMT模型根据其确切的体系结构而有所不同。 对于序列数据,很自然的选择是大多数NMT模型所使用的递归神经网络(RNN)。 编码器和解码器通常使用RNN。 但是,RNN模型在以下方面有所不同:(a)方向性

  • 单向或双向; (b)深度 - 单层或多层; 和(c)类型 - 通常是普通RNN,长期短期记忆(LSTM)或门控循环单元(GRU)。 有兴趣的读者可以在这篇博文中找到关于RNN和LSTM的更多信息。

在本教程中,我们以单向的深度多层RNN为例,将LSTM作为一个递归单元。 我们在图2中展示了这样模型的一个例子。在这个例子中,我们建立了一个模型,将源句子"I am a student"翻译成目标句子"Je suisétudiant"。 在高层次上,NMT模型由两个递归神经网络组成:编码器RNN仅仅消耗输入的源单词而不作任何预测; 另一方面,解码器在预测下一个单词的同时处理目标语句。

欲了解更多信息,我们向读者介绍本教程所基于的Luong (2016)。

图片 2

图2.神经机器翻译 - 一个深度循环架构的例子,将源句子“I am a student”翻译成目标句子“Je suistétudiant”。 这里,“<s>”表示解码过程的开始,而“</ s>”表示解码器停止。

使用 tf.contrib.data 中最新输入的管道对动态调整的输入序列进行预处理。

早期机器翻译系统多为基于规则的翻译系统,需要由语言学家编写两种语言之间的转换规则,再将这些规则录入计算机。该方法对语言学家的要求非常高,而且我们几乎无法总结一门语言会用到的所有规则,更何况两种甚至更多的语言。因此统计机器翻译(Statistical Machine Translation, SMT)技术应运而生。

  1. 简单:类似 Johnson 等人(2017)和 Ha 等人(2016)的方法,且与 Luong 等人(2016 年)和 Firat 等人(2016a)的方法相反,它只需稍作修改就可以应用于大多数现有的 NMT 系统,并且能够无缝地容纳注意力层。
  2. 多语言:和之前相同,允许使用相同的单个模型进行多语言翻译。
  3. 半监督:可以使用单语数据。
  4. 可扩展:通过在语言间使用大量但可控的共享来减少参数的数量,从而减少大量数据的需求,如 Johnson 等人所述(2017)。它还允许语言的解耦,避免对大量共享词汇需求,如 Ha 等人所述(2016)。
  5. 适应性强:无需完全重新训练就可以适应新语言。
  6. 当前最先进的方法:比成对 NMT 模型和 Johnson 等人的模型具备更好的性能。(2017 年)。事实上,该方法优于最先进的性能。

安装教程(Installing the Tutorial)

要安装本教程,您需要在系统上安装TensorFlow。 本教程需要TensorFlow Nightly。 要安装TensorFlow,请按照此处的安装说明进行操作。
一旦安装了TensorFlow,您可以运行以下命令来下载本教程的源代码:

git clone https://github.com/tensorflow/nmt/

使用批量填充和序列长度 bucketing,提高训练速度和推理速度。

在统计机器翻译技术中,转化规则是由机器自动从大规模的语料中学习得到的,而非我们人主动提供规则。因此,它克服了基于规则的翻译系统所面临的知识获取瓶颈的问题,但仍然存在许多挑战:

作者首先介绍一个可用于定义和描述大多数现有 NMT 系统模块化框架,然后,在第 3 节中,将根据该框架介绍本研究的主要贡献,即语境参数生成器(CPG)。作者还论证了该方法使我们更接近普适的中间语言。

训练 - 如何建立我们的第一个NMT系统(Training – How to build our first NMT system)

首先,我们将深入探讨用具体的代码片断构建NMT模型的核心,我们将通过它更详细地解释图2。 我们将数据准备和完整的代码推迟到以后。 这部分是指文件model.py

在底层,编码器和解码器RNNs接收以下输入:首先是源句子,然后是指示从编码转换到解码模式的边界标记"<s>" ,和目标语句。 对于训练,我们会给系统提供以下张量,这些张量在时间上是主要格式,包含文字索引:

  • encoder_inputs [max_encoder_time,batch_size]:源输入单词。
  • decoder_inputs [max_decoder_time,batch_size]:目标输入单词。
  • decoder_outputs [max_decoder_time,batch_size]:目标输出单词,这些是decoder_input向左移动一个时间步,右边添加一个句尾结束标记。
    这里为了提高效率,我们一起训练多个句子(batch_size)。 测试稍有不同,所以我们稍后再讨论。

使用通用结构和训练时间表训练 seq2seq 模型,包括多种注意力机制和固定抽样。

人为设计许多特征,但永远无法覆盖所有的语言现象;

论文:Contextual Parameter Generation for Universal Neural Machine Translation

嵌入(Embedding)

鉴于单词的分类性质,模型必须首先查找源和目标的嵌入来检索相应的词表示(word representations)。 为了使这个嵌入层起作用,首先为每种语言选择一个词汇表。 通常,选择词汇量V,只有最频繁的V词才被视为唯一。 所有其他单词都转换为"unknown"标记,并获得相同的嵌入。 嵌入权重,每种语言一套,通常在训练中学习。

# Embedding
embedding_encoder = variable_scope.get_variable(
    "embedding_encoder", [src_vocab_size, embedding_size], ...)
# Look up embedding:
#   encoder_inputs: [max_time, batch_size]
#   encoder_emb_inp: [max_time, batch_size, embedding_size]
encoder_emb_inp = embedding_ops.embedding_lookup(
    embedding_encoder, encoder_inputs)

同样,我们可以构建embedding_decoder和decoder_emb_inp。 请注意,可以选择使用预训练词表示(例如word2vec或Glove vectors)来初始化嵌入权重。 一般来说,给定大量的训练数据,我们可以从头学习这些嵌入。

使用 in-graph 集束搜索在 seq2seq 模型中进行推理。

难以利用全局的特征;

图片 3

编码器(Encoder)

一旦检索出来,嵌入字就作为输入被输入到主网络中,主网络由两个多层RNN组成

  • 一个源语言的编码器和一个目标语言的解码器。 这两个RNN原则上可以分享相同的权重; 然而,在实践中,我们经常使用两个不同的RNN参数(这些模型在拟合大型训练数据集时效果更好)。 编码器RNN使用零矢量作为其起始状态,并且如下构建:

    # Build RNN cell encoder_cell = tf.nn.rnn_cell.BasicLSTMCell(num_units)

    # Run Dynamic RNN # encoder_outputs: [max_time, batch_size, num_units] # encoder_state: [batch_size, num_units] encoder_outputs, encoder_state = tf.nn.dynamic_rnn(

      encoder_cell, encoder_emb_inp,
      sequence_length=source_sequence_length, time_major=True)
    

请注意,为避免浪费计算,句子具有不同的长度,我们通过source_sequence_length告诉dynamic_rnn确切的源句子长度。 由于我们的输入是时序重要的,我们设置time_major = True。 在这里,我们只建立一个单层的LSTM,encoder_cell。 我们将介绍如何构建多层LSTM,添加dropout,并在后面的章节中使用attention。

优化 seq2seq 模型,以实现在多 GPU 设置中的模型训练。

依赖于许多预处理环节,如词语对齐、分词或符号化(tokenization)、规则抽取、句法分析等,而每个环节的错误会逐步累积,对翻译的影响也越来越大。

  • 论文地址:
  • 项目地址:

解码器(Decoder)

解码器也需要访问源信息,一个简单的方法就是用编码器的最后一个隐藏状态encoder_state来初始化它。 在图2中,我们将源语词“student”的隐藏状态传递给解码器端。

# Build RNN cell
decoder_cell = tf.nn.rnn_cell.BasicLSTMCell(num_units)

# Helper
helper = tf.contrib.seq2seq.TrainingHelper(
    decoder_emb_inp, decoder_lengths, time_major=True)
# Decoder
decoder = tf.contrib.seq2seq.BasicDecoder(
    decoder_cell, helper, encoder_state,
    output_layer=projection_layer)
# Dynamic decoding
outputs, _ = tf.contrib.seq2seq.dynamic_decode(decoder, ...)
logits = outputs.rnn_output

在这里,这个代码的核心部分是BasicDecoder对象、解码器,其接收decoder_cell(类似于encoder_cell),帮助器,以及之前的encoder_state作为输入。 通过分离出解码器和帮助器,我们可以重用不同的代码库,例如,可以用GreedyEmbeddingHelper代替TrainingHelper来进行贪婪的解码。 请参阅helper.py。

最后,我们没有提到projection_layer是一个稠密的矩阵,它将顶部隐藏状态转化为维数为V的logit向量。我们在图2的顶部说明了这个过程。

projection_layer = layers_core.Dense(
    tgt_vocab_size, use_bias=False)

下文我们将简要地介绍该 Github 教程项目。

近年来,深度学习技术的发展为解决上述挑战提供了新的思路。将深度学习应用于机器翻译任务的方法大致分为两类:

摘要:我们对现有神经机器翻译(NMT)模型进行了简单修正,允许使用单个通用模型完成多种语言之间的翻译,同时允许语言特定的参数化,并且还可以用于域适应。我们的方法不需要改变标准 NMT 系统的模型架构,而是引入了新的组件,即语境参数生成器(CPG),可以生成系统的参数(例如,神经网络中的权重)。该参数生成器接受源语言嵌入和目标语言嵌入作为输入,并分别为编码器和解码器生成参数。模型的其余部分保持不变,并在所有语言中共享。我们展示了这种简单的修正如何使系统使用单语数据进行训练并实现 zero-shot 翻译。我们进一步表明,它能够超越 IWSLT-15 和 IWSLT-17 数据集的当前最佳性能,并且学习的语言嵌入能够发现语言之间的有趣关系。

损失(Loss)

基于上面的logits,我们现在准备计算我们的训练损失:

crossent = tf.nn.sparse_softmax_cross_entropy_with_logits(
    labels=decoder_outputs, logits=logits)
train_loss = (tf.reduce_sum(crossent * target_weights) /
    batch_size)

这里,target_weights是与decoder_outputs相同大小的0-1矩阵。 它将目标序列长度之外的值填充0。

重要说明:值得指出的是,我们用batch_size来分割损失,所以我们的超参数对batch_size是“不变的”。 有些人用(batch_size * num_time_steps)来划分损失,减少了短句的错误。 更微妙的是,我们的超参数(应用于前一种方式)不能用于后一种方式。 例如,如果两种方法都使用SGD来学习1.0,则后一种方法有效地使用1 / num_time_steps的更小的学习速率。

引言

仍以统计机器翻译系统为框架,只是利用神经网络来改进其中的关键模块,如语言模型、调序模型等;

图片 4

梯度计算和优化(Gradient computation & optimization)

现在我们已经定义了NMT模型的正向传播。 计算反向传播只是几行代码的问题:

# Calculate and clip gradients
params = tf.trainable_variables()
gradients = tf.gradients(train_loss, params)
clipped_gradients, _ = tf.clip_by_global_norm(
    gradients, max_gradient_norm)

训练RNNs的重要步骤之一是梯度裁剪。 在这里,我们在全局范围内进行裁剪。 最大值max_gradient_norm通常设置为5或1的值。最后一步是选择优化器。 Adam优化器是一个常用的选择。 我们也选择一个学习率。 learning_rate的值通常可以在0.0001到0.001之间; 随着训练的进行可以减少。

# Optimization
optimizer = tf.train.AdamOptimizer(learning_rate)
update_step = optimizer.apply_gradients(
    zip(clipped_gradients, params))

在我们自己的实验中,我们使用标准SGD(tf.train.GradientDescentOptimizer),其学习速率逐步降低,这样可以获得更好的性能。 参见 benchmarks。

未完待续

序列到序列(seq2seq)模型(Sutskeveret al., 2014, Cho et al.,2014)在机器翻译、语音识别和文本摘要等任务上取得了巨大的成功。本教程致力于帮助读者全面掌握 seq2seq模型,并且展示了如何从头开始构建一个强大的 seq2seq 模型。我们该教程会注重神经机器翻(NMT)任务,神经机器翻译是 seq2seq模型很好的试验台,并且已经获得了广泛的成功。我们使用的代码是极其轻量、高质量、可投入生产并且结合了最新研究思路的实现。我们通过以下方式实现这一目标:

不再以统计机器翻译系统为框架,而是直接用神经网络将源语言映射到目标语言,即端到端的神经网络机器翻译(End-to-End Neural Machine Translation, End-to-End NMT),简称为NMT模型。作为经典模型的实现,可以帮助大家更好的理解机器翻译。

图 1:在我们的模块化框架下的 NMT 系统概述。我们的主要贡献在于参数生成器模块(即,耦合或解耦——具有蓝色字体的每个框是单独的选项)。注意,g 表示参数生成器网络。在我们的实验中,我们考虑该网络的线性形式。但是,我们的贡献并不取决于其他模块的选择;我们仍然可以将具有不同架构的参数生成器和不同类型的词汇表用于编码器和解码器。

使用最新的解码器/attention wrapper API、TensorFlow 1.2 数据迭代器。

图片 5

图片 6

结合了我们在构建循环型和 seq2seq 型模型的专业知识。

图1:基于神经网络的机器翻译系统

表 1:我们提出的有基础成对 NMT(PNMT)模型的方法(阴影的一行)和用于 IWSLT-15 数据集的 Google 多语言 NMT 模型(GML)的比较。百分比的并列行显示训练时使用多少部分(1%、10%、100%)的平行语料库;其余的仅用作单语数据。表中显示了 BLEU 和 Meteor 指标的结果。CPG *表示与 CPG 相同的模型,但未使用自动编码训练样本进行训练。每种情况下的最佳分数加粗显示。

提供了可构建最好 NMT 模型的技巧,同时还复制了谷歌的 NMT(GNMT)系统。

效果展示

图片 7

我们相信提供所有人都很容易复制的基准是非常重要的。因此,我们基于以下公开的数据集提供了全部的试验结果和预训练模型:

以中英翻译的模型为例,当模型训练完毕时,如果输入如下已分词的中文句子:

表 2:我们提出的有基础成对 NMT(PNMT)模型的方法(阴影的一行)和用于 IWSLT-17 数据集的 Google 多语言 NMT 模型(GML)的比较。因为 Meteor 不支持 It、Nl 和 Ro,所以仅显示了 BLEU 度量标准的结果,CPG8 表示使用 8 个语言嵌入来表示 CPG。「C4」下标表示用于受控参数共享的 CPG 的低级版本(参见第 3.1 节),使用等级 4 等。每种情况下的最佳得分加粗显示。

小规模数据集:TED 演讲的英语-越南语平行语料库(133K 个句子对),该数据集由 IWSLT Evaluation Campaign 提供。

如果设定显示翻译结果的条数为3,生成的英语句子如下:

本文为机器之心编译,转载请联系本公众号获得授权。返回搜狐,查看更多

大规模数据集:德语-英语平行语料库(4.5M 个句子对),该数据集由 WMT Evaluation Campaign 提供。

左起第一列是生成句子的序号;左起第二列是该条句子的得分,分值越高越好;左起第三列是生成的英语句子。

责任编辑:

我们首先需要了解用于NMT 任务的 seq2seq 模型的基本知识,并需要理解如何构建和训练一个 vanilla NMT

另外有两个特殊标志:表示句子的结尾,表示未登录词(unknown word),即未在训练字典中出现的词。

模型。第二部分将更进一步详细地解释如何构建带注意力机制的强大神经机器翻译模型。然后我们会讨论构建更好神经机器翻译模型(翻译速度和质量)可能的技巧,例如TensorFlow 最好的实践方法(batching, bucketing)、双向循环神经网络和集束搜索等。

模型概览

基础

本节依次介绍双向循环神经网络(Bi-directional Recurrent Neural Network),NMT模型中典型的编码器-解码器(Encoder-Decoder)框架以及柱搜索(beam search)算法。

关于神经机器翻译

双向循环神经网络

以词组为基础的传统翻译系统将源语言句子拆分成多个词块,然后进行词对词的翻译。这使得翻译输出结果流畅性大打折扣,远远不如人类译文。我们会通读整个源语言句子、了解句子含义,然后输出翻译结果。神经机器翻译(NMT)竟然可以模仿人类的翻译过程!

我们这里介绍Bengio团队在论文2,4]中提出的另一种结构。该结构的目的是输入一个序列,得到其在每个时刻的特征表示,即输出的每个时刻都用定长向量表示到该时刻的上下文语义信息。

图片 8

具体来说,该双向循环神经网络分别在时间维以顺序和逆序——即前向和后向——依次处理输入序列,并将每个时间步RNN的输出拼接成为最终的输出层。这样每个时间步的输出节点,都包含了输入序列中当前时刻完整的过去和未来的上下文信息。下图展示的是一个按时间步展开的双向循环神经网络。该网络包含一个前向和一个后向RNN,其中有六个权重矩阵:输入到前向隐层和后向隐层的权重矩阵,隐层到隐层自己的权重矩阵,前向隐层和后向隐层到输出层的权重矩阵。注意,该网络的前向隐层和后向隐层之间没有连接。

图片 9

图片 10

图 1. 编码器-解码器结构——神经机器翻译的通用方法实例。编码器将源语言句子转换成「意义」向量,然后通过解码器输出翻译结果。

图2:按时间步展开的双向循环神经网络

具体来说,神经机器翻译系统首先使用编码器读取源语言句子,构建一个「思想」向量,即代表句义的一串数字;然后使用解码器处理该容器,并输出翻译结果,如图1所示。这就是我们通常所说的编码器-解码器结构。神经机器翻译用这种方法解决以词组为基础的传统翻译系统遇到的翻译问题:神经机器翻译能够捕捉语言中的长距离依赖结构,如词性一致、句法结构等,然后输出流利度更高的翻译结果,正如谷歌神经机器翻译系统已经做到的那样。

编码器-解码器框架

NMT模型在具体的结构中会发生变化。对于序列数据而言,最好的选择是循环神经网络(RNN),这也被大多数 NMT模型采用。通常情况下,编码器和解码器都可使用循环神经网络。但是,循环神经网络模型在下列情况下发生变化:(a)方向性(directionality),单向或双向;(b)深度,单层或多层;(c)类型,通常是vanilla RNN、长短期记忆(Long Short-term Memory,LSTM),或门控循环单元(gated recurrentunit,GRU)。

编码器-解码器(Encoder-Decoder)2]框架用于解决由一个任意长度的源序列到另一个任意长度的目标序列的变换问题。即编码阶段将整个源序列编码成一个向量,解码阶段通过最大化预测序列概率,从中解码出整个目标序列。编码和解码的过程通常都使用RNN实现。

感兴趣的读者可打开该网址( RNN 和 LSTM 的更多信息。

图片 11

本教程中,我们将以单向的深度多层RNN(deep multi-layer RNN)为例,它使用 LSTM 作为循环单元。模型实例如图 2所示。我们在该实例中构建了一个模型,将源语言句子「I am a student」翻译成目标语言「Je suis étudiant」。该 NMT模型包括两个循环神经网络:编码器 RNN,在不预测的情况下将输入的源语言单词进行编码;解码器,在预测下一个单词的条件下处理目标句子。

图3:编码器-解码器框架

若想参考更多信息,请查看 Luong(2016)(

编码器

图片 12

编码阶段分为三步:

图 2. 神经机器翻译——一个深度循环结构实例:将源语言句子「I am a student」翻译成目标语言句子「Je suis étudiant」。此处,「」代表解码过程开始,「」代表解码过程结束。

one-hot vector表示:将源语言句子x={x1,x2,…,xt}的每个词xi表示成一个列向量,i=1,2,…,T。这个向量Wi的维度与词汇表大小|V| 相同,并且只有一个维度上有值1(该位置对应该词在词汇表中的位置),其余全是0。

安装该教程

映射到低维语义空间的词向量:one-hot vector表示存在两个问题,1)生成的向量维度往往很大,容易造成维数灾难;2)难以刻画词与词之间的关系(如语义相似性,也就是无法很好地表达语义)。因此,需再one-hot vector映射到低维的语义空间,由一个固定维度的稠密向量表示。记映射矩阵为,用表示第i个词的词向量,K为向量维度。

为了安装该教程,我们需要先安装 TensorFlow。本教程需要最新的 TensorFlow 教程(目前为 1.2.1 版本)。为了安装 TensorFlow,请按照以下安装指导:

用RNN编码源语言词序列:这一过程的计算公式为,其中h是一个全零的向量,?θ是一个非线性激活函数,最后得到的h={h1,…,hT}就是RNN依次读入源语言T个词的状态编码序列。整句话的向量表示可以采用h在最后一个时间步T的状态编码,或使用时间维上的池化结果。

在安装 TensorFlow 之后,我们需要运行以下命令安装本教程的源代码:

第3步也可以使用双向循环神经网络实现更复杂的句编码表示,具体可以用双向GRU实现。前向GRU按照词序列的顺序依次编码源语言端词,并得到一系列隐层状态。类似的,后向GRU按照的顺序依次编码源语言端词,得到。最后对于词xi,通过拼接两个GRU的结果得到它的隐层状态,即hi=。

git clone

图片 13

训练-如何构建我们第一个 NMT 系统

图4:使用双向GRU的编码器

我们首先需要了解构建一个 NMT 模型具体代码的核心,我们会在图 2 中更详细地讲解。我们后面会介绍数据准备和全部的代码,这一部分是指 model.py 文件。

解码器

在网络的底层,编码器和解码器 RNN 接收到以下输入:首先是原句子,然后是从编码到解码模式的过渡边界符号「」,最后是目标语句。对于训练来说,我们将为系统提供以下张量,它们是以时间为主(time-major)的格式,并包括了单词索引:

机器翻译任务的训练过程中,解码阶段的目标是最大化下一个正确的目标语言词的概率。思路是:

encoder_inputs [max_encoder_time, batch_size]:源输入词。

每一个时刻,根据源语言句子的编码信息(又叫上下文向量,context vector)c、真实目标语言序列的第i个词ui和i时刻RNN的隐层状态zi,计算出下一个隐层状态zi+1。计算公式如下:

decoder_inputs [max_decoder_time, batch_size]:目标输入词。

其中?θ’是一个非线性激活函数;c是源语言句子的上下文向量,在不使用注意力机制时,如果编码器的输出是源语言句子编码后的最后一个元素,则可以定义c=ht;ui是目标语言序列的第i个单词,u是目标语言序列的开始标记,表示解码开始;zi是i时刻解码RNN的隐层状态,z是一个全零的向量。

decoder_outputs [max_decoder_time, batch_size]:目标输出词,这些是 decoder_inputs 按一个时间步向左移动,并且在右边有句子结束符。

将zi+1通过softmax归一化,得到目标语言序列的第i+1个单词的概率分布pi+1。概率分布公式如下:

为了更高的效率,我们一次用多个句子(batch_size)进行训练。测试略有不同,我们会在后面讨论。

其中WsZi+1+bz是对每个可能的输出单词进行打分,再softmax归一化就可以得到第i+1个词的概率pi+1。

1.嵌入

根据pi+1和ui+1计算代价。

给定单词的分类属性,模型首先必须查找词来源和目标嵌入以检索相应的词表征。为了令该嵌入层能够运行,我们首先需要为每一种语言选定一个词汇表。通常,选定词汇表大小V,那么频率最高的 V个词将视为唯一的。而所有其他的词将转换并打上「unknown」标志,因此所有的词将有相同的嵌入。我们通常在训练期间嵌入权重,并且每种语言都有一套。

重复步骤1~2,直到目标语言序列中的所有词处理完毕。

# Embedding

embedding_encoder = variable_scope.get_variable(

                  "embedding_encoder", [src_vocab_size, embedding_size], ...)# Look up embedding:#   encoder_inputs: [max_time, batch_size]#   encoder_emp_inp: [max_time, batch_size, embedding_size]

encoder_emb_inp = embedding_ops.embedding_lookup(

                  embedding_encoder, encoder_inputs)

机器翻译任务的生成过程,通俗来讲就是根据预先训练的模型来翻译源语言句子。生成过程中的解码阶段和上述训练过程的有所差异,具体介绍请见柱搜索算法。

我们同样可以构建 embedding_decoder 和 decoder_emb_inp。注意我们可以选择预训练的词表征如 word2vec 或 Glove vectors 初始化嵌入权重。通常给定大量的训练数据,我们能从头学习这些嵌入权重。

柱搜索算法

2.编码器

柱搜索(beam search)是一种启发式图搜索算法,用于在图或树中搜索有限集合中的最优扩展节点,通常用在解空间非常大的系统(如机器翻译、语音识别)中,原因是内存无法装下图或树中所有展开的解。如在机器翻译任务中希望翻译“你好”,就算目标语言字典中只有3个词,也可能生成无限句话(hello循环出现的次数不定),为了找到其中较好的翻译结果,我们可采用柱搜索算法。

一旦可以检索到,词嵌入就能作为输入馈送到主神经网络中。该网络有两个多层循环神经网络组成,一个是原语言的编码器,另一个是目标语言的解码器。这两个RNN 原则上可以共享相同的权重,然而在实践中,我们通常使用两组不同的循环神经网络参数(这些模型在拟合大型训练数据集上做得更好)。解码器RNN 使用零向量作为它的初始状态,并且可以使用如下代码构建:

柱搜索算法使用广度优先策略建立搜索树,在树的每一层,按照启发代价(heuristic cost)(本教程中,为生成词的log概率之和)对节点进行排序,然后仅留下预先确定的个数(文献中通常称为beam width、beam size、柱宽度等)的节点。只有这些节点会在下一层继续扩展,其他节点就被剪掉了,也就是说保留了质量较高的节点,剪枝了质量较差的节点。因此,搜索所占用的空间和时间大幅减少,但缺点是无法保证一定获得最优解。

# Build RNN cell

encoder_cell = tf.nn.rnn_cell.BasicLSTMCell(num_units)

# Run Dynamic RNN#   encoder_outpus: [max_time, batch_size, num_units]#   encoder_state: [batch_size, num_units]

encoder_outputs, encoder_state = tf.nn.dynamic_rnn(

                   encoder_cell, encoder_emb_inp,

                   sequence_length=source_seqence_length, time_major=True)

使用柱搜索算法的解码阶段,目标是最大化生成序列的概率。思路是:

注意语句有不同的长度以避免浪费计算力,因此我们会通过

每一个时刻,根据源语言句子的编码信息cc、生成的第ii个目标语言序列单词ui和i时刻RNN的隐层状态zi,计算出下一个隐层状态zi+1。

source_seqence_length 告诉 dynamic_rnn 精确的句子长度。因为我们的输入是以时间为主(time

将zi+1通过softmax归一化,得到目标语言序列的第i+1个单词的概率分布pi+1。

major)的,我们需要设定 time_major=True。现在我们暂时只需要构建单层

根据pi+1采样出单词ui+1。

LSTM、encoder_cell。我们后面会详细描述怎样构建多层 LSTM、添加 dropout 并使用注意力机制。

重复步骤1~3,直到获得句子结束标记或超过句子的最大生成长度为止。

3.解码器

注意:zi+1和pi+1的计算公式同解码器中的一样。且由于生成时的每一步都是通过贪心法实现的,因此并不能保证得到全局最优解。

decoder 也需要访问源信息,一种简单的方式是用编码器最后的隐藏态 encoder_state 对其进行初始化。在图 2 中,我们将源词「student」中的隐藏态传递到了解码器。

数据介绍

# Build RNN cell

decoder_cell = tf.nn.rnn_cell.BasicLSTMCell(num_units)

# Helper

helper = tf.contrib.seq2seq.TrainingHelper(

decoder_emb_inp, decoder_lengths, time_major=True)# Decoder

decoder = tf.contrib.seq2seq.BasicDecoder(

                      decoder_cell, helper, encoder_state,

                     output_layer=projection_layer)# Dynamic decoding

outputs, _ = tf.contrib.seq2seq.dynamic_decode(decoder, ...)

logits = outputs.rnn_output

本教程使用WMT-14数据集中的bitexts(after selection)作为训练集,dev+test data作为测试集和生成集。

此处代码的核心是 BasicDecoder、获取 decoder_cell(类似于 encoder_cell) 的 decoder、helper 以及之前作为输入的 encoder_state。

数据预处理

通过分离 decoders 和 helpers,我们能重复使用不同的代码库,例如 TrainingHelper 可由 GreedyEmbeddingHelper 进行替换,来做贪婪解码。

我们的预处理流程包括两步:

最后,我们从未提到过的 projection_layer 是一个密集矩阵,将顶部的隐藏态转变为维度 V 的逻辑向量。我们在图 2 的上部展示了此过程。

将每个源语言到目标语言的平行语料库文件合并为一个文件:

projection_layer = layers_core.Dense(

                        tgt_vocab_size, use_bias=False)

合并每个XXX.src和XXX.trg文件为XXX。

4.损失

XXX中的第i行内容为XXX.src中的第i行和XXX.trg中的第i行连接,用’t’分隔。

给出以上的 logits,可计算训练损失:

创建训练数据的“源字典”和“目标字典”。每个字典都有DICTSIZE个单词,包括:语料中词频最高的(DICTSIZE

crossent = tf.nn.sparse_softmax_cross_entropy_with_logits( labels=decoder_outputs, logits=logits)

train_loss = (tf.reduce_sum(crossent * target_weights) / batch_size)

  • 3)个单词,和3个特殊符号、和。

以上代码中,target_weights 是一个与 decoder_outputs 大小一样的 0-1 矩阵。该矩阵将目标序列长度以外的其他位置填充为标量值 0。

示例数据

我们需要指出来的是,训练损失可以由

该数据集有193319条训练数据,6003条测试数据,词典长度为30000。因为数据规模限制,使用该数据集训练出来的模型效果无法保证。

batch_size 分割,因此我们的超参数 batch_size 是「不变量」。也有些人将训练损失按照 batch_size *num_time_steps分割,这样可以减少短句所造成的误差。更巧妙的,我们的超参数(应用于前面的方法)不能用于后面的方法。例如,如果两种方法都是用学习率为 1.0的随机梯度下降,后面的方法将更有效地利用一个较小的学习率,即 1 / num_time_steps。

模型配置说明

5.梯度计算和优化

下面我们开始根据输入数据的形式配置模型。首先引入所需的库函数以及定义全局变量。

现在是时候定义我们的 NMT 模型的前向传播了。计算反向传播只需要写几行代码:

然后如下实现编码器框架:

# Calculate and clip gradients

parameters = tf.trainable_variables()

gradients = tf.gradients(train_loss, params)

clipped_gradients, _ = tf.clip_by_global_norm(

                   gradients, max_gradient_norm)

再实现训练模式下的解码器:

训练

实现推测模式下的解码器:

RNN 的一个重要步骤是梯度截断(gradient clipping)。这里,我们使用全局范数进行截断操作。最大值

进而,我们定义一个train_program来使用inference_program计算出的结果,在标记数据的帮助下来计算误差。我们还定义了一个optimizer_func来定义优化器。

max_gradient_norm 通常设置为 5 或 1。最后一步是选择优化器。Adam优化器是最常见的选择。我们还要选择一个学习率,learning_rate 的值通常在 0.0001 和 0.001之间,且可设置为随着训练进程逐渐减小。

训练模型

# Optimization

optimizer = tf.train.AdamOptimizer(learning_rate)

update_step = optimizer.apply_gradients( zip(clipped_gradients, params))

定义训练环境

在我们的实验中,我们使用标准的随机梯度下降(tf.train.GradientDescentOptimizer),并采用了递减的学习率方案,因此也就有更好的性能。

定义您的训练环境,可以指定训练是发生在CPU还是GPU上。

开始训练 NMT 模型

定义数据提供器

让我们开始训练第一个 NMT 模型,将越南语翻译为英语。代码的入口是** **nmt.py。

构造训练器

我们将使用小规模的 Ted 演讲并行语料库(133k 的训练样本)进行训练。所有的数据都可从以下链接找到:

训练器需要一个训练程序和一个训练优化函数。

我们将使用 tst2012 作为开发数据集,tst 2013 作为测试数据集。运行以下命令行下载数据训练 NMT 模型:

提供数据

nmt/scripts/download_iwslt15.sh /tmp/nmt_data

事件处理器

运行以下命令行开始训练:

回调函数event_handler在一个之前定义好的事件发生后会被调用。例如,我们可以在每步训练结束后查看误差。

mkdir /tmp/nmt_model

python -m nmt.nmt

--src=vi --tgt=en

--vocab_prefix=/tmp/nmt_data/vocab  

--train_prefix=/tmp/nmt_data/train

--dev_prefix=/tmp/nmt_data/tst2012  

--test_prefix=/tmp/nmt_data/tst2013

--out_dir=/tmp/nmt_model

--num_train_steps=12000

--steps_per_stats=100

--num_layers=2

--num_units=128

--dropout=0.2

--metrics=bleu

开始训练

以上命令行训练一个

最后,我们传入训练循环数(num_epoch)和一些别的参数,调用 trainer.train 来开始训练。

2 层的 LSTM seq2seq 模型,带有 128-dim 的隐藏单元和 12 个 epochs 的嵌入。我们使用 0.2(或然率为

应用模型

0.8)的 dropout 值。如果没误差,在我们训练中随着降低混淆度,我们应该能看到类似于以下的 logs。

定义解码部分

# First evaluation, global step 0

eval dev: perplexity 17193.66

eval test: perplexity 17193.27

# Start epoch 0, step 0, lr 1, Tue Apr 25 23:17:41 2017

sample train data:

src_reverse: Điều đó , dĩ nhiên , là câu chuyện trích ra từ học thuyết của Karl Marx .

ref: That , of course , was the distilled from the theories of Karl Marx .

epoch 0 step 100 lr 1 step-time 0.89s wps 5.78K ppl 1568.62 bleu 0.00

epoch 0 step 200 lr 1 step-time 0.94s wps 5.91K ppl 524.11 bleu 0.00

epoch 0 step 300 lr 1 step-time 0.96s wps 5.80K ppl 340.05 bleu 0.00

epoch 0 step 400 lr 1 step-time 1.02s wps 6.06K ppl 277.61 bleu 0.00

epoch 0 step 500 lr 1 step-time 0.95s wps 5.89K ppl 205.85 bleu 0.00

使用上面定义的 encoder 和 decoder 函数来推测翻译后的对应id和分数。

更多细节,请查看:train.py。

定义数据

我们可以使用 Tensorboard 在训练过程中查看模型的总结:

我们先初始化id和分数来生成tensors来作为输入数据。在这个预测例子中,我们用wmt14.test数据中的第一个记录来做推测,最后我们用”源字典”和”目标字典”来列印对应的句子结果。

tensorboard --port 22222 --logdir /tmp/nmt_model/

测试

通过以下简单的变化,就能逆向完成英语到越南语的翻译。

现在我们可以进行预测了。我们要在feed_order提供对应参数,放在executor上运行以取得id和分数结果。

--src=en --tgt=vi

总结

推理——如何生成翻译

端到端的神经网络机器翻译是近几年兴起的一种全新的机器翻译方法。在本文中,我们介绍了NMT中典型的“编码器-解码器”框架。由于NMT是一个典型的Seq2Seq(Sequence to Sequence,序列到序列)学习问题,因此,Seq2Seq中的query改写(query rewriting)、摘要、单轮对话等问题都可以用本教程的模型来解决。

当你训练你的NMT模型时(并且一旦你已经训练了模型),可以在给定之前不可见的源语句的情况下获得翻译。这一过程被称作推理。训练与推理之间有一个明确的区分(测试):在推理时,我们只访问源语句,即encoder_inputs。解码的方式有很多种,包括 greedy 解码、采样解码和束搜索解码(beam-search)。下面我们讨论一下greedy 解码策略。

参考文献

其想法简单,我们将在图 3 中作说明:

Koehn P. Statistical machine translationM]. Cambridge University Press, 2009.

在训练获取 encoder_state 的过程中,我们依然以相同方式编码源语句,并且 encoder_state 用于初始化解码器。

Cho K, Van Merri?nboer B, Gulcehre C, et al. Learning phrase representations using RNN encoder-decoder for statistical machine translationC]//Proceedings of the 2014 Conference on Empirical Methods in Natural Language Processing , 2014: 1724-1734.

一旦解码器接收到开始符 (在我们的代码中指 tgt_sos_id),就开始解码处理(翻译)。

Chung J, Gulcehre C, Cho K H, et al. Empirical evaluation of gated recurrent neural networks on sequence modelingJ]. arXiv preprint arXiv:1412.3555, 2014.

最大的单词,其 id 与最大的 logit 值相关联,正如被发出的词(这是 greedy 行为)。例如在图 3 中,单词 moi 在第一个解码步中具有最高的翻译概率。接着我们把这一单词作为输入馈送至下一个时间步。

Bahdanau D, Cho K, Bengio Y. Neural machine translation by jointly learning to align and translateC]//Proceedings of ICLR 2015, 2015.

这一过程会持续到这句话的终止符「</ s>」,然后输出(在我们的代码中是 tgt_eos_id)。

Papineni K, Roukos S, Ward T, et al. BLEU: a method for automatic evaluation of machine translationC]//Proceedings of the 40th annual meeting on association for computational linguistics. Association for Computational Linguistics, 2002: 311-318.

图片 14

—完—

图片 15

小程序|全类别AI学习教程

图 3. Greedy 解码——一个实例:已训练的 NMT 模型如何使用 greedy 搜索为源语句 Je suis étudiant 生成翻译。

推理与训练的区别在于步骤 3。推理不总是馈送作为输入的正确目标词,而是使用被模型预测的单词。下面是实现 greedy 解码的代码。它与训练解码器非常相似。

# Helper

helper = tf.contrib.seq2seq.GreedyEmbeddingHelper(

embedding_decoder,

tf.fill([batch_size], tgt_sos_id), tgt_eos_id)

# Decoder

decoder = tf.contrib.seq2seq.BasicDecoder(

                decoder_cell, helper, encoder_state,

                output_layer=projection_layer)# Dynamic decoding

outputs, _ = tf.contrib.seq2seq.dynamic_decode(

                decoder, maximum_iterations=maximum_iterations)

translations = outputs.sample_id

我们在本文中使用了 GreedyEmbeddingHelper 而不是 TrainingHelper。由于无法提前知道目标语句的长度,我们使用 maximum_iterations 限制翻译的长度。一个启发是解码最多两倍的源语句长度。

maximum_iterations = tf.round(tf.reduce_max(source_sequence_length) * 2)

我们已经训练了一个模型,现在可以创建一个推理文件并翻译一些语句:

cat > /tmp/my_infer_file.vi# (copy and paste some sentences from /tmp/nmt_data/tst2013.vi)

python -m nmt.nmt

--model_dir=/tmp/nmt_model

--inference_input_file=/tmp/my_infer_file.vi

--inference_output_file=/tmp/nmt_model/output_infer

cat /tmp/nmt_model/output_infer # To view the inference as output

注意上述指令也可在模型被训练时运行,只要存在一个训练检查点。详见 inference.py。

中级

在训练了一些最基本的序列到序列模型之后,我们现在更进一步。为了打造当前最优的神经机器翻译系统,我们需要更多的秘诀:注意力机制。该机制由

Bahdanau 等人在 2015 年首次提出( Luong等人和其他人完善了它,其核心思想是当我们翻译时通过「注意」相关的源内容,建立直接的短连接。注意力机制的一个很好副产品是源语句和目标语句之间的一个易于可视化的对齐矩阵(如图

4 所示)。

图片 16

图片 17

图 4. 注意力可视化——源语句与目标语句之间对齐的实例。图片来自 2015 年 Bahdanau 等人的论文。

请记住在vanilla序列到序列模型中,当开始编码处理时,我们把最后的源状态从编码器传递到解码器。这对短、中长度的语句效果很好;对于长句子,单一固定大小的隐状态成为了信息瓶颈。注意力机制没有摈弃源RNN中计算的所有隐状态,而是提出了允许解码器窥探它们的方法(把它们看作是源信息的动态存储)。如此,注意力机制提升了长句的翻译质量。现在,注意力机制实至名归,已成功应用于其他诸多任务(比如语音识别)。

注意力机制背景

我们现在描述一下注意力机制的实例(Luonget al., 2015),它已经被应用到几个最新型的系统当中了,包括开源工具,比如OpenNMT( TF seq2seq API。我们还将会提供注意力机制相关变体的内容。

图片 18

图 5. 注意力机制——基于注意力的 NMT 系统(Luong et al., 2015 中有具体描述)。

我们重点详解注意力计算过程中的第一步。为了更加清晰,我们没有展示图(2)中的嵌入层和投影层。

如图 5 所示,注意力计算发生在解码步骤中的每一步。它包含下列步骤:

  1. 当前目标隐蔽状态和所有源状态(source state)进行比较,以导出权重(weight),见图 4。

  2. 基于注意力权重,我们计算了一个背景向量(context vector),作为源状态的平均权值。

  3. 将背景向量与当前目标隐蔽态进行结合以生成最终的注意力向量。

图片 19

4. 此注意力向量将作为下一时序步骤的输入。前三个步骤可以由下列公式总结:

图片 20

图片 21

这里,函数score 用于将目标隐蔽状态 ht 和每一个源状态 hs进行比较,结果会被标准化成生成式注意力权重(一个源位置的分布)。其实有很多种关于评分函数(scoring function)的选择;比较流行的评分函数包括公式(4)中给出的乘法与加法形式。一旦被计算,注意力向量 at 就会用于推导 softmax logit 和损失。这与 vanilla seq2seq 模型顶层的目标隐蔽态相似。函数 f 也可以利用其它形式。

图片 22

注意力机制的多种实现方法可由以下链接获得:

注意力机制中有什么相关注意事项呢?

上述公式表明注意力机制有很多种变体。这些变体依赖于评分函数(scoring function)和注意力函数(attention function)的形式,也依赖于前一状态 ht-1,而不依赖于开始建议的评分函数 ht(Bahdanau et al.,2015)。实际上我们发现的只有一些选择上的注意事项。一,注意力的基本形式,例如,目标和源之间的直接联系需要被呈现。二,把注意力向量输入给下一时间步骤,以把之前的注意力决策告知给网络(Luong

et al., 2015)。最后,评分函数的选择经常可以造成不同的性能表现。

Attention Wrapper API

在我们的Attention Wrapper API 的实现中,借鉴了 Weston et al., 2015 在 onmemory network工作中的术语。相比于拥有可读、可写的记忆,此教程中的 attention 机制仅是可读的记忆。特别是对隐藏态(或者隐藏态的变体,例如$$Woverline{h}_s$$ in Luong's scoring style or $$W_2overline{h}_s$$ )的设定,被认为是「记忆」。在每个时间步下,我们使用现有的目标隐藏态作为「query」决定读取哪一部分记忆。通常情况下,query需要与单个记忆条相对应的 keys进行对比。在上面对注意机制的演示中,我们偶然使用一套源隐藏态(或者其变体,例如$$W_1h_t$$)作为「key」。你们可以从这种记忆网络术语中获取灵感,找到其他形式的attention。

由于 attention wrapper,就不再需要扩展我们带有 attention 的 vanilla seq2seq 代码。这部分文件为 attention_model.py。

首先,我们需要定义一种注意机制,例如采用 Luong et al., 2015 的研究。

# attention_states: [batch_size, max_time, num_units]

attention_states = tf.transpose(encoder_outputs, [1, 0, 2])

# Create an attention mechanism

attention_mechanism = tf.contrib.seq2seq.LuongAttention(

num_units, attention_states,

memory_sequence_length=source_sequence_length)

在之前的Encoder 部分,encoder_outputs 是一套顶层的掩藏态源,形式为 [max_time, batch_size,

num_units](因为我们使用 dynamic_rnn with time_major设定)。在注意机制上,我们需要保证通过的「memory」是批次为主的,所以需要调换 attention_states。我们通过source_sequence_length 保证注意机制的权重有适当的规范化(只在 non-padding的位置)。定义完注意机制之后,我们使用 AttentionWrapper 来包裹解码单元。

decoder_cell = tf.contrib.seq2seq.AttentionWrapper(

                   decoder_cell, attention_mechanism,

                   attention_layer_size=num_units)

剩下的代码基本和编码器一转样 (

上手—打造一个基于注意力的 NMT 模型

为了使注意力发挥作用,我们需要用到luong、scaled_luong、bahdanau 或 normed_bahdanau其中的一个作为训练期间注意力标志(attentionflag)的值。该标志指定了我们将要使用的注意力机制。除此之外,我们需要为注意力模型创建一个新目录,因此无需重新使用之前训练的基本 NMT模型。

运行以下指令开始训练:

mkdir /tmp/nmt_attention_model

python -m nmt.nmt

--attention=scaled_luong

--src=vi --tgt=en

--vocab_prefix=/tmp/nmt_data/vocab  

--train_prefix=/tmp/nmt_data/train

--dev_prefix=/tmp/nmt_data/tst2012  

--test_prefix=/tmp/nmt_data/tst2013

--out_dir=/tmp/nmt_attention_model

--num_train_steps=12000

--steps_per_stats=100

--num_layers=2

--num_units=128

--dropout=0.2

--metrics=bleu

训练之后,我们可以使用带有新 model_dir 的相同推理指令进行推理:

python -m nmt.nmt

--model_dir=/tmp/nmt_attention_model

--inference_input_file=/tmp/my_infer_file.vi

--inference_output_file=/tmp/nmt_attention_model/output_infer

基准

IWSLT 英语-越南语

训练:133k 的样本,dev=tst2012,test=tst2013

图片 23

训练速度:在英伟达 K40m 上是 0.37s 的时间步、15.3k 的 wps,在 Titan X 上是 0.17 s 的时间步,32.2k 的 wps。

WMT 德语-英语

训练:4.5M 的样本量,dev=newstest2013,test=newtest2015

图片 24

训练速度:在英伟达 K40m 上是 2.1s 的时间步,3.4k 的 wps,在英伟达 Titan X 上是 0.7s 的时间步,8.7k 的 wps。

为了查看 GNMT 注意的加速度,我们只在 K40m 上做了基准测试:

图片 25

WMT 英语-德语 全对比

第二行是我们 GNMT 注意模型:模型 1(4 层),模型 2(8 层)。

图片 26

其他资源

若想深入了解神经机器翻译和序列-序列模型,我们非常推荐以下资源:

Neural Machine Translation and Sequence-to-sequence Models: A Tutorial:

Neural Machine Translation - Tutorial ACL 2016:

Thang Luong's Thesis on Neural Machine Translation:

用于构建 seq2seq 模型的工具很多:

Stanford NMT [Matlab]

tf-seq2seq [TensorFlow]

Nemantus [Theano]

OpenNMT [Torch]

参考内容

[1]Sequence to sequence learning with neural networks( Sutskever, Oriol Vinyals, and Quoc V. Le. NIPS, 2014.

[2]Learning phrase representations using RNN encoder-decoder forstatistical machine translation(), Kyunghyun Cho, Bart Van Merrienboer, Caglar Gulcehre, Dzmitry Bahdanau, Fethi Bougares,Holger Schwenk, and Yoshua Bengio. EMNLP 2014.

[3] Neural machine translation by jointly learning to align and translate(), Dzmitry Bahdanau, Kyunghyun Cho,and Yoshua Bengio. ICLR, 2015.

[4] Effective approaches to attention-based neural machine translation(), Minh-Thang Luong, Hieu Pham, and Christopher D Manning. EMNLP, 2015.

[5] Google‘s Neural Machine Translation System: Bridging the Gap between Human and Machine Translation (.

机器之心原文参考:

本文由澳门新葡8455最新网站发布于澳门新葡8455最新网站,转载请注明出处:基于PaddlePaddle的机器翻译教程,神经机器翻译

关键词:

MIT等人工神经网络评分系统,AI控制了动物大脑

原标题:【深度学习模型哪个最像人脑?】MIT等人工神经网络评分系统,DenseNet实力夺冠! 新智元报道 神经网络模型...

详细>>

想捂也捂不住的汽车安全漏洞,几秒钟黑入并开走特斯拉

原标题:黑客用价值约4000元人民币设备 几秒钟黑入并开走特斯拉 原标题:600 美元秒开特斯拉 Model S,这帮“学院派...

详细>>

人类和月球,星球物质被超级黑洞吞噬

原标题:新阿波罗8号《地出》纪录片是“写给地球的情书” 这些惊艳的图片向我们展示了美国国家航空航天局(NA...

详细>>

惠普发布金属喷射3D打印机,惠普推出首款金属增材制造系统M

原标题:【产品】惠普推出首款金属增材制造系统Metal Jet 原标题:惠普推出批量化生产金属 3D 的打印技术 Metal Jet 澳...

详细>>