Transformer原理理解

参考博客

https://wmathor.com/index.php/archives/1438/,大佬讲的非常清晰!!!博客排版也非常值得学习。

https://zhuanlan.zhihu.com/p/85612521,Transformer三部曲,也解释了attention机制

Transformer

Transformer 是谷歌大脑在 2017 年底发表的论文 attention is all you need 中所提出的 seq2seq 模型。现在已经取得了大范围的应用和扩展,而 BERT 就是从 Transformer 中衍生出来的预训练语言模型。

Transformer 和 LSTM 的最大区别,就是 LSTM 的训练是迭代的、串行的,必须要等当前字处理完,才可以处理下一个字。而 Transformer 的训练时并行的,即所有是同时训练的,这样就大大增加了计算效率。

Transformer 使用了位置嵌入 (Positional Encoding) 来理解语言的顺序,使用自注意力机制(Self Attention Mechanism)全连接层进行计算。

Transformer 模型主要分为两大部分,分别是 Encoder 和 Decoder

  • Encoder编码器负责把输入(语言序列)隐射成隐藏层(下图中第 2 步用九宫格代表的部分),即把自然语言序列映射为隐藏层的数学表达的过程
  • Decoder解码器再把隐藏层映射为自然语言序列。

例如下图机器翻译的例子(Decoder 输出的时候,是通过 N 层 Decoder Layer 才输出一个 token,并不是通过一层 Decoder Layer 就输出一个 token)

Transformer原理理解

Transformer Encoder结构图

Transformer原理理解

Encoder的关键部分就是上图的四个框框。下面将分别说明原理和重点。

第一部分:positional encoding(位置编码)

由于 Transformer 模型没有循环神经网络的迭代操作,所以我们必须提供每个字的位置信息给 Transformer,这样它才能识别出语言中的顺序关系。

现在定义一个位置嵌入的概念,也就是 Positional Encoding,位置嵌入的维度为 [max_sequence_length, embedding_dimension], 位置嵌入的维度与词向量的维度是相同的,都是 embedding_dimensionmax_sequence_length 属于超参数,指的是限定每个句子最长由多少个词构成。

注意,我们一般以为单位训练 Transformer 模型。首先初始化字编码(embedding)的大小为 [vocab_size, embedding_dimension]vocab_size 为字库中所有字的数量,embedding_dimension 为字向量的维度,对应到 PyTorch 中,其实就是 nn.Embedding(vocab_size, embedding_dimension)

论文中使用了 sin 和 cos 函数的线性变换来提供给模型位置信息:

Transformer原理理解

PE是positional encoding的缩写,上式中 pos 指的是一句话中某个字的位置,取值范围是 [0,max_sequence_length),i 指的是字向量的维度序号,取值范围是 [0,embedding_dimension/2),dmodel 指的是 embedding_dimension?的值,也就是词向量的维度。

上面有 sin 和 cos 一组公式,也就是对应着 embedding_dimension 维度的一组奇数和偶数的序号的维度,偶数对应上面,奇数对应下面。分别用上面的 sin 和 cos 函数做处理,从而产生不同的周期性变化。而位置嵌入在 embedding_dimension?维度上随着维度序号增大,周期变化会越来越慢,最终产生一种包含位置信息的纹理,就像论文原文中第六页讲的,位置嵌入函数的周期从 2π 到 10000?2π 变化,而每一个位置在 embedding_dimension?维度上都会得到不同周期的 sin 和 cos 函数的取值组合,从而产生独一的纹理位置信息,最终使得模型学到位置之间的依赖关系和自然语言的时序特性

可以参考这篇文章 Transformer 中的 Positional Encoding

下面画一下位置嵌入,纵向观察,可见随着 embedding_dimension?序号增大,位置嵌入函数的周期变化越来越平缓

画法的python代码见https://wmathor.com/index.php/archives/1438/

 

第二部分:self-attention mechanism(自注意力机制)

对于输入的句子 X,通过 WordEmbedding 得到该句子中每个字的字向量,同时通过 Positional Encoding 得到所有字的位置向量,将其相加(维度相同,可以直接相加),得到该字真正的向量表示。第 t 个字的向量记作 xt

