@TOC

<hr style=" border:solid; width:100px; height:1px;" color=#000000 size=1">

循环神经网络RNN结构被广泛应用于自然语言处理、机器翻译、语音识别、文字识别等方向。本文主要介绍经典的RNN结构,以及RNN的变种(包括Seq2Seq结构和Attention机制)。希望这篇文章能够帮助初学者更好地入门。

1.经典的RNN结构

初步了解RNN, Seq2Seq, Attention注意力机_全连接

这就是最经典的RNN结构,它的输入是:

初步了解RNN, Seq2Seq, Attention注意力机_全连接_02

输出为:

初步了解RNN, Seq2Seq, Attention注意力机_全连接_03

也就是说,输入和输出序列必有相同的时间长度!

初步了解RNN, Seq2Seq, Attention注意力机_机器翻译_04

初步了解RNN, Seq2Seq, Attention注意力机_机器翻译_05

初步了解RNN, Seq2Seq, Attention注意力机_全连接_06

初步了解RNN, Seq2Seq, Attention注意力机_机器翻译_07

初步了解RNN, Seq2Seq, Attention注意力机_机器翻译_08

初步了解RNN, Seq2Seq, Attention注意力机_机器翻译_09

初步了解RNN, Seq2Seq, Attention注意力机_机器翻译_10

初步了解RNN, Seq2Seq, Attention注意力机_全连接_11

2.Sequence to Sequence模型

初步了解RNN, Seq2Seq, Attention注意力机_全连接_12

在Seq2Seq结构中,编码器Encoder把所有的输入序列都编码成一个统一的语义向量Context,然后再由解码器Decoder解码。在解码器Decoder解码的过程中,不断地将前一个时刻 t-1 的输出作为后一个时刻 **t **的输入,循环解码,直到输出停止符为止。

初步了解RNN, Seq2Seq, Attention注意力机_机器翻译_13

初步了解RNN, Seq2Seq, Attention注意力机_机器翻译_14

初步了解RNN, Seq2Seq, Attention注意力机_全连接_15

初步了解RNN, Seq2Seq, Attention注意力机_复杂度_16

3.Embedding

还有一点细节,就是如何将前一时刻输出类别index(数值)送入下一时刻输入(向量)进行解码。假设每个标签对应的类别index如下:

初步了解RNN, Seq2Seq, Attention注意力机_全连接_17

初步了解RNN, Seq2Seq, Attention注意力机_机器翻译_18

初步了解RNN, Seq2Seq, Attention注意力机_复杂度_19

初步了解RNN, Seq2Seq, Attention注意力机_复杂度_20

初步了解RNN, Seq2Seq, Attention注意力机_复杂度_21

初步了解RNN, Seq2Seq, Attention注意力机_机器翻译_22

4.Seq2Seq训练问题

初步了解RNN, Seq2Seq, Attention注意力机_机器翻译_23

初步了解RNN, Seq2Seq, Attention注意力机_复杂度_24

5.Attention注意力机制

初步了解RNN, Seq2Seq, Attention注意力机_机器翻译_25

在Seq2Seq结构中,encoder把所有的输入序列都编码成一个统一的语义向量Context,然后再由Decoder解码。由于context包含原始序列中的所有信息,它的长度就成了限制模型性能的瓶颈。如机器翻译问题,当要翻译的句子较长时,一个Context可能存不下那么多信息,就会造成精度的下降。除此之外,如果按照上述方式实现,只用到了编码器的最后一个隐藏层状态,信息利用率低下。所以如果要改进Seq2Seq结构,最好的切入角度就是:利用Encoder所有隐藏层状态 h(t)解决Context长度限制问题。

初步了解RNN, Seq2Seq, Attention注意力机_复杂度_26

上下文context表示成如下的方式(h的加权平均):

初步了解RNN, Seq2Seq, Attention注意力机_机器翻译_27

那么权重alpha(attention weight)可表示成Q和K的乘积,小h即V(下图中很清楚的看出,Q是大H,K和V是小h):

初步了解RNN, Seq2Seq, Attention注意力机_全连接_28

