Transformer各层网络结构详解!面试必备!(附代码实现)

1. 什么是Transformer

《Attention Is All You Need》是一篇Google提出的将Attention思想发挥到极致的论文。这篇论文中提出一个全新的模型,叫 Transformer,抛弃了以往深度学习任务里面使用到的 CNN 和 RNN。目前大热的Bert就是基于Transformer构建的,这个模型普遍应用于NLP领域,例如机器翻译,问答系统,文本摘要和语音识别等等方向。html

2. Transformer结构

2.1 整体结构

Transformer的结构和Attention模型同样,Transformer模型中也采用了 encoer-decoder 架构。但其结构相比于Attention更加复杂,论文中encoder层由6个encoder堆叠在一块儿,decoder层也同样。git

不了解Attention模型的,能够回顾以前的文章:Attentiongithub

每个encoder和decoder的内部结构以下图:面试

  • encoder,包含两层,一个self-attention层和一个前馈神经网络,self-attention能帮助当前节点不只仅只关注当前的词,从而能获取到上下文的语义。
  • decoder也包含encoder提到的两层网络,可是在这两层中间还有一层attention层,帮助当前节点获取到当前须要关注的重点内容。

2.2 Encoder层结构

首先,模型须要对输入的数据进行一个embedding操做,也能够理解为相似w2c的操做,enmbedding结束以后,输入到encoder层,self-attention处理完数据后把数据送给前馈神经网络,前馈神经网络的计算能够并行,获得的输出会输入到下一个encoder。网络

2.2.1 Positional Encoding

transformer模型中缺乏一种解释输入序列中单词顺序的方法,它跟序列模型还不不同。为了处理这个问题,transformer给encoder层和decoder层的输入添加了一个额外的向量Positional Encoding,维度和embedding的维度同样,这个向量采用了一种很独特的方法来让模型学习到这个值,这个向量能决定当前词的位置,或者说在一个句子中不一样的词之间的距离。这个位置向量的具体计算方法有不少种,论文中的计算方法以下:架构

PE(pos,2i)=sin(\frac{pos}{10000^{\frac{2i}{d_{model}}}})
PE(pos,2i+1)=cos(\frac{pos}{10000^{\frac{2i}{d_{model}}}})

其中pos是指当前词在句子中的位置,i是指向量中每一个值的index,能够看出,在偶数位置,使用正弦编码,在奇数位置,使用余弦编码机器学习

最后把这个Positional Encoding与embedding的值相加,做为输入送到下一层。函数

2.2.2 Self-Attention

接下来咱们详细看一下self-attention,其思想和attention相似,可是self-attention是Transformer用来将其余相关单词的“理解”转换成咱们正在处理的单词的一种思路,咱们看个例子:学习

The animal didn't cross the street because it was too tired编码

这里的 it 到底表明的是 animal 仍是 street 呢,对于咱们来讲能很简单的判断出来,可是对于机器来讲,是很难判断的,self-attention就可以让机器把 it 和 animal 联系起来,接下来咱们看下详细的处理过程。

  1. 首先,self-attention会计算出三个新的向量,在论文中,向量的维度是512维,咱们把这三个向量分别称为Query、Key、Value,这三个向量是用embedding向量与一个矩阵相乘获得的结果,这个矩阵是随机初始化的,维度为(64,512)注意第二个维度须要和embedding的维度同样,其值在BP的过程当中会一直进行更新,获得的这三个向量的维度是64。

  2. 计算self-attention的分数值,该分数值决定了当咱们在某个位置encode一个词时,对输入句子的其余部分的关注程度。这个分数值的计算方法是Query与Key作点成,如下图为例,首先咱们须要针对Thinking这个词,计算出其余词对于该词的一个分数值,首先是针对于本身自己即q1·k1,而后是针对于第二个词即q1·k2。

  3. 接下来,把点成的结果除以一个常数,这里咱们除以8,这个值通常是采用上文提到的矩阵的第一个维度的开方即64的开方8,固然也能够选择其余的值,而后把获得的结果作一个softmax的计算。获得的结果便是每一个词对于当前位置的词的相关性大小,固然,当前位置的词相关性确定会会很大。

  4. 下一步就是把Value和softmax获得的值进行相乘,并相加,获得的结果便是self-attetion在当前节点的值。

