以自注意力机制破局Transformer

各位好久不见,这段时间因工作项目加上家中大事,停更一段时间,细节略过不表。

本文针对Transformer进行重新梳理,针对其中要点附图详细讲解,按需取用!

1. Transformer架构解析

首先放出Transformer对应的架构图:

Transformer完整架构

Transformer源自这篇论文“Attention Is All You Need”。本质上而言这个模型其实还是Seq2Seq系列模型,如上图所示,左边使用encoder对输入信息进行编码,然后右边使用decoder得到解码的输出结果。即:

Seq2Seq(Transformer) = (Transformer)Encoder + (Transformer)Decoder

至于Transformer为何能取得比LSTM、RNN等模型更好的性能,很大一部分得益于自注意力机制的引入。接下来针对自注意力机制进行详细介绍。

2.自注意力机制详解

2.1 缘起

要介绍自注意力机制,首先还是得谈一谈自注意力机制在处理长距离序列的特性。

针对变长的向量序列,通常使用CNN或RNN系列模型来得到等长的隐藏状态/向量序列信息,然而这种操作方式本质上都属于局部编码,只能捕捉到短距离的依赖特征,对于长距离还是无能为力。为了解决这个问题,全连接模型和自注意力模型被提出。

全连接模型与自注意力模型最大的区别点在于其不能处理变长序列(虽然二者都可以捕捉长距离依赖特征)。而自注意力模型是利用注意力机制来动态的生成不同连接的权重,从而可以处理变长序列。

2.2 计算流程

Self-Attention(自注意力机制)的计算流程如下图所示:

自注意力机制计算流程

self-attention的核心就是计算自己对自己的权重,体现在:Q=K=V。这样做的目的,往往是为了充分考虑句子之间不同词语之间的语义以及语法联系,所以,这样重新计算得到的词向量,它就更进一步地考虑了上下文之间的联系了。

总共包括四个步骤:

1)线性变换

设输入为X=[X1,X2,...,Xn],图中的X1、X2分别为中、国。通过线性变换生成查询向量序列(Q/Queries)、键向量序列(K/Keys)、值向量序列(V/Values),即:

2)相似度计算

对于句中的每个字,将当前字的Q与句中所有字的K相乘,即:

普通的注意力在这一步都是直接将X1与X2相乘,在这里不这样做感觉考虑到如下原因:生成的q向量更多是为了保持单词本身的意思,忽略了上下文情况;生成的k向量则是为了在计算相似度的时候放大词和词之间的异同特性。举例来说,在计算相似度的时候,一个单词和自己的相似度应该最大,但在计算不同向量x的乘积也可能出现更大的相似度,这种情况是不合理的;因此通过新向量q、k相乘来计算相似度,通过模型的训练学习就可以避免这种情况。相比原来一个个词向量相乘的形式,通过构建新向量q、k,在计算相似度的时候灵活性更大,效果会更好。

3)权重转化

将当前字的QK计算完相似度之后,需要进行缩放点积操作,即:

执行缩放操作(即:除以维度dk的开方 )是为了把注意力矩阵变成标准正态分布,有助于加速模型收敛,减少dk规模造成的影响。

4)加权求和

同样,为了让模型更灵活,使用点积缩放作为注意力的打分机制得到权重后,并没有与原来的向量X或者Q相乘,而是新构建了一个向量V,然后将其与转化后的权重进行加权求和得到最终的新向量Z,即:

至此,'中’这个字对应的向量x1就变成了新向量z1。

综上所述的4个步骤,即可对应到论文中所提出的自注意力机制的公式:

2.3 注意力机制的分类体系

有了自注意力机制,相信有读者会对注意力机制的发展过程or分类体系有些好奇,在这里额外拓展一些注意力机制的相关知识。

所谓注意力机制其实就是在计算向量的过程中引入权重,让其可以包含多个方面/角度的语义。目下比较流行的分类体系如下:

注意力计算框架

传统计算框架大多是由谷歌提出的,除了上图展示的三种类别外,还包括一种hard attention,但这种一般很少使用,故略过不表。

这类传统计算框架中的注意力机制都包括三步操作:一是信息输入表示;二是注意力分布α计算;三是根据注意力分布α来对输入信息进行加权平均得到新的输入表示。

另外一个框架multi-head attention也是由谷歌提出,并集成到了Transformer中,主要改进的地方在于对Q、K、V进行了多次不同的线性变换,在通过缩放点击注意力机制把结果拼接到一起,大大提升了模型的拟合能力。具体细节会放在后面进行表述。

当然,如果想深入了解传统计算框架里面的三个类别注意力计算方式,可以自行查阅相关资料,博客很多。