初步了解RNN, Seq2Seq, Attention注意力机_全连接_29

6.乘法VS加法attention

加法注意力:

还是以传统的RNN的seq2seq问题为例子,加性注意力是最经典的注意力机制,它使用了有一个隐藏层的前馈网络(全连接)来计算注意力分配:

初步了解RNN, Seq2Seq, Attention注意力机_复杂度_30

乘法注意力:就是常见的用乘法来计算attention score:

初步了解RNN, Seq2Seq, Attention注意力机_机器翻译_31

乘法注意力不用使用一个全连接层,所以空间复杂度占优;另外由于乘法可以使用优化的矩阵乘法运算,所以计算上也一般占优。 论文中的乘法注意力除了一个scale factor:

初步了解RNN, Seq2Seq, Attention注意力机_机器翻译_32

论文中指出当dk比较小的时候,乘法注意力和加法注意力效果差不多;但当d_k比较大的时候,如果不使用scale factor,则加法注意力要好一些,因为乘法结果会比较大,容易进入softmax函数的“饱和区”,梯度较小。

7.Luong Attention(简单了解)

初步了解RNN, Seq2Seq, Attention注意力机_机器翻译_33

初步了解RNN, Seq2Seq, Attention注意力机_复杂度_34

初步了解RNN, Seq2Seq, Attention注意力机_全连接_35

注:这里就是把Decoder中的每一次的输入:上一层的输出y换成了Attention。

8.Self-Attention

初步了解RNN, Seq2Seq, Attention注意力机_全连接_36

9.《Attention is all you need》

9.1 encoder

初步了解RNN, Seq2Seq, Attention注意力机_全连接_37

注: 词向量加上了positional embedding,即给位置1,2,3,4...n等编码(也用一个embedding表示)。然后在编码的时候可以使用正弦和余弦函数,使得位置编码具有周期性,并且有很好的表示相对位置的关系的特性(对于任意的偏移量k,PE[pos+k]可以由PE[pos]表示):

初步了解RNN, Seq2Seq, Attention注意力机_机器翻译_38

输入的序列长度是n,embedding维度是d,所以输入是n*d的矩阵,N=6,6个重复一样的结构,由两个子层组成:子层1:

  • Multi-head self-attention
  • 残余连接和LN: Output = LN (x+sublayer(x))

子层2:

  • Position-wise fc层(跟卷积很像):对n*d的矩阵的每一行进行操作(相当于把矩阵每一行铺平,接一个FC),同一层的不同行FC层用一样的参数,不同层用不同的参数(对于全连接的节点数目,先从512变大为2048,再缩小为512),这里的max表示使用relu激活函数
  • 残差连接(待)

输出:

  • 整个encoder的输出也是n*d的矩阵

9.2 Decoder

初步了解RNN, Seq2Seq, Attention注意力机_机器翻译_39

输入:假设已经翻译出k个词,向量维度还是d,同样使用N=6个重复的层,依然使用残余连接和LN3个子层,比encoder多一个attention层,是Decoder端去attend encoder端的信息的层(待)Sub-L1:

  • self-attention,同encoder,但要Mask掉未来的信息,得到k*d的矩阵 (这个暂且不懂代码实现)

Sub-L2:

  • 和encoder做attention的层,输出k*d的矩阵,这里就不是self-Attention了。

Sub-L3:

  • 全连接层,输出k*d的矩阵,用第k行去预测输出y

10.mutli-head attention

初步了解RNN, Seq2Seq, Attention注意力机_复杂度_40

初步了解RNN, Seq2Seq, Attention注意力机_全连接_41

获取每个子任务的Q、K、V:

  • 通过全连接进行线性变换映射成多个Q、K、V,线性映射得到的结果维度可以不变、也可以减少(类似降维)
  • 或者通过Split对Q、K、V进行划分(分段)

初步了解RNN, Seq2Seq, Attention注意力机_复杂度_42

如果采用线性映射的方式,使得维度降低;或者通过split的方式使得维度降低,那么多个head做attention合并起来的复杂度和原来一个head做attention的复杂度不会差多少,而且多个head之间做attention可以并行。