深度学习·神经网络·计算机视觉NLP大数据 爬虫Python AI Sql

机器翻译不可不知的Seq2Seq模型

2018-05-19  本文已影响34人  机器学习算法工程师

前 言

Seq2Seq,全称Sequence to Sequence。它是一种通用的编码器——解码器框架,可用于机器翻译、文本摘要、会话建模、图像字幕等场景中。Seq2Seq并不是GNMT(Google Neural Machine Translation)系统的官方开源实现。框架的目的是去完成更广泛的任务,而神经机器翻译只是其中之一。在循环神经网络中我们了解到如何将一个序列转化成定长输出。在本文中,我们将探究如何将一个序列转化成一个不定长的序列输出(如机器翻译中,源语言和目标语言的句子往往并没有相同的长度)。

简单入门

(1)****设计目标

(2)****主要概念

许多objects都是使用键值对来配置的。这些参数通常以YAML的形式通过配置文件传递,或者直接通过命令行传递。配置通常是嵌套的,如下例所示:

model_params:    attention.class:                                                       seq2seq.decoders.attention.AttentionLayerBahdanau    attention.params:        num_units: 512        embedding.dim: 1024        encoder.class: seq2seq.encoders.BidirectionalRNNEncoder    encoder.params:        rnn_cell:        cell_class: LSTMCell    cell_params:        num_units: 512

InputPipeline定义了如何读取、解析数据并将数据分隔成特征和标签。如果您想要读取新的数据格式,我们需要实现自己的输入管道。

Encoder-Decoder

整个过程可以用下面这张图来诠释:

image

图 1:最简单的Encoder-Decoder模型

其中,X、Y均由各自的单词序列组成(X,Y可以是同一种语言,也可以是两种不同的语言):

X = (x1,x2,...,xm)

Y = (y1,y2,...,yn)

Encoder:是将输入序列通过非线性变换编码成一个指定长度的向量C(中间语义表示),得到c有多种方式,最简单的方法就是把Encoder的最后一个隐状态赋值给c,还可以对最后的隐状态做一个变换得到c,也可以对所有的隐状态做变换。

C = F(x1,x2,...,xm)

Decoder:是根据向量C(encoder的输出结果)和之前生成的历史信息y1,y2,...,yn来生成i时刻要生成的单词yi。

yi = G( C , y1,y2,...,yn-1)

下图是一个生成对联的示意图。

image

图 2:生活中的小栗子

在RNN中,当前时间的隐藏状态由上一时间的状态和当前时间输入决定的,即: image 获得了各个时间段的隐藏层以后,再将隐藏层的信息汇总,生成最后的语义向量 image 当然,有一种最简单的方法是将最后的隐藏层作为语义向量C,即 image 可以看做编码的逆过程。这个阶段,我们根据给定的语义向量C和之前已经生成的输出序列y1,y2,...,yt-1来预测下一个输出的单词yt,即 image

也可以写作

image

在RNN中,也可以简化成

image

其中s是输出RNN(即RNN解码器)中的隐藏层,C代表之前编码器得到的语义向量,yt-1表示上个时间段的输出,反过来作为这个时间段的输入。g可以是一个非线性的多层神经网络,产生词典中各个词语属于yt的概率。

Attention模型

        encoder-decoder模型虽然非常经典,但是局限性也非常大。最大的局限性就在于编码和解码之间的唯一联系就是一个固定长度的语义向量C。也就是说,编码器要将整个序列的信息压缩进一个固定长度的向量中去。但是这样做有两个弊端,一是语义向量无法完全表示整个序列的信息,二是先输入的内容携带的信息会被后输入的信息稀释掉。输入序列越长,这个现象就越严重。这就使得在解码的时候一开始就没有获得输入序列足够的信息, 那么解码时准确率就要打一定折扣。

        为了解决上述问题,在 Seq2Seq出现一年之后,Attention模型被提出了。该模型在产生输出的时候,会产生一个注意力范围来表示接下来输出的时候要重点关注输入序列的哪些部分,然后根据关注的区域来产生下一个输出,如此反复。attention 和人的一些行为特征有一定相似之处,人在看一段话的时候,通常只会重点注意具有信息量的词,而非全部词,即人会赋予每个词的注意力权重不同。attention 模型虽然增加了模型的训练难度,但提升了文本生成的效果。模型的大概示意图如下。
image

图 3:经典的attention模型

        每一个c会自动去选取与当前所要输出的y最合适的上下文信息。具体来说,我们用 aij 衡量编码中第j阶段的hj和解码时第i阶段的相关性,最终Decoder中第i阶段的输入的上下文信息 ci 就来自于所有 hj对 aij的加权和。
image