此时的词向量包括了word embedding和位置向量。

接着我们定义三个矩阵 WQ,WK.WV,使用这三个矩阵分别对所有的字向量进行三次线性变换,于是所有的字向量又衍生出三个新的向量 qt,kt,vt。我们将所有的 q向量拼成一个大矩阵,记作查询矩阵 Q,将所有的 kt 向量拼成一个大矩阵,记作键矩阵 K,将所有的 vt 向量拼成一个大矩阵,记作值矩阵 V(见下图)

Transformer原理理解

把上图的结构拼接在一起拼成Q、K、V矩阵。K矩阵的拼法是一列一列的拼(为了方便查询)。

为了获得第一个字的注意力权重,我们需要用第一个字的查询向量 q1 乘以键矩阵 K(见下图)

Transformer原理理解

得到的结果要经过softmax,使得它们的和为1

 Transformer原理理解

 得到的是对应每个key的分值(score),作为权重,如下图:

Transformer原理理解

得到权重后,将权重分别乘以对应的值向量,如下图:

Transformer原理理解

 在整个self-attention中计算传播如下:

Transformer原理理解

最后将这些权重化的值向量v求和,就得到了第一个字的输出。

Transformer原理理解

动图传递如下:

Transformer原理理解

对于单个向量,整个self-attention的计算步骤如下:

  • 先用W和所有子向量得到Q、K、V
  • 对于一个字向量,先得到q向量
  • 用q向量与K矩阵相乘(相当于与每个k向量相乘求和),将结果用softmax转换为权重
  • v向量加权求和就是最终的结果。

计算顺序和结果如下图:

Transformer原理理解

用矩阵表示整个self-attention计算过程

第一步:计算所有时刻的Q、K、V,输入是矩阵X,X的第t行表示第t个词的向量xt

Transformer原理理解

然后将Q和KT相乘,然后除以一个缩放因子,dk是向量Q、V、K的维度,当维度较大时,Q和KT相乘值可能会很大,softmax之后会有较多的值接近0。经过softmax转换为权重后乘以V,得到最后的输出。

Transformer原理理解

Multi-Head attention(多头注意力机制)

Transformer原理理解

每一组Q、K、V可以得到一个输出矩阵Z,多头就能得到多个输出矩阵Z。

Padding Mask

Transformer原理理解

上面 Self Attention 的计算过程中,我们通常使用 mini-batch 来计算,也就是一次计算多句话,即 X 的维度是 [batch_size, sequence_length],sequence_length?是句长,而一个 mini-batch 是由多个不等长的句子组成的,我们需要按照这个 mini-batch 中最大的句长对剩余的句子进行补齐,一般用 0 进行填充,这个过程叫做 padding。

Transformer原理理解 

第三部分:残差连接和Layer Normalization

残差连接

把经过self-attention后的输出和原来的输入加起来,把原来的输入残差连接过来。

Transformer原理理解

 

Layer Normalization

Layer Normalization 的作用是把神经网络中隐藏层归一为标准正态分布,也就是 i.i.d 独立同分布,以起到加快训练速度,加速收敛的作用。

首先计算均值,以矩阵的列为单位:

Transformer原理理解

然后计算方差,也是以矩阵的列为单位:

Transformer原理理解

然后进行归一化,根据中心极限定理,

Transformer原理理解

加一个ε是为了防止分母为0.

Layer Normalization与Batch Normalization的对比:Batch是在Batch之间,Layer是在单个数据内。

Transformer原理理解

 

整个Encoder结构的解释

Transformer原理理解

 

上图展示了更多细节:输入 x1,x2 经 self-attention 层之后变成 z1,z2,然后和输入 x1,x2 进行残差连接,经过 LayerNorm 后输出给全连接层。全连接层也有一个残差连接和一个 LayerNorm,最后再输出给下一个 Encoder(每个 Encoder Block 中的 FeedForward 层权重都是共享的)

用公式来进行说明如下:

第一步:子向量和位置编码

