您现在的位置是:首页 >技术教程 >Transformer模型原理—论文精读网站首页技术教程

Transformer模型原理—论文精读

浩然然然 2024-07-24 18:01:02
简介Transformer模型原理—论文精读

前言

今天来看一下Transformer模型,由Google团队提出,论文名为《Attention Is All You Need》。论文地址
正如标题所说的,注意力是你所需要的一切,该模型摒弃了传统的RNN和CNN结构,网络结构几乎由Attention机制构成,该论文的亮点在于提出了Multi-head attention机制,其又包含了self-attention,接下来我们将慢慢介绍该模型的原理。

模型架构

正如文中提到大多数的序列传导模型都含有encoder-decoder结构,Transformer的encoder是将一段表征序列 ( x 1 , ⋯   , x n ) (x_1,cdots,x_n) (x1,,xn)映射为另一种连续表示的序列 ( z 1 , ⋯   , z n ) (z_1,cdots,z_n) (z1,,zn),即encoder的输出信息;而decoder是将encoder输出和decoder前一步的输出自回归的共同生成序列 ( y 1 , ⋯   , y m ) (y_1,cdots,y_m) (y1,,ym)。举个例子,现在有一个机器翻译任务,首先将句子embedding为高维向量,输入encoder中,其输出随后输入decoder进行解码得到最终翻译结果,如下图所示。
Encoder-Decoder

需要注意的是,Transformer的输出 y i y_i yi是一次一次自回归的生成的,也就是每一次输出都需要调用最后一层encoder的输出序列。这里不像多层RNN隐层的并行传递,Transformer是串行的。如下图所示。
多层Transformer

Encoder和Decoder

好了,接下来该介绍encoder和decoder的神秘面纱了,如下图所示。
Transformer模型架构
在读论文时第一眼看这个架构图,一开始是比较懵的,这到底做了些啥操作。后来看了李沐老师讲解的Transformer才有了一定的理解。

Encoder

回到论文的讲解!
Enc

这里说到作者实验用到了6层的encoder,这里是为了学到更多的语义信息。并且每层encoder都包含两个子层,分别是多头注意力机制Multi-head attention前馈神经网络FFN。当然了,作者对两个子层的输出都做了residual连接Layer normalization(LN),加了残差连接是为了网络能搭的更深,并且容易训练,防止梯度消失;而LN完全是针对每一个样本自身的特征缩放,能将每个词都归一为相同空间的语义信息。BN也是一种常见的特征缩放方法,常用于CNN,不适用于NLP任务,因为其对所有batch的同一个特征做缩放,在图像中是非常友好的,而NLP中每一个sequence的长度是不一样的,所以在同一个batch中越长的语句得不到充分的缩放表示。

Decoder

Dec

同样的,作者实验用到了6层decoder,不同于encoder,这里作者还设置了mask的multi-head attention,其原因在于在解码时,模型是看不到整条句子的,因此,必须在当前时刻掩码掉后面的词,才能做到正确训练和有效预测。

Attention

谈到注意力机制,像我们人一样,看到一幅图片,我们会关注其强烈的表征现象,能让我们快速了解新事物的信息,如下图所示。特别在处理NLP任务中,长距离的记忆能力是一个难题,引入注意力机制,关注更重要的词,可以缓解这一现象。
在这里插入图片描述

在Transformer中,每个单词embedding为三个不同的向量,分别是 Q u e r y Query Query向量 Q Q Q K e y Key Key向量 K K K V a l u e Value Value向量 V V V。具体来说,对于一个句子,只需要将其输入到三个linear层,通过学习三个 W W W参数就能得到不一样的 Q 、 K 、 V Q、K、V QKV。至于为什么说 Q 、 K 、 V Q、K、V QKV要不一样,其实一样也可以,但是这里为了增强数据的表达能力,保证在 Q K T QK^T QKT矩阵内积时可以得到不同的空间投影提高模型泛化能力

生成的 Q 、 K 、 V Q、K、V QKV矩阵后便可以进行attention计算了,如下图所示
在这里插入图片描述

