《Attention is All You Need》

https://www.jianshu.com/p/25fc600de9fb

谷歌最近的一篇BERT取得了卓越的效果,为了研究BERT的论文,我先找出了《Attention is All You Need》,看看里面的Transformer模型作为基础。

Transformer是为了机器翻译任务中的问题所提出的。

传统的RNN神经网络结构是可以处理任意长度的输入,它非常适合于自然语言的建模,所以它在一段时间内占据了整个神经网络中的主流。随着学术的发展,我们也会看到RNN有些不足。

RNN的缺点主要有两点:

  • RNN序列的特性导致其非常难以并行化
  • 在RNN训练中,RNN的网络结构对于长距离和层级化的依赖关系难以建立

关于第二点举个例子:“The dog didn’t cross street because it wastoo tired”,当我们看到“tired”的时候知道这个it指dog 。如果把最后一个词换了,“The dog didn’t cross street because it was too wide”,这时候如果是人看了这句话就很容易发现it 指的是street,因为street because it was wide,不可能是dog too wide。对于人来说很简单,但是机器要分清楚指代关系是非常难的。

所以人们开始探索新的网络结构,例如FaceBook提出的《Convolutional Sequence to Sequence Learning》。

Google在这一问题上的探索结果便是Transformer。Transformer这个网络命名,Transformer在英文翻译过来有变形金刚的意思。

 

1. 整体结构

从整体上来看,Transformer依旧是一个“Sequence to Sequence”框架,拥有Encoder和Decoder两部分:

 
Transformer的整体结构

Transformer的Encoder其实有6层,Decoder也有6层,从Encoder的角度,低层的Encoder是表层的词法信息,逐步向上进行抽象之后,在上层将表示抽象语义信息。Encoder部分还在最上层连了几条线到每个Decoder的部分,这是为了在Decoder中进行Attention操作,Decoder的网络中和Encoder也有信息传递和交互的。最后一个特点是Decoder和Encoder画的大小是一样的,因为它们层的维度大小是一样的。

 
 

多层的神经网络结构能够对句子层级化信息进行建模,如果我们更精细的去看每一层的结构,就会发现这样的情况:Encode分两个子网络部分,第一个是Self-Attention,第二个部分是Feed Forward。

Self-Attention是自注意力机制层,表征句子当中不同位置词之间的关系,是我们前面提到的it和street 或dog之间的依赖关系。

 
 

 

2. Self-Attention

首先在做DeepNLP任务时,我们都会使用word2vec等技术生成词向量:

 
 

注:这里对词向量的维数都做了简化,以方便后面说明

那么首先要明白什么是Attention。从语言学的角度,它是表示词与词之间的关联关系,像下图所示,这是一个Self-Attention的示意,它这个it会和其他位置的词发生关系,颜色越深的是说关系越紧密,从中图中看到它很正确的关联到了animal它实际指代的一个词。

 
 

从机器学习的角度,这个Attention是神经网络隐层之间一个相似度的表示,什么是Self-Attention?就是表示句子内部词与词之间的关联关系,就像这里的it到animal,可以用于指代消解等问题。

在Transformer中提出一种扩展性更高、并行度更高的Attention计算方式,它把Attention看作一个基于内容的查询的过程,content based query,它会设置3个vector:QueryVector、Key Vector、Value Vector。并且每一个Vector都是通过它的input embedding和权重的矩阵相乘得到的。利用这个Q、K、V进行各种数值的计算,最终得到Attentionscore。

 
 
 
计算公式
 
 

用一个例子来给大家演示具体的Attention是怎么计算的。如果我们计算“Thinking”这个词,用Self-Attention的话,首先会用它的Query Vector乘以K的向量,如果计算和第二个位置的attention是乘以T2的矩阵得到一个score,这个score再去和它维度的平根根进行相除,这个相除有数学上的含义,能够使它回传的梯度更加稳定,除完后得到一个数值进行softmax,所有Attention都是正数并且相加之和等于1,这是从数学正确上考虑,并且最终得到概率这个值是去定义每一个词在当前位置的表现力。Softmax之后,我们会用softmax得到的乘以它Value的矩阵,这样实际得到Attention的值,最后会把不同位置得到Attention的score加到一起,形成当前位置Attention的Vector,就是Z1,加上逐词计算的话就得到所有位置的Attention。

 
 

使用矩阵形式来表示:

 
 
 
 

 

3. Multi-head Attention

这个是Google提出的新概念,是Attention机制的完善。不过从形式上看,它其实就再简单不过了,就是把Q,K,V通过参数矩阵映射一下,然后再做Attention,把这个过程重复做h次,结果拼接起来就行了

 
 
 
 
 
 
 
 

 