在实际的应用场景,为了提升计算速度,咱们采用的是矩阵的方式,直接计算出Query, Key, Value的矩阵,而后把embedding的值与三个矩阵直接相乘,把获得的新矩阵 Q 与 K 相乘,乘以一个常数,作softmax操做,最后乘上 V 矩阵。

这种经过 query 和 key 的类似性程度来肯定 value 的权重分布的方法被称为scaled dot-product attention。

2.2.3 Multi-Headed Attention

这篇论文更牛逼的地方是给self-attention加入了另一个机制,被称为“multi-headed” attention,该机制理解起来很简单,就是说不只仅只初始化一组Q、K、V的矩阵,而是初始化多组,tranformer是使用了8组,因此最后获得的结果是8个矩阵。

2.2.4 Layer normalization

在transformer中,每个子层(self-attetion,Feed Forward Neural Network)以后都会接一个残缺模块,而且有一个Layer normalization。

Normalization有不少种,可是它们都有一个共同的目的,那就是把输入转化成均值为0方差为1的数据。咱们在把数据送入激活函数以前进行normalization(归一化),由于咱们不但愿输入数据落在激活函数的饱和区。

Batch Normalization

BN的主要思想就是:在每一层的每一批数据上进行归一化。咱们可能会对输入数据进行归一化,可是通过该网络层的做用后,咱们的数据已经再也不是归一化的了。随着这种状况的发展,数据的误差愈来愈大,个人反向传播须要考虑到这些大的误差,这就迫使咱们只能使用较小的学习率来防止梯度消失或者梯度爆炸。BN的具体作法就是对每一小批数据,在批这个方向上作归一化。

Layer normalization

它也是归一化数据的一种方式,不过LN 是在每个样本上计算均值和方差,而不是BN那种在批方向计算均值和方差!公式以下:

LN(x_i)=\alpha*\frac{x_i-\mu_L}{\sqrt{\sigma_L^2+\varepsilon}}+\beta

2.2.5 Feed Forward Neural Network

这给咱们留下了一个小的挑战,前馈神经网络无法输入 8 个矩阵呀,这该怎么办呢?因此咱们须要一种方式,把 8 个矩阵降为 1 个,首先,咱们把 8 个矩阵连在一块儿,这样会获得一个大的矩阵,再随机初始化一个矩阵和这个组合好的矩阵相乘,最后获得一个最终的矩阵。

2.3 Decoder层结构

根据上面的整体结构图能够看出,decoder部分其实和encoder部分大同小异,刚开始也是先添加一个位置向量Positional Encoding,方法和 2.2.1 节同样,接下来接的是masked mutil-head attetion,这里的mask也是transformer一个很关键的技术,下面咱们会进行一一介绍。

其他的层结构与Encoder同样,请参考Encoder层结构。

2.3.1 masked mutil-head attetion

mask 表示掩码,它对某些值进行掩盖,使其在参数更新时不产生效果。Transformer 模型里面涉及两种 mask,分别是 padding mask 和 sequence mask。其中,padding mask 在全部的 scaled dot-product attention 里面都须要用到,而 sequence mask 只有在 decoder 的 self-attention 里面用到。

  1. padding mask

    什么是 padding mask 呢?由于每一个批次输入序列长度是不同的也就是说,咱们要对输入序列进行对齐。具体来讲,就是给在较短的序列后面填充 0。可是若是输入的序列太长,则是截取左边的内容,把多余的直接舍弃。由于这些填充的位置,实际上是没什么意义的,因此咱们的attention机制不该该把注意力放在这些位置上,因此咱们须要进行一些处理。

    具体的作法是,把这些位置的值加上一个很是大的负数(负无穷),这样的话,通过 softmax,这些位置的几率就会接近0!

    而咱们的 padding mask 其实是一个张量,每一个值都是一个Boolean,值为 false 的地方就是咱们要进行处理的地方。

  2. Sequence mask

    文章前面也提到,sequence mask 是为了使得 decoder 不能看见将来的信息。也就是对于一个序列,在 time_step 为 t 的时刻,咱们的解码输出应该只能依赖于 t 时刻以前的输出,而不能依赖 t 以后的输出。所以咱们须要想一个办法,把 t 以后的信息给隐藏起来。

    那么具体怎么作呢?也很简单:产生一个上三角矩阵,上三角的值全为0。把这个矩阵做用在每个序列上,就能够达到咱们的目的

  • 对于 decoder 的 self-attention,里面使用到的 scaled dot-product attention,同时须要padding mask 和 sequence mask 做为 attn_mask,具体实现就是两个mask相加做为attn_mask。
  • 其余状况,attn_mask 一概等于 padding mask。