假设有三个矩阵 Q 、 K 、 V Q、K、V QKV,维度分别为 ( d q , d m o d e l ) 、 ( d k , d m o d e l ) 、 ( d v , d m o d e l ) (d_q, d_{model})、(d_k, d_{model})、(d_v, d_{model}) (dq,dmodel)(dk,dmodel)(dv,dmodel),其中 q = k = v q=k=v q=k=v

  1. 首先进入的是Multi-Head Attention多头注意力机制。这里可以h层,也就是我们说的多头,类似cv中的channel数量,能学习更多维度信息。多头注意力机制中包含了Scaled Dot-product Attention,也是self-attention
  2. 其次进入self-attention,对于每个sequence,用它的query矩阵: ( d q , d m o d e l ) (d_q, d_{model}) (dq,dmodel)和key向量shape: ( d k , d m o d e l ) (d_k, d_{model}) (dk,dmodel)进行内积,本质上是求解每个词之间的余弦相似度,如果两者相似度较高,则赋予较大的值来反应两者的关系,反之如果是正交的,内积为0,则它们就没有相似性,这里输出的attention score矩阵维度是shape: ( d q , d k ) (d_q, d_k) (dq,dk)
  3. 再次将输出矩阵进行scale缩放相似度,为了防止softmax推向梯度平缓区,使得收敛困难,公式如 Attention ( Q 、 K 、 V ) ext{Attention}(Q、K、V) Attention(QKV)所示。
  4. 从次是通过可选的mask操作,为了保证decoder得到sequence的leak信息。具体来说是通过将权重矩阵添加一个上三角的负无穷矩阵,这样softmax就能将这些值推为0,即无权重,保证mask的作用。
  5. 最后将attention score矩阵shape: ( d q , d k ) (d_q, d_{k}) (dq,dk)与Value矩阵shape: ( d v , d m o d e l ) (d_v, d_{model}) (dv,dmodel)内积,得到encoder后的sequence信息表征shape: ( d q , d m o d e l ) (d_q, d_{model}) (dq,dmodel)

Scale缩放公式:
Attention ( Q 、 K 、 V ) = softmax ( Q K T ( d k ) ) V egin{aligned} ext{Attention}(Q、K、V)= ext{softmax}(frac{QK^T}{sqrt(d_k)})V end{aligned} Attention(QKV)=softmax(( dk)QKT)V

Multi-head公式:
Multihead ( Q 、 K 、 V ) = Concat ( head i , ⋯   , head h ) W O where  head i = Attention ( Q W i Q , Q W i K , Q W i V ) egin{aligned} ext{Multihead}(Q、K、V)= ext{Concat}( ext{head}_i,cdots, ext{head}_h)W^O\ ext{where} ext{ } ext{head}_i= ext{Attention}(QW_{i}^{Q},QW_{i}^{K},QW_{i}^{V}) end{aligned} Multihead(QKV)=Concat(headi,,headh)WOwhere headi=Attention(QWiQ,QWiK,QWiV)

上述的操作执行完后,便可以通过多个头的concat将矩阵拼接,随后通过linear层降维,完成Multi-head attention的过程。

在这里插入图片描述
值得注意的是多头数量必须可被 d m o d e l d_{model} dmodel整除。这个很好理解,在CNN中,我们经常将feature map的width和height升维后,会把channel数降低,学到更深的信息一个道理。

FFN

除了注意子层外,encoder和decoder中的每个层都包含一个完全连接的前馈网络,它分别和相同地应用于每个位置。这由两个线性变换组成,中间有一个ReLU激活。换句话说就是MLP模型。公式如下所示:

FFN ( x ) = max ( 0 , x W 1 + b 1 ) W 2 + b 2 egin{aligned} ext{FFN}(x) = ext{max}(0, xW_1 + b_1)W_2 + b_2 end{aligned} FFN(x)=max(0,xW1+b1)W2+b2

在这里插入图片描述
论文作者给定了MLP的中间状态输出维度为2048,而最后输出维度为512,当然就是512->2048->512这样变换。

Embeddings和Positional Encoding

Emdedding+Positional Encoding

Embeddings

在Transformer中,在嵌入层中,这些权重乘以 d m o d e l sqrt{d_{model}} dmodel 。其原因是在嵌入层学emdedding的时候,在L2norm后,不管维度多大最终权重都会比较小,但后续要和positional encoding相加(不会经过norm),需要保持差不多的scale。

Positional Encoding

self-attention对输入sequence中各单词的位置或者说顺序不敏感,因为通过Query向量和Key向量的内积,本质上就是一些词由其他词的线性表出,并没有说有位置的信息存在。比如“我吃牛肉”这句话,在Transformer看来和“牛吃我肉”是没什么区别的。
为了缓解该问题,作者提出了位置编码。简而言之,就是在词向量输入到注意力模块之前,与该词向量等长的位置向量进行了按位相加,进而赋予了词向量相应的位置信息。

作者给出了位置编码的定义公式,具体如下:

P E p o s , 2 i = s i n ( p o s / 1000 0 2 i / d m o d e l ) P E p o s , 2 i + 1 = c o s ( p o s / 1000 0 2 i / d m o d e l ) PE_{pos, 2i}=sin(pos/10000^{2i/d_{model}}) \ PE_{pos, 2i+1}=cos(pos/10000^{2i/d_{model}}) PEpos,2i=sin(pos/100002i/dmodel)PEpos,2i+1=cos(pos/100002i/dmodel)

这样通过 s i n ( α + β ) = s i n ( α ) c o s ( β ) + c o s ( α ) s i n ( β ) sin(alpha+eta)=sin(alpha)cos(eta)+cos(alpha)sin(eta) sin(α+β)=sin(α)cos(β)+cos(α)sin(β)。可以将牛(pos=3)可以由pos=2和pos=4表达,使得Transformer可以更容易掌握单词间的相对位置。

总结

关于Transformer比较重要的点基本上就这些,当然还有很多细节的地方需要去探索,接下来我将会写更多的论文分享,总结一些经典的模型。

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。