转载自:Seq2Seq模型和Attention机制,如侵联删

pdf: NEURAL MACHINE TRANSLATION BY JOINTLY LEARNING TO ALIGN AND TRANSLATE

1 RNN的多种结构

首先从RNN的结构说起,根据输出和输入序列不同数量RNN可以有多种不同的结构,不同结构自然就有不同的引用场合。如下图

Seq2Seq模型和Attention机制-StubbornHuang Blog
  • one to one结构,仅仅只是简单的给一个输入得到一个输出,此处并未体现序列的特征,例如图像分类场景。
  • one to many结构,给一个输入得到一系列输出,这种结构可用于生产图片描述的场景。
  • many to one结构,给一系列输入得到一个输出,这种结构可用于文本情感分析,对一些列的文本输入进行分类,看是消极还是积极情感。
  • many to many结构,给一些列输入得到一系列输出,这种结构可用于翻译或聊天对话场景,对输入的文本转换成另外一些列文本。
  • 同步many to many结构,它是经典的RNN结构,前一输入的状态会带到下一个状态中,而且每个输入都会对应一个输出,我们最熟悉的就是用于字符预测了,同样也可以用于视频分类,对视频的帧打标签。

2 Seq2Seq模型

Seq2Seq是2014年Google提出的一个模型Sequence to Sequence Learning with Neural Networks。论文中提出的 Seq2Seq 模型可简单理解为由三部分组成:EncoderDecoder和连接两者的State Vector (中间状态向量) C
在上图many to many的两种模型中,可以看到第四和第五种是有差异的,经典的RNN结构的输入和输出序列必须要是等长,它的应用场景也比较有限。而第四种它可以是输入和输出序列不等长,这种模型便是Seq2Seq模型,即Sequence to Sequence。
Seq2Seq实现了从一个序列到另外一个序列的转换,比如google曾用Seq2Seq模型加attention模型来实现了翻译功能,类似的还可以实现聊天机器人对话模型。经典的RNN模型固定了输入序列和输出序列的大小,而Seq2Seq模型则突破了该限制。
这种结构最重要的地方在于输入序列和输出序列的长度是可变的
举个栗子

在机器翻译:输入(hello) -> 输出 (你好)。输入是1个英文单词,输出为2个汉字。 在对话机器中:我们提(输入)一个问题,机器会自动生成(输出)回答。这里的输入和输出显然是长度没有确定的序列(sequences)

要知道,在以往的很多模型中,我们一般都说输入特征矩阵,每个样本对应矩阵中的某一行。就是说,无论是第一个样本还是最后一个样本,他们都有一样的特征维度。但是对于翻译这种例子,难道我们要让每一句话都有一样的字数吗,那样的话估计五言律诗和七言绝句又能大火一把了,哈哈。但是这不科学呀,所以就有了Seq2Seq这种结构。

Seq2Seq模型的应用有:

3 Encoder-Decoder结构

3.1 Encoder-Decoder介绍

所谓的Sequence2Sequence任务主要是泛指一些Sequence到Sequence的映射问题,Sequence在这里可以理解为一个字符串序列,当我们在给定一个字符串序列后,希望得到与之对应的另一个字符串序列(如 翻译后的、如语义上对应的)时,这个任务就可以称为Sequence2Sequence了。

在现在的深度学习领域当中,通常的做法是将输入的源Sequence编码到一个中间的context当中,这个context是一个特定长度的编码(可以理解为一个向量),然后再通过这个context还原成一个输出的目标Sequence。

如果用人的思维来看,就是我们先看到源Sequence,将其读一遍,然后在我们大脑当中就记住了这个源Sequence,并且存在大脑的某一个位置上,形成我们自己的记忆(对应Context),然后我们再经过思考,将这个大脑里的东西转变成输出,然后写下来。

那么我们大脑读入的过程叫做Encoder,即将输入的东西变成我们自己的记忆,放在大脑当中,而这个记忆可以叫做Context,然后我们再根据这个Context,转化成答案写下来,这个写的过程叫做Decoder。其实就是编码-存储-解码的过程。

而对应的,大脑怎么读入(Encoder怎么工作)有一个特定的方式,怎么记忆(Context)有一种特定的形式,怎么转变成答案(Decoder怎么工作)又有一种特定的工作方式。

好了,现在我们大体了解了一个工作的流程Encoder-Decoder后,我们来介绍一个深度学习当中,最经典的Encoder-Decoder实现方式,即用RNN来实现。

Seq2Seq模型和Attention机制-StubbornHuang Blog

在RNN Encoder-Decoder的工作当中,我们用一个RNN去模拟大脑的读入动作,用一个特定长度的特征向量去模拟我们的记忆,然后再用另外一个RNN去模拟大脑思考得到答案的动作,将三者组织起来利用就成了一个可以实现Sequence2Sequence工作的“模拟大脑”了。 而我们剩下的工作也就是如何正确的利用RNN去实现,以及如何正确且合理的组织这三个部分了。

获取语义向量C最简单的方式就是直接将最后一个输入的隐状态作为语义向量C。也可以对最后一个隐含状态做一个变换得到语义向量,还可以将输入序列的所有隐含状态做一个变换得到语义变量。

3.2 Encoder-Decoder分析

(1)Encoder
给定句子对

(2)Decoder
得到中间语义向量C后,使用Decoder进行解码。Decoder根据中间状态向量C和已经生成的历史信息y_{1},y_{2},...,y_{i-1}去生成t时刻的单词y_{i}

