Transformer原理理解

参考博客

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

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

http://nlp.seas.harvard.edu/2018/04/03/attention.html,与代码结合的论文阅读,不过是全英文的

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 Encoder结构图

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 函数的线性变换来提供给模型位置信息:

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(见下图)

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

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

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

 

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

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

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

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

动图传递如下:

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

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

计算顺序和结果如下图:

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

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

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

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

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

Padding Mask

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

 

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

残差连接

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

 残差连接一是解决梯度消失的问题,二是解决权重矩阵的退化问题。

Layer Normalization

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

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

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

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

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

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

 补:Batch Normalization的作用简单说明,由论文On calibration of modern neural networks中可得:

Batch Normalization improves the optimization of neural networks by minimizing distribution shifts in activation within the neural network's hidden layers.

Batch Normalization improves training time, reduces the need for additional regularization, and can in some cases improve the accuracy of networks.

详细的阐释在知乎或者博客很多。

例如:知乎上的

整个Encoder结构的解释

 

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

用公式来进行说明如下:

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

第二步:自注意力机制

第三步:残差连接和Layer Normalization

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

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

 其中,

 

Transformer Decoder结构

整体上看,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.

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

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

Masked Encoder-Decoder Attention

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

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

 

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和条件计算、对超长序列建模能力较差。

其余问题

https://blog.csdn.net/weixin_43837878/article/details/118153000?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_title~default-0.no_search_link&spm=1001.2101.3001.4242.0

posted @ 2021-07-28 22:29  永远是个小孩子  阅读(3887)  评论(0编辑  收藏  举报