Transformer原理理解

第二步:自注意力机制

Transformer原理理解

第三步:残差连接和Layer Normalization

Transformer原理理解

第四步:FeedForward部分,其实就是两层线性映射并用激活函数激活。比如说ReLU。

Transformer原理理解

 第五步:FeedForward的残差连接和Layer Normalization

Transformer原理理解

 其中,

Transformer原理理解

 

Transformer Decoder结构

Transformer原理理解

整体上看,Decoder的结构从下到上依次是:

  • Masked Multi-Head Self-Attention
  • Multi-Head Encoder-Decoder Attention
  • FeedForward Network

和 Encoder 一样,上面三个部分的每一个部分,都有一个残差连接,后接一个 Layer Normalization。Decoder 的中间部件并不复杂,大部分在前面 Encoder 里我们已经介绍过了,但是 Decoder 由于其特殊的功能,因此在训练时会涉及到一些细节

Masked Multi-Head Self-Attention

具体来说,传统 Seq2Seq 中 Decoder 使用的是 RNN 模型,因此在训练过程中输入 t 时刻的词,模型无论如何也看不到未来时刻的词,因为循环神经网络是时间驱动的,只有当 t 时刻运算结束了,才能看到 t+1 时刻的词。而 Transformer Decoder 抛弃了 RNN,改为 Self-Attention,由此就产生了一个问题,在训练过程中,整个 ground truth (正确的标注)都暴露在 Decoder 中,这显然是不对的,我们需要对 Decoder 的输入进行一些处理,该处理被称为 Mask.

Transformer原理理解

Transformer原理理解

之后再做 softmax,就能将 - inf 变为 0,得到的这个矩阵即为每个字之间的权重

Multi-Head:就是有许多组Q、K、V,多做几次。

Masked Encoder-Decoder Attention

其实这一部分的计算流程和前面 Masked Self-Attention 很相似,结构也一摸一样。

唯一不同的是这里的 K,V 为 Encoder 的输出,Q 为 Decoder 中 Masked Self-Attention 的输出

Transformer原理理解

 

Transformer的总结

Transformer原理理解

转载一下大佬的思考性问题:

为什么要引入attention机制?

Attention机制理论上可以建模任意长度的长距离依赖,并且符合人类直觉

Transformer 为什么需要进行 Multi-head Attention?

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

Transformer 相比于 RNN/LSTM,有什么优势?为什么?

  • RNN 系列的模型,无法并行计算,因为 T 时刻的计算依赖 T-1 时刻的隐层计算结果,而 T-1 时刻的计算依赖 T-2 时刻的隐层计算结果
  • Transformer的特征提取能力比RNN系列的模型要好

为什么说 Transformer 可以代替 seq2seq?

这里用代替这个词略显不妥当,seq2seq 虽已老,但始终还是有其用武之地,seq2seq 最大的问题在于将 Encoder 端的所有信息压缩到一个固定长度的向量中,并将其作为 Decoder 端首个隐藏状态的输入,来预测 Decoder 端第一个单词 (token) 的隐藏状态。在输入序列比较长的时候,这样做显然会损失 Encoder 端的很多信息,而且这样一股脑的把该固定向量送入 Decoder 端,Decoder 端不能够关注到其想要关注的信息。Transformer 不但对 seq2seq 模型这两点缺点有了实质性的改进 (多头交互式 attention 模块),而且还引入了 self-attention 模块,让源序列和目标序列首先 “自关联” 起来,这样的话,源序列和目标序列自身的 embedding 表示所蕴含的信息更加丰富,而且后续的 FFN 层也增强了模型的表达能力,并且 Transformer 并行计算的能力远远超过了 seq2seq 系列模型

Transformer有哪些优点和不足?

优点:完全基于attention,在可以并行的情况下仍然有很强的特征抽取能力。

缺点:仍然是自回归的形式、理论上非图灵完备、缺少Recurrent Inductive Bias和条件计算、对超长序列建模能力较差。

Transformer原理理解

上一篇:epoll学习代码


下一篇:【Docker】访问 jupyter notebook