图 4:不同关注度示意图

        输入的序列是“我爱中国”,因此,Encoder中的h1、h2、h3、h4就可以分别看做是“我”、“爱”、“中”、“国”所代表的信息。在翻译成英语时,第一个上下文c1应该和“我”这个字最相关,因此对应的 a11就比较大,而相应的 a12 、a13 、 a14 就比较小。c2应该和“爱”最相关,因此对应的 a22 就比较大。最后的c3和h3、h4最相关,因此 a33 、 a34的值就比较大。具体模型权重 aij 是如何计算出来的呢?

比如:
输入的是英文句子:Tom chase Jerry,生成:“汤姆”,“追逐”,“杰瑞”。
注意力分配概率分布值的通用计算过程:

image

图 5:权重计算示意图

        当前输出词Yi针对某一个输入词j的注意力权重由当前的隐层Hi,以及输入词j的隐层状态(hj)共同决定;然后再接一个sofrmax得到0-1的概率值。即通过函数F(hj,Hi)来获得目标单词Yi和每个输入单词对应的对齐可能性。更多细节,请大家参看知乎何之源的文章,文末会给出文章链接。

CNN的seq2seq

        现在大多数场景下使用的Seq2Seq模型是基于RNN构成的,虽然取得了不错的效果,但也有一些学者发现使用CNN来替换Seq2Seq中的encoder或decoder可以达到更好的效果。最近,FaceBook发布了一篇论文:《Convolutional Sequence to Sequence Learning》,提出了完全使用CNN来构成Seq2Seq模型,用于机器翻译,超越了谷歌创造的基于LSTM机器翻译的效果。此网络获得暂时性胜利的重要原因在于采用了很多的窍门,这些技巧值得学习:

底层的CNN捕捉相聚较近的词之间的依赖关系,高层CNN捕捉较远词之间的依赖关系。通过层次化的结构,实现了类似RNN(LSTM)捕捉长度在20个词以上的Sequence的依赖关系的功能。

假设一个sequence序列长度为n,采用RNN(LSTM)对其进行建模 需要进行n次操作,时间复杂度O(n)。相比,采用层叠CNN只需要进行n/k次操作,时间复杂度O(n/k),k为卷积窗口大小。

RNN对sequence的建模依赖于序列的历史信息,因此不能并行实现。相比,层叠CNN对整个sequence进行卷积,不依赖序列历史信息,可以并行实现,特别是在工业生产,面临处理大数据量和实时要求比较高的情况下,模型训练更快。

融合了Residual connection、liner mapping的多层attention。通过attention决定输入的哪些信息是重要的,并逐步往下传递。把encoder的输出和decoder的输出做点乘(dot products),再归一化,再乘以encoder的输入X之后做为权重化后的结果加入到decoder中预测目标语言序列。

采用GLU做为gate mechanism。GLU单元激活方式如下公式所示:

image

应用领域

image

<center style="margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; word-wrap: break-word !important;">图 6:采用Seq2Seq效果对比</center>

从图像可以看出,模型中的语境向量很明显的包涵了输入序列的语言意义,能够将由不同次序所产生的不同意思的语句划分开来,这对于提升机器翻译的准确率很有帮助。当前,主流的在线翻译系统都是基于深度学习模型来构建的,包括 Google、百度等。

<center data-anchor-id="p096" style="margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; word-wrap: break-word !important; color: rgb(44, 62, 80);">图 7:对话生成Chatbot</center>

小结

         Seq-to-Seq模型从一开始在机器翻译领域被提出,到后来被广泛应用到NLP各个领域,原因就在于其对序列数据的完美使用,而且解决了以前RNN模型输出维度固定的难题,所以很快得到了推广。但Seq-to-Seq不是万能药,只有在合适的场景,它才能发挥它最大的作用。

参考资料

  1. 源码地址:https://github.com/google/seq2seq

  2. 《Convolutional Sequence to Sequence Learning》:
    https://link.zhihu.com/?target=https%3A//arxiv.org/abs/1705.03122

  3. 《Language modeling with gated linear units》:
    https://link.zhihu.com/?target=https%3A//arxiv.org/abs/1612.08083

  4. 《A Convolutional Encoder Model for Neural Machine Translation》:
    https://link.zhihu.com/?target=https%3A//arxiv.org/abs/1611.02344

  5. Google Neural Machine Translation:
    https://research.googleblog.com/2016/09/a-neural-network-for-machine.html

  6. 简书:Datartisan
    https://www.jianshu.com/p/124b777e0c55

  7. 知乎作者:李宁
    https://zhuanlan.zhihu.com/p/30516984

  8. 知乎作者:何之源
    https://zhuanlan.zhihu.com/p/28054589

  9. PaperWeekly:张俊
    https://zhuanlan.zhihu.com/p/26753131


QQ交流群:651616387 请备注 : 来自简书
微信公众号:机器学习算法工程师 ----二维码见下图


扫码关注微信号:机器学习算法工程师,更多干货分享, 或加个人微信,拉你进机器学习、深度学习交流群

image
上一篇下一篇

猜你喜欢

热点阅读