2.3.2 Output层

当decoder层所有执行完毕后,怎么把获得的向量映射为咱们须要的词呢,很简单,只须要在结尾再添加一个全链接层和softmax层,假如咱们的词典是1w个词,那最终softmax会输入1w个词的几率,几率值最大的对应的词就是咱们最终的结果。

2.4 动态流程图

编码器经过处理输入序列开启工做。顶端编码器的输出以后会变转化为一个包含向量K(键向量)和V(值向量)的注意力向量集 ,这是并行化操做。这些向量将被每一个解码器用于自身的“编码-解码注意力层”,而这些层能够帮助解码器关注输入序列哪些位置合适:

在完成编码阶段后,则开始解码阶段。解码阶段的每一个步骤都会输出一个输出序列(在这个例子里,是英语翻译的句子)的元素。

接下来的步骤重复了这个过程,直到到达一个特殊的终止符号,它表示transformer的解码器已经完成了它的输出。每一个步骤的输出在下一个时间步被提供给底端解码器,而且就像编码器以前作的那样,这些解码器会输出它们的解码结果 。

3. Transformer为何须要进行Multi-head Attention

原论文中说到进行Multi-head Attention的缘由是将模型分为多个头,造成多个子空间,可让模型去关注不一样方面的信息,最后再将各个方面的信息综合起来。其实直观上也能够想到,若是本身设计这样的一个模型,必然也不会只作一次attention,屡次attention综合的结果至少可以起到加强模型的做用,也能够类比CNN中同时使用多个卷积核的做用,直观上讲,多头的注意力有助于网络捕捉到更丰富的特征/信息

4. Transformer相比于RNN/LSTM,有什么优点?为何?

  1. RNN系列的模型,并行计算能力不好。RNN并行计算的问题就出在这里,由于 T 时刻的计算依赖 T-1 时刻的隐层计算结果,而 T-1 时刻的计算依赖 T-2 时刻的隐层计算结果,如此下去就造成了所谓的序列依赖关系。

  2. Transformer的特征抽取能力比RNN系列的模型要好。

    具体实验对比能够参考:放弃幻想,全面拥抱Transformer:天然语言处理三大特征抽取器(CNN/RNN/TF)比较

    可是值得注意的是,并非说Transformer就可以彻底替代RNN系列的模型了,任何模型都有其适用范围,一样的,RNN系列模型在不少任务上仍是首选,熟悉各类模型的内部原理,知其然且知其因此然,才能遇到新任务时,快速分析这时候该用什么样的模型,该怎么作好。

5. 为何说Transformer能够代替seq2seq?

seq2seq缺点:这里用代替这个词略显不稳当,seq2seq虽已老,但始终仍是有其用武之地,seq2seq最大的问题在于将Encoder端的全部信息压缩到一个固定长度的向量中,并将其做为Decoder端首个隐藏状态的输入,来预测Decoder端第一个单词(token)的隐藏状态。在输入序列比较长的时候,这样作显然会损失Encoder端的不少信息,并且这样一股脑的把该固定向量送入Decoder端,Decoder端不可以关注到其想要关注的信息。

Transformer优势:transformer不但对seq2seq模型这两点缺点有了实质性的改进(多头交互式attention模块),并且还引入了self-attention模块,让源序列和目标序列首先“自关联”起来,这样的话,源序列和目标序列自身的embedding表示所蕴含的信息更加丰富,并且后续的FFN层也加强了模型的表达能力,而且Transformer并行计算的能力是远远超过seq2seq系列的模型,所以我认为这是transformer优于seq2seq模型的地方。

6. 代码实现

地址:github.com/Kyubyong/tr…

代码解读:Transformer解析与tensorflow代码解读

机器学习通俗易懂系列文章

7. 参考文献


做者:@mantchs

GitHub:github.com/NLP-LOVE/ML…

欢迎你们加入讨论!共同完善此项目!群号:【541954936】NLP面试学习群

相关文章
相关标签/搜索