y_{i} = g(C,y_{1},y_{2},...,y_{i-1})

如果直接将C输入到Decoder中,则是Seq2Seq模型的第一种模型:

Seq2Seq模型和Attention机制-StubbornHuang Blog

如果将C当作Decoder的每一时刻输入,则是Seq2Seq模型的第二种模型:

Seq2Seq模型和Attention机制-StubbornHuang Blog

4 Attention机制

4.1 Encoder-Decoder结构的局限性

(1)Encoder和Decoder的唯一联系只有语义编码C

即将整个输入序列的信息编码成一个固定大小的状态向量再解码,相当于将信息”有损压缩”。很明显这样做有两个缺点:

  • 中间语义向量无法完全表达整个输入序列的信息。
  • 随着输入信息长度的增加,由于向量长度固定,先前编码好的信息会被后来的信息覆盖,丢失很多信息。

(2)不同位置的单词的贡献都是一样的

Decoder过程,其输出的产生如下:

\begin{array}{l}
y_{1}=g\left(C, h_{0}^{\prime}\right) \\
y_{2}=g\left(C, y_{1}\right) \\
y_{3}=g\left(C, y_{1}, y_{2}\right)
\end{array}

明显可以发现在生成y_{1}y_{2}y_{3}时,语义编码C对它们所产生的贡献都是一样的。例如翻译Cat chase mouse,Encoder-Decoder模型逐字生成:“猫”、“捉”、“老鼠”。在翻译mouse单词时,每一个英语单词对“老鼠”的贡献都是相同的。如果引入了Attention模型,那么mouse对于它的影响应该是最大的。

4.2 Attention机制原理

为了解决上面两个问题,于是引入了Attention模型。Attention模型的特点是Decoder不再将整个输入序列编码为固定长度的中间语义向量C,而是根据当前生成的新单词计算新的C_{i},使得每个时刻输入不同的C,这样就解决了单词信息丢失的问题。引入了Attention的Encoder-Decoder模型如下图

Seq2Seq模型和Attention机制-StubbornHuang Blog

对于刚才提到的那个“猫捉老鼠”的翻译过程变成了如下:

\begin{array}{l}
y_{1}=g\left(C_{1}, h_{0}^{\prime}\right) \\
y_{2}=g\left(C_{2}, y_{1}\right) \\
y_{3}=g\left(C_{3}, y_{1}, y_{2}\right)
\end{array}

整个翻译流程如下:

Seq2Seq模型和Attention机制-StubbornHuang Blog

图中输入是Cat chase mouse,Encoder中隐层h_{1}h_{2}h_{3}可看做经过计算的Cat chase mouse这些词的信息。

Seq2Seq模型和Attention机制-StubbornHuang Blog

使用a_{ij}表示Encoder中第j阶段的h_{j}和解码时第i阶段的相关性,计算出解码需要的中间语义向量C_{i}C_{1}和“猫”关系最近,相对应的a_{11}要比a_{12}a_{13}大;而C_{2}和“捉”关系最近,相对比的a_{22}要比a_{21}a_{23}大;同理,C_{3}和“老鼠关系”最近,相对应的a_{33}要比a_{31}a_{32}大。

Seq2Seq模型和Attention机制-StubbornHuang Blog

那么参数a_{ij}是如何得到的呢?
Encoder中第j个隐层单元h_{j}和Decoder第i-1个隐层单元h_{i-1}^{\prime}经过运算得到a_{ij}
例如a_{1j}的计算过程:

Seq2Seq模型和Attention机制-StubbornHuang Blog

例如a_{2j}的计算过程:

Seq2Seq模型和Attention机制-StubbornHuang Blog

那具体是怎么运算得到的呢?我们来把上面的过程用公式严谨的表达出来。我们按照原论文的标点符号来进行推导。

Seq2Seq模型和Attention机制-StubbornHuang Blog

语义向量C_{i}由Encoder的隐向量h_{i}加权求和表示:

c_{i}=\sum_{j=1}^{T_{x}}\alpha_{i j}h_{j}

每个隐向量h_{j}对应的权重\alpha_{ij}可由下式计算得到

\alpha_{i j}=\frac{\exp(e_{i j})}{\sum_{k=1}^{T_{x}}\exp(e_{i k})}

其中,

e_{i j}=\alpha(s_{i-1},h_{j})

上式中的s_{i-1}就是上图中的h_{i-1}^{\prime}

这个\alpha具体怎么算,有不同的方法,论文里是用了神经网络去算

\epsilon_{i j}=\alpha(s_{i-1},h_{j})=v^{T}\mathrm{tanh}(W s_{i-1}+V h_{j})

还可以用二次型矩阵来计算:

e_{i j}=\alpha(s_{i-1},h_{j})=s_{i-1}W_{i-1,j}h_{j}

通过训练,注意力机制可以对关系较大的输入输出的赋以较大权重(两者在转换中对齐的概率更大),对位置信息进行了建模,而因此减少了信息损失,能专注于更重要的信息进行序列预测。

我们可以看到,attention的效果如下图所示,确实是不同单词的注意力是不一样的。

Seq2Seq模型和Attention机制-StubbornHuang Blog

这是Attention Mechanism第一次找到很合适的用武之地。在BERT中,还会用到Attention Mechanism。

参考