3. Transformer详解

从第1节得知Transformer包括6个encoder-decoder结构,接下来以其中一个encoder-decoder结构进行表述。具体结构细节如下图所示:

Transformer的encoder-dedcoder架构

3.1 编码器

上图左边部分即为编码器Encoder,包括2个sub-layers,具体可分为四个子结构:位置嵌入(Positional encoding)、多头自注意力机制(Multi-head self-attention mechanism)、前馈网络(Position-wise Feed-forward Networks)、残差链接和层归一化。

(1)位置嵌入/Positional encoding

RNN系列网络之所以在NLP中应用那么多,是因为其天然适合处理序列特征,可以捕捉系列特征的位置顺序信息,这一点对于NLP是很重要的。对于一句话,若其中的字组合顺序发生改变,那么这句话的语义也可能会发生变化。【比如,读书好、读好书、好读书,三个组合的语义明显不一致。】

而Transformer没有类似RNN的那种循环结构,不能捕捉序列特征的位置信息,因此为了解决这个问题,论文中提出了位置嵌入的方式,即sin-cos规则,利用sin和cos函数的线性变换来捕捉位置信息:

其中,pos是字的位置,d_model是字嵌入的维度,i代表是维度的第几维数。

最后将Input Embedding产生的X_embedding与得到的对应位置嵌入相加,送给下一层:

其中,EmbeddingLookup代表字向量的查表操作。

(2)多头自注意力机制(Multi-head self-attention mechanism)

论文中提出的多头自注意力机制包括两个部分:Scaled Dot-Product Attention、Multi-Head Attention,如下图所示:

Multi-head self attention机制模型图

这种多头机制用于提取多重语义信息,类似于卷积网络的窗口操作,获取多个角度的上下文特征,有利于解决一词多义问题。注意嵌入维度embedding_dimension必须要整除于h(head数目),因为要把嵌入维度分割成h份。

Multi-head self attention机制计算流程

具体计算流程如上图所示:

  • 线性变换:针对输入的embedding进行线性变换生成Q、K、V;
  • 切分head:将生成的Q、K、V分头,每个head的维度=embedding_dimension / num of heads;
  • 自注意力计算:对划分后的每个Q、K、V组合计算自注意力得分,具体计算过程与2.2节一致;
  • 拼接:将通过自注意力计算的每个head拼接起来得到更新后的向量。

总结后即为以下公式:

进行完这4步后,还要继续dropout、残差连接以及层归一化三个操作。

(3)前馈网络(Position-wise Feed-forward Networks)

这一层主要是提供非线性变换,具体是两个FC层->dropout->残差连接->层归一化。

(4)残差连接和层归一化

在上面的介绍中可以发现每一个子层都使用了残差连接和层归一化两个操作,目的是为了防止梯度消失,加快模型收敛。

残差连接:

层归一化:

3.2 解码器

解码器Decoder的每层包括3个sub-layers。分别为:

(1)Masked multi-head self-attention mechanism

与Encoder不同,在对Q、K的相似度进行缩放点积后进行了mask操作,这是因为解码是序列生成过程,在时刻i,只有小于i的时候才有生成结果,大于i的时候没有结果。因此使用Mask对大于时刻i的部分进行操作。

(2)Position-wise Feed-forward Networks

与Encoder的部分一致。

(3)Encoder-Decoder attention

与Encoder相比,该层是Decoder独有的。它与self-attention mechanism都使用multi-head计算,但不同的是它使用的不是自注意力计算机制,而是传统的注意力计算机制。其中的Q/Query是在Decoder中自注意力机制计算出的上一时刻i的编码值,K/Key和V/Value都是Encoder的输出。

4.面试考点

在算法面试环节Transformer相关知识点是个很频繁的考点,可参考以下问题:

(1)self-attention mechanism是什么?计算流程叙述?

(2)Transformer的Encoder架构介绍?里面的多头自注意力机制介绍下?

(3)Transformer的Encoder与Decoder有哪些不同之处?

(4)Transformer的每一子层为什么都添加残差连接和层归一化操作?

(5)缩放点积具体起到什么作用,为什么要加它?

(6)Decoder中的多头自注意力机制为什么要Mask?

(7)多头自注意力机制中的多头具体发挥什么作用?

以上问题都可以在上文介绍中得到解答(当然是在你仔细阅读的前提下)。可能有些细节考点还没涉及到,待后面继续补充。

5. 总结

本文从自注意力机制的角度出发,首先探索并详细叙述自注意力机制的原理和注意力机制的演化,随后引入Transformer的要点叙述,最后本文针对面试给出梳理的频繁考点供读者参考。


(0)

相关推荐