4. Positional Encoding

这样的模型并不能捕捉序列的顺序!换句话说,如果将K,V按行打乱顺序(相当于句子中的词序打乱),那么Attention的结果还是一样的。这就表明了,到目前为止,Attention模型顶多是一个非常精妙的“词袋模型”而已。

Position Embedding,也就是“位置向量”,将每个位置编号,然后每个编号对应一个向量,通过结合位置向量和词向量,就给每个词都引入了一定的位置信息,这样Attention就可以分辨出不同位置的词了。

在以往的Position Embedding中,基本都是根据任务训练出来的向量。而Google直接给出了一个构造Position Embedding的公式:

 
 

这里的意思是将id为p的位置映射为一个dpos维的位置向量,这个向量的第i个元素的数值就是PEi(p)。

Position Embedding本身是一个绝对位置的信息,但在语言中,相对位置也很重要,Google选择前述的位置向量公式的一个重要原因是:由于我们有sin(α+β) = sinαcosβ+cosαsinβ 以及 cos(α+β)=cosαcosβ−sinαsinβ,这表明位置p+k的向量可以表示成位置p的向量的线性变换,这提供了表达相对位置信息的可能性。

 
 

这上面的编码结果好像有点问题,我运行了哈佛的代码后的结果如下,也可能我哪里没有理解清楚,希望有明白的大佬给我指点下。

 
 

需要注意的一点,结合位置向量和词向量其实有好几个可选方案,可以把它们拼接起来作为一个新向量,也可以把位置向量定义为跟词向量一样大小,然后两者加起来。Google论文中用的都是后者。

 

5. Position-wise Feed-Forward Networks

 
 
 
 

虽然线性变换在不同位置上是相同的,但它们在层与层之间使用不同的参数。 另一种描述这种情况的方法是两个内核大小为1的卷积。

 

6. Residual connection和layer-normalization

对于学习CV的人估计对这个结构一点也不陌生,Residual connection是对于较为深层的神经网络有比较好的作用,比如网络层很深时,数值的传播随着weight不断的减弱,Residual connection是从输入的部分,就是图中虚线的部分,实际连到它输出层的部分,把输入的信息原封不动copy到输出的部分,减少信息的损失。

 
 

layer-normalization这种归一化层是为了防止在某些层中由于某些位置过大或者过小导致数值过大或过小,对神经网络梯度回传时有训练的问题,保证训练的稳定性,这是神经网络设计比较常用的case。

基本在每个子网络后面都要加上layer-normalization、加上Residual connection,加上这两个部分能够使深层神经网络训练更加顺利。

 
 

到此为止,Encoder部分其实基本上就已经结束了,Decoder部分其实大多数结构都与Encoder部分相同,但是它的Attention部分还是有一些小小的不同。

 

7. Encoder-Decoder Attention

 
 

由上图可以看到,Decoder 部分除了Self-Attention的机制之外,还有Encoder-Decoder Attention。

其实,Encoder-Decoder Attention就是平常使用的Attention:

 
 

 

8. 小节

 
 

总体流程(上图是只画两层的Encoder和Decoder):

  1. 将底层的词的输入转化为embedding的输入,X1、X2
  2. 加上“Positional Encoding”的输入
  3. 输入到第一个Encoder当中,经过self-Attention层,直连的“Residual connection”和归一化层,得到的输出
  4. 将其输入到前馈神经网络中,前馈神经网络出来之后再经过直连层和归一化层,这样就完成了一个Encoder部分
  5. 再以这个输入到第二个Encoder之后,它会把第二个Encoder的输出(这里由于只有两层,所以第二个Encoder就是最后Encoder)作为第一个Decoder的输入,也是依次进行上面的过程
  6. 最后就是通过一个liner层之后由softmax层转化概率输出
 
 

注意:目标端的Attention注意力机制是一个masked注意力机制,为什么?比如在机器翻译当中,在源端能够看到所有的词,但如果你目标端生成翻译时是自左上右,生成翻译时能够看到前面已经生成词的信息,看不到后面层的,这是目标端Attention和源端Attention比较大的区别,所以在目标端所有的Attention都是加Masked的,这个Masked相当于把后面不该看到的信息屏蔽掉

 

参考:

  1. https://kexue.fm/archives/4765
  2. pytorch代码实现
  3. https://jalammar.github.io/illustrated-transformer/
  4. https://mp.weixin.qq.com/s/w3IKoygTLDsAxk1MB5JrGg


作者:freedom_king
链接:https://www.jianshu.com/p/25fc600de9fb
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
posted @ 2019-02-27 19:38  Django's blog  阅读(323)  评论(0编辑  收藏  举报