详解Transformer模型(Atention is all you need)

1 概述git

  在介绍Transformer模型以前,先来回顾Encoder-Decoder中的Attention。其实质上就是Encoder中隐层输出的加权和,公式以下:github

    

  将Attention机制从Encoder-Decoder框架中抽出,进一步抽象化,其本质上以下图 (图片来源:张俊林博客):网络

    

  以机器翻译为例,咱们能够将图中的Key,Value看做是source中的数据,这里的Key和Value是对应的。将图中的Query看做是target中的数据。计算Attention的整个流程大体以下:架构

  1)计算Query和source中各个Key的类似性,获得每一个Key对应的Value的权重系数。在这里我认为Key的值是source的的隐层输出,Key是等于Value的,Query是target的word embedding(这种想法保留)。框架

  2)利用计算出来的权重系数对各个Value的值加权求和,就获得了咱们的Attention的结果。函数

  具体的公式以下:学习

    $ Attention(Query, source) = \sum_{i=1}^{L_x} Similarity(Query, Key_i) * Value_i $spa

  其中 $L_x$ 表明source中句子的长度。.net

  再详细化将Attention的计算分为三个阶段,以下图(图片来源:张俊林博客翻译

    

  1)计算类似性,在这里计算类似性的方法有多种:点积,Cosine类似性,MLP网络等。较经常使用的是点积和MLP网络。

  2)将计算出的类似性用softmax归一化处理。

  3)计算Value值的加权和。

  在这里的Attention本质上是一种对齐的方法,也能够将Attention看做是一种软寻址的方法,以权重值将target中的词和source中的词对齐。相对应软寻址(soft-Attention),还有一种hard-Attention,顾名思义就是直接用权值最大的Value值做为Attention。

 

