Attention Is All You Need—transformer详解
以下大部分是根据论文理解进行的总结和概括,如有疑问,欢迎交流~
transformer仅仅使用注意力机制,没有使用任何的卷积或者RNN结构。
传统RNN结构的当前隐层状态
由于翻译前后句子长短不一定是一致的,机器翻译任务一般采用编码-解码结构来解决。无论输入的句子有多长,都将句子编码成一个固定大小的向量,再对该向量进行解码以完成机器翻译任务。这样由于中间编码向量的大小是固定的,解码的效果显然会随着输入的句子的增长而下降,注意力机制就是为了缓解这种现象而被提出的。
输入输出
word embedding
不能直接将输入的话(一串字符)输入到transformer,因为它并不认识,所以需要将文字转换成计算机认识的数学表示。文字到字向量转换。用到的方法有Word2Vec。字嵌入得到的尺寸是
论文中包括两个输入,原始输入的数据,以及上一时刻及之前输出的结果序列。将这两个信息利用可以学习的嵌入方法转换成
positional embedding
输入是经过词嵌入后的向量。
由于网络中,不包含RNN和卷积网络,为了充分利用token的相对或者绝对的位置信息,所以需要将位置信息注入到嵌入向量中。
为了让字嵌入和位置嵌入进行相加,位置嵌入和字嵌入的维度相同。有很多位置嵌入的方法,可以学习的或者固定的提取方法。
文中采用了在不同频率使用sin和cos进行提取的方法。采用sin-cos的方法是为了让模型能够轻松学到通过相对位置来获取注意力信息。如果使用固定的位置编码,对于任何的偏移量,位置编码为
文中同时也测试了可以学习的位置嵌入方法,但是发现二者性能差不多。但采用sin-cos还有一个好处就是可以让模型去轻松处理比在训练过程中遇到的更长的序列。
pos是位置序号,取值范围是[0,mxalen]
,maxlen>=T。i是维度序号,取值范围是
总体结构
transformer全部由Attention机制组成。transformer的Encoder-Decoder结构如下所示,其编码器和解码器均有6层相同的结构组成。最后一层编码器的输出是每一层解码器的输入。实际预测时,会根据编码器的结果及上一次预测结果的编码,输出序列的下一个结果。
将上述的6层编解码结构拆解,只看其中的一个encoder-decoder,如下图所示
上图左侧是一个encoder,右侧是一个decoder。transformer就是有6个左侧结构和6个右侧结构组成。
Encoder
编码器有六个相同的层组成,每个层包括两个子层,第一个子层是多头注意力机制,第二个子层是一个简单的前馈神经网络。这两个子层都使用残差连接,并且在其后面都有一个layer归一化。每一个子层可用下式表述:
为了方便残差连接,所有的子层输出维度为512。
编码器包含很多个自注意力层,每个自注意力层的Q,K,V均来自于上一层的输出。编码器的每一个位置可以注意到之前编码器前一层的所有位置。这里我理解,由于权重计算是KQ,计算出的注意力可以作用到V的每一个位置,因此每一层都会注意到之前一层的所有位置的。
decoder
解码器也是由6个相同的层组成,除了和encoder两个一样的子层以外,解码器增加了一个多头注意力机制。和encoder一样,每一个子层都使用了残差连接,并添加了layernorm。
新添加子层的输入中,query是来自于解码器上一层的输出;key和value是来自于编码器的输出。这可以让解码器的每个位置注意到输入序列的所有位置。这里我的理解是这样的:利用Q,K获取注意力信息,也就是就能利用上一时刻的输出结果的编码与输入序列获取下一时刻输出所需要的注意力权重。假设是中译英的翻译任务,这里的输入序列就是中文的编码信息,上一时刻的输出结果就是上一时刻及之前输出的英文序列结果。这样在预测当前输出结果时,就能利用编码器的所有信息,能够注意到所有位置的信息获得一个输出。
解码器预测时的输入是上一时刻及之前的网络输出结果。但是在训练的时候是将整个输出结果输进去的。由于解码器中的自注意力层允许解码器中的每一个位置都关注到解码器的所有位置。为了防止信息左流以保持自回归的特性,我们通过屏蔽掉所有的对应着非法连接的softmax输入实现。
这里信息左流的解释:
为了保持自回归的性质,要保持从左往右的顺序 (这种情况下,不能利用要预测的未来来推断过去)。 这里将当前token以后的进行mask (即将注意力得分加上-inf,将其变成无穷小,使其注意力系数极小接近于无) [exp(-inf) = 0]。GAT也是这样做的,只不过mask的是非邻居结点 (避免信息泄露,从而让模型学不好)。
Attention
attention函数可以被描述为将query和一系列键值对映射到输出的过程。在这里QKV都是向量。输出是V的加权之和,这里的权重是由Q和V计算出来的。
scale dot-product attention
Q(query),K(key),V(value)可以理解为带有时序信息的向量。
文中采用的注意力机制除了缩放系数
在两种常用的注意力机制中,文章解释了为什么用点积注意力机制,而不是加型注意力机制。
加型注意力机制采用单个隐藏层的前向神经网络计算注意力系数。然而这两种方式理论上复杂度是一样的。但是点积注意力计算速度更快和空间利用更高效,因为可以使用高度优化的矩阵乘法代码进行计算。
缩放点积注意力的输入包括维度为
对
对于较小的
multi-head attention
其中
缩放点积注意力是多头注意力的一部分。在多头注意力机制中,总体思路是先进行线性映射,然后进行多头注意力的计算,再进行concat和线性映射。
文中提及先对Q,K,V进行h次线性映射,这样效果更好。这h次分别将Q,K,V的维度从d转换成
多头有什么好处呢?多头可以允许模型联合处理不同位置(head)的不同表示子空间中的信息。如果使用单头注意力,那么计算中的平均操作会阻碍模型学习到这种信息。
假设模型输入的向量的维度为d,经过h次线性映射后,每一个head的维度为
关于多头在这里有两种思考路径:
思考一:
假设
思考二:
假设
总结:
其实根据点乘的原理,上述两种思考的结果是一致的,每个多头注意力用的是不一样的可以学习的权重。一开始权重矩阵分开计算的方式和先点乘完后再分开其实是一致的。
假设h=2,d/2=n,那么将有两次
所以上述两种思路是等价的。
不过如果按照计算机计算的方便性,应该是先将其进行点乘,然后再分开,这样计算效率会更高。
每个head进行注意力计算后,输出
在代码中,也是采用第二种思路进行代码编写。
由于降低了维度,所以多头注意力的计算量与单头计算量大致相当。
所以,多头注意力的关键点就是将线性变换后的Q,K,V按照维度划分成了h份,每一份进行注意力的计算,计算h次,多头注意力可以联系不同位置表示子空间的信息。
多头注意力中的线性变换
在两个线性变换中增加一个RELU激活函数,其变换公式如下:
输出
在输出中,每个时间步输出都使用了可以学习的线性变换,并且采用softmax输出下一个输出token的概率。
输出线性层的作用:通过对上一步进行线性变换得到指定维度的输出,也就是转换维度,转换后的维度对应着输出类别的个数。如果是翻译任务,对应着文字字典的大小。
正则化手段
每一个子层(缩放点积注意力)的softmax输出之后,与V进行计算之前,采用了dropout。同时在编解码器对位置嵌入和词嵌入之和后面添加了dropout。
维度变化
-
词嵌入和位置嵌入:
输出:(batch_size,seq,dimension)
-
缩放点积注意力:
输入 (batch_size,seq,dimension)
:(dimension,dimension)输出:(batch_size,seq,dimension)
-
多头注意力
线性映射将维度分为h份后,Q,K,V的的维度变成:(batch_size,seq,h,dimension/h)
拿出一组head进行说明,
与 的转置点积: (seq,dimension/h) (dimension/h,seq),输出的维度为: (seq,seq)然后沿着最后一个维度做softmax,使每一行的和为1。拿出第一行来说,表示的是第一个字与其他几个字的注意力状态,即权重。也就是第一个字与其他几个字的相关程度。
然后利用注意力矩阵给
加权。 (seq,seq) 与 (seq,dimension/h) 相乘,输出 (seq,dimension/h)因为有h个head,concat之后的维度为 (batch_size,seq,dimension)
-
做残差:
输出维度为(batch_size,seq,dimension)
-
层归一化。
层归一化把神经网络中的隐藏层归一化为正态分布,也就是i.i.d独立同分布,以起到加快训练速度,加速收敛的作用。
-
前馈神经网络:
-
输入:(batch_size,seq,dimension),权重(batch_size,dimension,d)(batch_size,d,dimension)
-
输出仍然是:(batch_size,seq,demsion)
优缺点分析
-
每层的计算复杂度更低
大多数情况下,序列长度小于表示维度d,这时self-attention会更快。可以并行计算
-
self-attention只需要操作一次,但是RNN需要操作O(n)
-
解决长序列依赖问题
由于RNN固有特性,需要一步一步计算,在遇到长序列,需要从第一个序列计算到第n个序列。CNN需要增大感受野。而self-attention只需要计算一次。当序列n过长的时候可以通过窗口限制长度。
-
模型更具有可解释性。通过对结果分析,其学到了一些语义和语法信息。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!