2 Transformer模型

  Transformer模型来源于谷歌2017年的一篇文章(Attention is all you need)。在现有的Encoder-Decoder框架中,都是基于CNN或者RNN来实现的。而Transformer模型汇中抛弃了CNN和RNN,只使用了Attention来实现。所以Transformer是一个彻底基于注意力机制的Encoder-Decoder模型。在Transformer模型中引入了self-Attention这一律念,Transformer的整个架构就是叠层的self-Attention和全链接层。具体的结构以下:

    

  上面结构中的左半部分是Encoder,右半部分是Decoder。在详细介绍结构以前,先来看几个概念词:

  self-Attention

  在通常的Attention中,source和target中的内容是不同的,也就是Query是不属于Key的。而self-Attention是发生在单个句子内的,它的Query是属于Key的,能够认为下面公式中

    $ Attention(Query, source) = \sum_{i=1}^{L_x} Similarity(Query, Key_i) * Value_i $

  上面公式中Query = Key = Value。也就是说在序列内部作Attention,寻找序列内部的联系。

  那么为何要用self-Attention呢?它有什么优势:

  1) 能够并行化处理,在计算self-Attention是不依赖于其余结果的。

  2)计算复杂度低,self-Attention的计算复杂度是$n^2 d$,而RNN是$n d^2$,在这里$n$是指序列的长度,$d$是指词向量的维度,通常来讲$d$的值是大于$n$的。

  3)self-Attention能够很好的捕获全局信息,不管词的位置在哪,词之间的距离都是1,由于计算词之间的关系时是不依赖于其余词的。在大量的文献中代表,self-Attention的长距离信息捕捉能力和RNN至关,远远超过CNN(CNN主要是捕捉局部信息,固然能够经过增长深度来增大感觉野,但实验代表即便感觉野能涵盖整个句子,也没法较好的捕捉长距离的信息)。

  Scaled dot-product attention

  Scaled dot-product attention 的公式以下:

    

  在上面公式中Q和K中的向量维度都是 $d_k$ ,V的向量维度是 $d_v$ ,实际上在self-Attention中,$d_k = d_v = d_wordEmbedding / numHeads$,为了方便将Attention的计算转化为矩阵运算,论文在这里采用了点积的形式求类似度。常见的计算方法除了点积还有MLP网络,可是点积能转化为矩阵运算,计算速度更快。然而点积的方法面临一个问题,当 $d_k$ 太大时,点积计算获得的内积会太大,这样会致使softmax的结果非0即1,所以引入了$\sqrt{d_k}$ 来对内积进行缩放。

  Multi-Head Attention

  这是本文中首次提出的概念,这里的用法有点玄妙,但理解起来也很简单,其表达式以下:

    

  表达式的计算以下:

  1)假设如今头数为$h$,首先按照每一时序上的向量长度(若是是词向量的形式输入,能够理解为embedding size的值)等分红$h$份。

  2)而后将上面等分后的$h$份数据分别经过不一样的权重($W_i^Q, W_i^K, W_i^V$)映射获得新的Q, K, W的值。

  3)将上述映射后的$h$份数据计算相应的Attention的值。

  4)按照以前分割的形式从新拼接起来,再映射到原始的向量维度。就获得Multi-Head Attention的值。

  在这里每一次映射时的矩阵都不相同,所以映射以后再计算也就会获得不同的结果。其实认真来看Multi-Head Attention的机制有点相似与卷积中的多个卷积核,在卷积网络中,咱们认为不一样的卷积核会捕获不一样的局部信息,在这里也是同样,咱们认为Multi-Head Attention主要有两个做用

  1)增长了模型捕获不一样位置信息的能力,若是你直接用映射前的Q, K, V计算,只能获得一个固定的权重几率分布,而这个几率分布会重点关注一个位置或个几个位置的信息,可是基于Multi-Head Attention的话,能够和更多的位置上的词关联起来。

  2)由于在进行映射时不共享权值,所以映射后的子空间是不一样的,认为不一样的子空间涵盖的信息是不同的,这样最后拼接的向量涵盖的信息会更广。

  有实验证实,增长Mult-Head Attention的头数,是能够提升模型的长距离信息捕捉能力的。

  Feed Forward 层

  Feed Forward 层采用了全链接层加Relu函数实现,用公式能够表示为:

   $ FFN(x) = Relu(xW_1 + b_1) W_2 + b_2$ 

  其实关于在这里并不必定要用全链接层,也可使用卷积层来实现。

  Dropout 层

  咱们还能够在每一个subLayers后面加上一个10%的Dropout层,则subLayers的输出能够写成:

    $ LayerNorm(x + Dropout(Sublayer(x)))$

  介绍到这里能够来看下咱们总体的模型结构了。

  Encoder

  Encoder 是有N=6个layers层组成的,每一层包含了两个sub-layers。第一个sub-layer就是多头注意力层(multi-head attention layer),第二个就是一个简单的全链接层。在每一个sub-layer层之间都用了残差链接,根据resNet,咱们知道残差链接其实是:

  $H(x) = F(x) + x$

  所以每一个sub-layer的输出都是:

  $ LayerNorm(x + Sublayer(x)) $

  在这里LayerNorm中每一个样本都有不一样的均值和方差,不像BatchNormalization是整个batch共享均值和方差。

  注意:每一个Layer的输入和输出的维度是一致的。

  Decoder

  Decoder 一样是N=6个layers层组成的,可是这里的layer和Encoder不同,这里的layer包含了三个sub-layers。第一个sub-layer就是多头自注意力层,也是计算输入的self-Attention,可是由于这是一个生成过程,所以在时刻 $t$ ,大于 $t$ 的时刻都没有结果,只有小于 $t$ 的时刻有结果,所以须要作masking,masking的做用就是防止在训练的时候使用将来的输出的单词。第二个sub-layer是对encoder的输入进行attention计算的,从这里能够看出Decoder的每一层都会对Encoder的输出作Multi Attention(这里的Attention就是普通的Attention,非self-Attention)。第三个sub-layer是全链接层。

  从上面的分析来看Attention在模型中的应用有三个方面:

  1)Encoder-Decoder Attention

  在这里就和普通的Attention同样运用,query来自Decoder,key和value来自Encoder。

  2)Encoder Attention

  这里是self-Attention,在这里query,key,value都是来自于同一个地方

  3)Decoder Attention

  这里也是self-Attention,在这里的query,key,value也都是来自于同一个地方。可是在这里会引入masking。

  Embedding and Softmax

  和其余的序列传导模型同样,在这里的source,target的输入都会使用word embedding。也会用softmax来预测token

  Positional Embedding

  Positional Embedding 是一个很重要的东西,咱们回过头来看上面的self-Attention,咱们发现self-Attention能提取词与词之间的依赖关系,可是却不能提取词的绝对位置或者相对位置关系。若是将K,V的顺序打乱,得到的Attention的结果仍是同样的。在NLP任务中词之间的顺序是很重要的,所以文章运用了Positional Embedding来保留词的信息,将每一个位置编号,而后每一个编号对应这一贯量,最后将该向量和词向量相加,这样就给每一个词引入了必定的位置信息。

  在论文中使用不一样频率的正弦和余弦函数来生成位置向量,表达式以下:

  

  位置向量的维度和word embedding的一致。上面公式中 $pos$ 表示序列中词的位置,$i$ 表示位置向量中每一个值的维度,也就是说$ i < d_{model}$。经过上面公式计算出每个位置的位置向量。位置向量是能够被训练的值,并且用上面的公式计算的位置向量并非绝对的,你也能够用其余的方法求位置向量。

参考文献:

深度学习中的注意力机制(2017版)

《Attention is All You Need》浅读(简介+代码)

The Illustrated Transformer

Dissecting BERT Part 1: The Encoder

相关文章
相关标签/搜索