Attention Is All You Need论文阅读笔记
Attention is All You Need是如今机器学习研究者必读的论文,该文章提出的Transformer架构是如今很多机器学习项目的基础,说该文章极大推动了机器学习领域的研究也不为过。
但这么重要,也是必读的文章对初学者来说其实并不友好,很多前置知识和背景可能因为篇幅原因并没有详细介绍,故本文参考周奕帆的解读,Transformer注意力以及illustrated transformer的同时,再补充更多基础知识,希望让机器学习的初学者也能很快读懂这篇文章。
前置知识
循环神经网络RNN
普通神经网络的大致结构为输入层=>隐含层=>输出层,层与层之间全连接,但层内的节点互相没有连接,所以该网络只能处理顺序递进的任务,而无法处理前后相关联的,比如翻译等任务。
为解决同一层次节点的关联问题,RNN诞生了,该网络会记忆前面节点的信息并用于当前输出的计算。即隐藏层之间的节点不再无连接而是有连接的,并且隐藏层的输入不仅包括输入层的输出还包括上一时刻隐藏层的输出。
针对翻译任务,其解决过程大致如下:
I want to eat a hamburger, it is so delicious
-->我想吃
-->我想吃汉堡
-->我想吃汉堡,它/他/她(代指谁要看前面语境,RNN的主要结构创新,用前面的输出作为下一层的输入)
-->我想吃汉堡,汉堡实在太好吃了
该网络的多种结构如下图,这些不同结构的应用与详解可见RNN详解:
编码器与解码器Encoder-Decoder
原始RNN结构在处理翻译任务时只能实现等长的输入输出,然而翻译任务的输入输出在大多数情景下都是不等长的。
为此人们设计了一种新的架构,该架构将RNN网络分成两部分,前半段只有输入,后半段只有输出,中间通过一个状态来转递信息,这就是编码器解码器结构Encoder-Decoder
。
该结构不是具体的网络,而是一种框架的统称,编码器Encoder
负责将输入转换为固定长度的向量,解码器Decoder
负责将固定长度的向量转换成输出,因为该结构不限制输入和输出长度,所以应用十分广泛,应用场景有:
1,机器翻译:Encoder-Decoder的最经典应用,事实上该结构就是在机器翻译领域最先提出的。
2,文本摘要:输入是一段文本序列,输出是这段文本序列的摘要序列。
3,阅读理解:将输入的文章和问题分别编码,再对其进行解码得到问题的答案。
4,语音识别:输入是语音信号序列,输出是文字序列。
注意力模型
经过上面的介绍我们可能想到,输入和输出之间只有一个固定长度的中间向量作为连接,当输入较长时,该定长向量还能否保证信息完整性,这就是RNN的不足。
为此,有人提出了注意力机制attention mechanism
,该机制仍然使用编码器和解码器,但在不同时间输入多个中间向量来解决问题,解码器的输入是编码器结果的加权和,而非简单的中间向量,每个输入对输出的权重叫注意力,注意力的大小取决于输入输出的相关性。
注意力框架从结构上的变化如下图:
以翻译为例,数学计算上的结构如下图,其中 a i j a_{ij} aij表示相关性, h i h_i hi为 i i i阶段输入, c i c_i ci为 i i i阶段中间向量:
注意力机制优化了解码器与编码器的信息交流方式,处理长文章时更有效,但所有基于RNN的结构也都面临同一个问题:因为本轮输入取决于上一轮的状态,所以训练过程必须是线性执行的,RNN的训练速度较慢。
基于上述研究现状,放弃RNN,完全使用注意力机制的Transformer问世了。
文章摘要
摘要中提到序列传导模型中性能最好的是用注意力机制连接编码器和解码器的框架,但该框架仍基于复杂的递归和卷积神经网络,故文章提出了一种完全基于注意力机制,无需递归和卷积网络的框架。实验结果显示模型的质量上乘,并且训练时间明显减少。
由前置知识中的注意力模型我们知道,RNN网络虽然解决了元素相关依赖的问题,但是其输入取决于上一轮状态,训练过程的效率较低。
本文引言中将该问题描述为:“这种固有的 Sequences 性质排除了训练样本中的并行化,这在较长的序列长度下变得至关重要,因为内存约束限制了样本之间的批处理。最近的工作通过因式分解技巧和条件计算实现了计算效率的显著提高,同时也提高了后者情况下的模型性能。但是,顺序计算的基本约束仍然存在。”
该描述引出了Transfomer要解决的问题——提高并行训练效率。
随后介绍了注意力机制:"注意力机制已成为各种任务中引人注目的序列建模和转导模型不可或缺的一部分,允许对依赖关系进行建模,而不考虑它们在输入或输出序列中的距离。然而,除了少数情况外,这种注意力机制都与循环网络结合使用。在这项工作中,我们提出了 Transformer,这是一种避免重复出现的模型架构,而是完全依赖注意力机制来绘制输入和输出之间的全局依赖关系。Transformer 允许显著提高并行化水平,并且在 8 个 P100 GPU 上经过短短 12 小时的训练后,就可以达到翻译质量的新水平。"
上述内容指出注意力机制可以无视序列中的距离,作者依据该机制提出了一种全新的名为Transformer的架构,可以绘制输入输出的依赖关系,训练速度更快,表现也更好。
也就是放弃RNN网络,仅使用注意力机制构造新的结构,以绘制全局依赖关系。
注意力机制
感性认识
论文自顶向下介绍设计,但读者可能并不了解模块,一下引入过多新概念容易劝退读者,所以本文跟随周奕帆的思路,介绍顺序修改为自底向上,首先介绍论文的关键机制——注意力。
论文首先对注意力作了大致解释:注意力函数可以描述为将查询和一组键值对映射到输出,其中查询、键、值和输出都是向量。其中输出由值的权重和构成。
像是数据库的查询操作。
在学习具体算法之前我们通过一个案例对注意力机制先形成一个感性认识:
比如有如下键值对姓名key-年龄value
的数据集合张三:18, 李四:22, 张五:25
,要执行查询query
为:姓张年龄的平均数,查询条件为key[0]==‘张'
。
但在神经网络中很多操作可能并没有现实意义,只是单纯的数学运算,所以我们可以将一切都转换为数字和向量。比如原有的数据集合可转变为[1,0,0]:18, [0,2,1]:22, [1,3,2]:25
,假设张
表示为1,那原有对姓张的查询就可以表示为向量[1,0,0]
,使用该查询向量与集合向量作点积可得到权重向量[1,0,1]
,如果该权重之和大于1,可用激活函数softmax进行归一化处理,结果为[1/2,0,1/2]
,获得的权重向量中的数值就是对不同key的注意力。
该过程用数学表示如下:
[1,0,0]:18 # 张三
[0,2,1]:22 # 李四
[1,3,2]:25 # 张五# 查询向量[1,0,0]
# 查询过程,最后获取权重
dot([1,0,0],[1,0,0])=1
dot([0,2,1],[1,0,0])=0
dot([1,3,2],[1,0,0])=1# 归一化处理,获对每个key的注意力
softmax([1,0,1])=[1/2,0,1/2]
dot([1/2,0,1/2],[18,22,25])=21.5
平均年龄为21.5
到这里我们也会有感觉,这注意力明明是一次查询匹配的归一化结果,重点应该在查而不在注意上,周也认为该机制称为“全局信息查询”才更合理。
缩放点积注意力Scaled Dot-Product Attention
Q Q Q代表查询向量组,可由多个查询如 q = [ 1 , 0 , 0 ] q=[1,0,0] q=[1,0,0]的组成;
K K K是键key
的向量组, V V V则是键值value
的向量组,用数学符号表示感性认识中的操作为:
m y a t t e n t i o n ( q , K , V ) = s o f t m a x ( q K T ) V myattention(q,K,V)=softmax(qK^T)V myattention(q,K,V)=softmax(qKT)V
有关softmax的知识可见深度学习基础,该算法用于多分类问题,将结果归一化成概率可能性,归一化后的结果数值为正和为1。
论文中的注意力机制与我们的感性认识大致相同,文章将其称为“缩放点积注意力”,大名鼎鼎的注意力公式如下:
A t t e n t i o n ( Q , K , V ) = s o f t m a x ( Q K T d k ) V Attention(Q,K,V)=softmax(\frac{QK^T}{\sqrt{d_k} } )V Attention(Q,K,V)=softmax(dkQKT)V
多个查询 q q q的组合就是 Q Q Q,我们的感性认识和该公式只差一步 d k d_k dk;
论文还引入了两个变量,分别是键的维度 d k d_k dk,键值的维度为 d v d_v dv,在该公式中,因为 Q Q Q和 K K K要作点积预算,所以 Q Q Q的维度要和 d k d_k dk一致,而 d v d_v dv则无要求。
所以 a t t e n t i o n attention attention的本质就是在我们感性认识的基础上用 k k k的维度对注意力进行了缩放,那为什么要进行这一步操作呢?这涉及深度学习中激活函数的特性,周的解释为:“softmax在绝对值较大的区域梯度较小,梯度下降的速度比较慢。因此,我们要让被softmax的点乘数值尽可能小。而一般dk在较大时,也就是向量较长时,点乘的数值会比较大。除以一个和dk相关的量能够防止点乘的值过大。”
注意力函数除了本文提到点积的方法,还有加性注意力,效率上点积更快一些,故该论文选了这种方法。
缩放点积注意力的执行流程图如下:
1,输入 Q , K , V Q,K,V Q,K,V, M a t M u l MatMul MatMul矩阵乘法,计算查询 Q Q Q和键 K K K的相关度,多采用点积计算;
2, S c a l e Scale Scale缩放,除 d k \sqrt{d_k} dk;
3, M a s k Mask Mask掩码,屏蔽后续信息,将在整体框架中介绍;
4, S o f t M a x SoftMax SoftMax归一化;
5,最后将查询归一化结果与键值 V V V作乘法,计算注意力结果。
自注意力Self-Attention
自注意力在文中介绍很少,但在注意力机制中又是很关键的内容,所以展开学习一下。
1,感性认识
在翻译场景下,注意力机制用于实现英文到中文的翻译转换,自注意力则是完成序列内词义的确定,,比如”The animal didn't cross the street because it was too tired”
,如何确定后面的it
是指animal
还是street
呢?通过自注意力机制可确定it
的翻译要重点关注animal
。
有关该部分详细解释可参考一文搞定自注意力机制。
公式上变为如下形式:
s e l f − a t t e n t i o n ( X ) = s o f t m a x ( x x T d k ) X self-attention(X)=softmax(\frac{xx^T}{\sqrt{d_k} } )X self−attention(X)=softmax(dkxxT)X
其中 X X X是序列中的所有元素, d k d_k dk是向量的维度。
所以自注意力本质是注意力机制的一种特殊形式,每个输入元素与序列中的其他元素进行交互,计算得出自己的自身的表示,其实就是输入token[i]和整个输入token的注意力计算。
2,具体算法
1,自注意力中, Q K V QKV QKV分别由输入 x x x和三个随机矩阵作点积得到,这三个随机矩阵是网络的参数之一,会在训练中不断调整。
2,获取 Q K V QKV QKV矩阵后,使用注意力公式计算得到注意力 S S S,以animal
为例,注意力矩阵 S S S经过softmax归一化操作后可能是[0.88,0.02,0.05,0.05,0]
。
3,此时与整个序列作点积,该操作会获得一个向量并冲淡与该词关联性不强的其他单词。
4,将第三步获得的序列相加就是最终得到的注意力结果。
举一个具体例子:
有三个输入分别为: i n p u t 1 = [ 1 , 0 , 1 ] i n p u t 2 = [ 1 , 1 , 0 ] i n p u t 3 = [ 0 , 0 , 1 ] input1=[1,0,1] input2=[1,1,0] input3=[0,0,1] input1=[1,0,1]input2=[1,1,0]input3=[0,0,1],组合形成的输入为 i n p u t = [ 1 0 1 1 1 0 0 0 1 ] input=\begin{bmatrix} 1 & 0 & 1\\ 1 & 1 & 0\\ 0 & 0 &1 \end{bmatrix} input= 110010101 随机初始化的参数矩阵假设为
W Q = [ 1 0 3 2 1 0 0 0 1 ] W K = [ 1 1 0 2 1 1 1 0 1 ] W V = [ 1 0 0 0 1 1 1 1 0 ] W^Q=\begin{bmatrix} 1 & 0 & 3\\ 2 & 1 & 0\\ 0 & 0 &1 \end{bmatrix} W^K=\begin{bmatrix} 1 & 1&0 \\ 2& 1& 1\\ 1 & 0&1 \end{bmatrix} W^V=\begin{bmatrix} 1& 0 & 0\\ 0& 1 &1 \\ 1& 1&0 \end{bmatrix} WQ= 120010301 WK= 121110011 WV= 101011010
计算得到的 Q , K , V Q,K,V Q,K,V分别为:
Q = [ 1 0 4 3 1 3 0 0 1 ] K = [ 2 1 1 3 2 1 1 0 1 ] V = [ 2 1 0 1 1 1 1 1 0 ] Q=\begin{bmatrix} 1 & 0 & 4\\ 3 & 1 & 3\\ 0 & 0 &1 \end{bmatrix} K=\begin{bmatrix} 2 & 1 & 1\\ 3 & 2 & 1\\ 1 & 0 &1 \end{bmatrix} V=\begin{bmatrix} 2 & 1 & 0\\ 1 & 1 & 1\\ 1 & 1 &0 \end{bmatrix} Q= 130010431 K= 231120111 V= 211111010
使用注意力公式 Q K T V QK^TV QKTV可得所有输入的自注意力结果,为了简化计算,只使用 i n p u t 1 input1 input1的查询 q 1 q_1 q1作为输入进行计算,过程如下
q 1 × K T = [ 1 , 0 , 4 ] × [ 2 3 1 1 2 0 1 0 1 ] = [ 6 , 3 , 5 ] q_1\times K^T=[1, 0, 4]\times\begin{bmatrix} 2& 3&1 \\ 1& 2&0 \\ 1& 0 &1 \end{bmatrix}=[6, 3 ,5] q1×KT=[1,0,4]× 211320101 =[6,3,5]
将该向量 [ 6 , 3 , 5 ] [6, 3, 5] [6,3,5]softmax处理后再与V点积运算并相加求和即获得 i n p u t 1 input1 input1的自注意力结果,也就是其更新后的自身表示。
自注意力计算过程示例图如下:
通过对自身所在序列进行注意力计算有什么作用呢?
背景中我们提到,注意力机制的出现是为了弥补Encoder
和Decoder
之间用于联系的定长向量过于脆弱,在长程输入下的失效问题。
我的理解是,自注意力利用注意力机制使每个输入都能获得自己与输入整体中其他元素的关联,使单个内容与上下文的联系更加紧,单独元素也携带上下文信息。
多头注意力Multi-Head Attention
自注意力模式下,所有输入都只关注序列中其他位置的向量与自身的关系,也就是注意力都在自身,对整个序列信息的关注就可能相对不足,论文作者提出了多头注意力机制解决这一问题,即将学习到不同线性投影的查询、键和值,线性投影到 dk、dk 和 dv 维度是有益的。多头注意力允许模型共同关注来自不同位置的不同表示子空间的信息,缓和单个注意力头的波动
。
其实就是作者发现组合多个自注意力结果的效果更好,通过 C o n c a t Concat Concat组合器将多个缩放点积注意力组合起来生成效果,修改后的数学表示为:
h e a d i = A t t e n t i o n ( Q W i Q , K W i K , V W i K ) head_i=Attention(QW_i^Q, KW^K_i, VW_i^K ) headi=Attention(QWiQ,KWiK,VWiK)
M u l t i H e a d ( Q , K , V ) = C o n c a t ( h e a d 1 , . . . , h e a d i ) W O MultiHead(Q, K, V )=Concat(head_1, ... , head_i)W^O MultiHead(Q,K,V)=Concat(head1,...,headi)WO
其中 d m o d e l d_{model} dmodel为输出长度,即每个输入会映射为 d m o d e l d_{model} dmodel个输出,默认设置为512, n n n个输入的维度为 n × d m o d e l n\times d_{model} n×dmodel。
W Q , W K W^Q, W^K WQ,WK形状为 d m o d e l × d k d_{model}\times d_k dmodel×dk, W V W^V WV形状为 d m o d e l × d v d_{model}\times d_v dmodel×dv, W O W^O WO形状为 h d v × d m o d e l hd_{v}\times d_{model} hdv×dmodel。
通常注意力头个数 h h h选择为8,维度 d k = d v = d m o d e l / h = 64 d_k=d_v=d_{model}/h=64 dk=dv=dmodel/h=64, h e a d i head_i headi的维度为 n × d k × d k × n × n × d v = n × d v n\times d_{k}\times d_k \times n\times n\times d_v=n\times d_v n×dk×dk×n×n×dv=n×dv,最后得到的 M u l t i H e a d MultiHead MultiHead维度为 n × d m o d e l n\times d_{model} n×dmodel。
而如果不适用多头缩小 h h h倍,单头计算维度为 n × d m o d e l × d m o d e l × d m o d e l = n × d m o d e l n\times d_{model} \times d_{model}\times d_{model}=n\times d_{model} n×dmodel×dmodel×dmodel=n×dmodel,可见多头将维度缩小为原来的 1 h \frac{1}{h} h1,但组合了 h h h个结果,所以总计算成本与全维的单头部注意力相似。
多头注意力计算组合如下图:
该过程可同时训练多组 W Q , W K , W V W^Q, W^K, W^V WQ,WK,WV,提高关联性的同时增加了自注意力表示的丰富度。
Transformer模型
了解了注意力机制,我们回过头来学习Transformer的整体架构,Transformer 遵循这种整体架构,编码器和解码器都使用堆叠式自注意力层和逐点全连接层,分别如图的左半部分和右半部分所示
:
主干结构
输入输出的处理我们暂且搁置,先只看主干结构:
图中橙色部分的Multi-Head Attention
我们已经了解了,文中提到编码器解码器分别由 N = 6 N=6 N=6个相同层组成,主干结构的大致流程为:
输入 i n p u t s inputs inputs经过编码器处理进入解码器,上一轮的输出 O u t p u t s Outputs Outputs直接进入解码器,经过单独一层处理后与编码器输入一同处理生成新的输出。
但对模型的主干结构还有三个疑问:
1,Add&Norm
是做什么的?
2,Feed Forward
的功能是什么?
3,右图下方的多头注意力为什么加了Masked
?
原文中提到:
编码器部分第一个是多头自注意力机制,第二个是简单的、位置完全连接的前馈网络。我们在两个子层中的每一个周围采用残差连接,然后进行层归一化
。
而解码器部分除了每个编码器层中的两个子层之外,解码器还插入了第三个子层,该子层对编码器堆栈的输出执行多头注意。我们还修改了解码器堆栈中的 self-attention 子层,以防止 positions 关注后续位置。这种掩码,再加上输出嵌入向量偏移一个位置的事实,确保对位置 i 的预测只能依赖于小于 i 的位置的已知输出
。
也就是说:
Add&Norm是残差连接和归一化;
Feed Forward是完全连接的前馈网络;
Masked是为了保证输出不受预测影响。
下面依次对这些知识进行补充介绍。
残差连接add&Norm
本小节参考ResNet核心思想。
残差连接的基础是跳跃连接(skip connection),指的是越过某些中间层,将数据直接添加到中间节点上。
该操作使得信息可以更自由地流动,并且保留了原始输入数据中的细节和语义信息。 使信息更容易传播到后面的层次,避免了信息丢失。
比如网络层层递进的结构中,尤其卷积操作,输入细节可能不断丢失,随着层数的深入,学习效果反而可能变差。
此时添加一个跳跃连接,将输入与最后一层拼接起来,可以保留输入的更多原始语义和信息。
跳跃连接示意图如下:
残差网络ResNet
则是专门用于解决网络层数过深导致的梯度消失和训练困难问题,其核心思想是引入残差块构建网络,并使用跳跃连接将输入直接添加到输出层上。
该部分并非Transformer核心内容,有关原理讲解可见ResNet模型详解。
对该模型作大致介绍,输入 x x x,经过卷积层、批归一化(BN)、激活函数(ReLU)等一通操作构成 F ( x ) F(x) F(x),输出为 H ( x ) = F ( x ) + x H(x)=F(x)+x H(x)=F(x)+x通过跳跃连接将输入与之相加,最后归一化操作。
本文使用的方法与之类似,子层的输出是 L a y e r N o r m ( x + S u b l a y e r ( x ) ) LayerNorm(x + Sublayer(x)) LayerNorm(x+Sublayer(x)),其中 S u b l a y e r ( x ) Sublayer(x) Sublayer(x)是由子层本身实现的函数, L a y e r N o r m LayerNorm LayerNorm是归一化方法。
残差连接要求 x x x与 F ( x ) + x F(x)+x F(x)+x等长,所以在Transformer中模型子层和嵌入层的输入都是 d m o d e l = 512 d_{model}=512 dmodel=512。
前馈网络Feed Forward
就是一个网络,其中包括两个线性变换,中间有一个 ReLU 激活,执行公式为:
F N N ( X ) = m a x ( 0 , x W 1 + b 1 ) W 2 + b 2 FNN(X)=max(0,xW_1+b_1)W_2+b_2 FNN(X)=max(0,xW1+b1)W2+b2
其中隐藏层维数 d f f = 2048 d_{ff}=2048 dff=2048
因为注意力机制本质是线性的矩阵变换,该网络 F N N FNN FNN通过激活函数引入非线性特征,使模型能拟合复杂函数关系;同时将 d m o d e l = 512 d_{model}=512 dmodel=512维上升到 d f f = 2048 d_{ff}=2048 dff=2048维,扩展特征空间,方便更深层次提取特征。
右移操作shifted right
在讲掩码多头注意力之前不得不转到主干结构之外,解码器的另一个输入来自上一个解码器的输出,但该 o u t p u t s outputs outputs使用了一次shifted right
操作,这步操作有什么含义?
首先看一下Transformer对注意力机制的使用:
1,在编码器解码器层中,查询 Q Q Q来自前一个解码器,键 K K K和值 V V V来自编码器。编码器与输入 i n p u t input input一一对应。
2,编码器使用自注意力。该层注意力的 Q , K , V Q, K, V Q,K,V都来自前一层编码器。
3,解码器使用自注意力,该机制使整个序列对当前生成的元素都可见。
这种机制有两个问题:
1,当编码器接受第0个字符时,上一层的输出该如何设置使编码器解码器处理对齐?
2,Transformer并行训练时,序列 t 0 , . . . , t k t_0, ..., t_k t0,...,tk都进入解码器,但此时才输出到 t 2 t_2 t2,如何避免后续序列对输出的干扰。
shiftedright右移操作解决第一个对齐问题。
该操作将输出序列整体右移一位,解码器训练数据为 1 , 2 , 3 1,2,3 1,2,3,整体右移变为 < s o s > , 1 , 2 , 3 <sos>,1,2,3 <sos>,1,2,3,此时编码器处理第0个数据, < s o s > <sos> <sos>就可以作为上一个解码器的结果输出给当前解码器,实现对齐。
掩码多头注意力Masked Multi-Head Attention
该机制解决前面提到的第二个问题,输出序列当前步 i i i预测输出应该只根据该步以前的结果,即 i − 1 i-1 i−1实现,但用于解码器训练的输出序列全部输入解码器中,为防止后续元素对解码过程的干扰,应该把后续元素给“盖住”,类似如下过程:
掩码注意力的mask
就是实现“盖”的功能,论文中使用将注意力 s o f t m a x softmax softmax的输入设置为 − ∞ -\infty −∞实现,该设置导致权重为0,被遮住的输出就全为0。
训练并行,推理串行
首先声明一个结论,Transformer是训练并行,推理串行的结构。
前面提到的第二个问题我反反复复看了好几遍,假如有输入序列 < s o s > , 1 , 2 , 3 <sos>, 1, 2, 3 <sos>,1,2,3要进入Transformer,编码器输出 K i , V i K_i, V_i Ki,Vi给解码器,解码器接收上一步解码器输出 Q i − 1 Q_{i-1} Qi−1与本次编码输出 K i , V i K_i, V_i Ki,Vi得出本次输出 Q i Q_i Qi,这样一个串行执行的结构怎么会涉及避免后续元素的干扰问题?
我忽略了一个关键问题,Transformer就是为了改进RNN串行训练速度慢才诞生的,所以其训练过程一定是并行的。
对于这个问题很多资料一带而过,本节单独对该内容进行详细说明。
传统RNN网络的训练过程应该是输入序列 X X X输入编码器,生成 K , V K, V K,V给解码器,解码器从 < s o s > <sos> <sos>开始不断推理生成预测 P P P,最后与正确输出 P P P进行比较,使用损失函数更新编码器解码器参数,大致流程如下:
该方案的缺陷是序列P要逐步生成并代替 < s o s > <sos> <sos>,这种串行的训练模式效率十分低下。
传统RNN采用该方案的原因是当前生成的元素无法有效关联其他元素,必须逐步生成,将已有元素输入下一步预测节点。
而Transformer使用注意力机制,生成的每个元素都清楚知道自己和其他元素的关系,所以对任意元素的预测都可以独立进行。注意力允许Transformer同步生成所有序列,即同时生成 t 0 , t 1 , . . . , t n t_0, t_1, ..., t_n t0,t1,...,tn。
取消递推训练后的解码器上一步输入 Q Q Q又由谁决定呢?Transformer使用一种名为“教师强迫”Teacher forcing
的训练模式,即每个节点都将正确的输出作为已知的序列进行预测,使用这种模式可以实现所有节点无需等待上一步预测,独立进行训练。
但正确的输出过于完整,节点 i i i应该只基于 0 − i 1 0-i_1 0−i1个序列进行预测,所以作者采用了掩码注意力机制,将i及以后的输出对当前节点隐藏。
假设有一训练集为x=我想吃汉堡,p=I want to eat a hamburger,Transformer训练过程如下:
该过程比较复杂,再次简要总结:
1,注意力建立序列关联性,使训练无需等待前一次结果独立进行;
2,Teacher forcing机制让解码器将正确输出作为上一次结果,实现并行训练;
3,掩码注意力机制为当前节点屏蔽后续正确输出,使训练依据局限在当前序列。
如果还不能理解可以看transformer如何实现并行化,该文章角度中,编码器并行由注意力机制实现,解码器并行由Teacher forcing和掩码注意力共同作用实现。
但推理过程仍然是串行的,解码器不断迭代生成序列用于下一次输出。
嵌入层Embedding
主干网络之后我们来看模型对输入输出的处理:
和其他序列转换模型一样,Transformers也使用词嵌入处理输入输出,将其转换为维度 d m o d e l d_{model} dmodel的向量。
词嵌入就是将词转换为向量的方法,如猫=>[0,1,1] 狗=>[0,0,1]
,转换后的形式更容易被计算机识别并计算,有关具体方法可见从0开始词嵌入。
随后使用通常的线性变换和softmax将解码器输出转换为预测的下一个标记概率。
文中提到:两个嵌入层和线性变换层之间共享相同的权重矩阵,并在嵌入层中将权重乘 d m o d e l \sqrt{d_{model}} dmodel。
位置编码Positional Encoding
Transformer现在只剩下一个位置没有解读了,就是输入后的位置编码:
因为Transformer中不含递归和卷积,注意力机制为了并行计算也只具有全局查询功能,因此为了让模型利用序列的顺序,必须注入一些关于序列中标记的相对或绝对位置的信息。
为此,作者设计了一种“位置编码”,将序列顺序信息直接与编码器和解码器输入的 E m b e d d i n g Embedding Embedding相加,保证位置信息参与模型的后续运算,所以真正的输入 i n p u t = e m b e d d i n g + p o s i t i o n a l e n c o d i n g input=embedding+positional encoding input=embedding+positionalencoding。
位置编码与词嵌入具有相同维度 d m o d e l d_{model} dmodel,使用 p o s pos pos表示位置, i i i表示维度,
作者使用了不同频率的正弦和余弦函数作为位置编码:
P E ( p o s , 2 i ) = s i n ( p o s / 10000 2 i / d m o d e l ) PE(pos,2i)=sin(pos/10000^{2i/d_{model}}) PE(pos,2i)=sin(pos/100002i/dmodel)
P E ( p o s , 2 i + 1 ) = c o s ( p o s / 10000 2 i / d m o d e l ) PE(pos,2i+1)=cos(pos/10000^{2i/d_{model}}) PE(pos,2i+1)=cos(pos/100002i/dmodel)
比如输入dog eat food
,每个词对应的 p o s = 0 , 1 , 2 pos=0,1,2 pos=0,1,2,假设转换的 E m b e d d i n g Embedding Embedding维度是20,计算过程示例如下:
在该公式中,当 i = 0 i=0 i=0即低维情景下,频率 1 10000 2 i / d m o d e l = 1 \frac{1}{10000^{2i/d_{model}}}=1 100002i/dmodel1=1,当 i = d m o d e l i=d_{model} i=dmodel即高维场景下,频率等于 1 10000 1 2 ≈ 0.01 \frac{1}{10000^{\frac{1}{2}}}\approx 0.01 10000211≈0.01。
也就是低维频率大,高维频率小,这进一步导致低维位置编码变化大,高维位置编码变化小,相加得到的结果输入网络后会使网络通过低维位置编码关注局部差异,又通过高维建立序列整体联系。
这种设计同时可保证编码唯一,并且不依赖最大序列长度,支持任意长度的输入。
同时作者还尝试了可学习的位置编码函数,发现二者结果几乎相同,最终选择了该版本也是因为其支持任意长度的输入序列,可学习的位置编码只能处理训练时的序列长度。
有关位置编码更详细的介绍可参考详解自注意力机制中的位置编码。
实验结果
作者对英语-德语,英语-法语两项任务进行了训练,使用8张P100显卡,每个训练步骤需要0.4s,基本模型用12小时就可以训练结束,大模型3天半也能训练完成。
Transformer使用更少的训练成本实现了最好的训练效果。
另外进行了消融实验,即分别修改实验条件和参数,确定对结果影响更大的因素。
实验A表明,头部数量 h h h和键的维度 d k d_k dk比例要适中,太大太小效果都不好,而且另外表明多头注意力要优于单头。
实验B表明,键 d k d_k dk减小会损失性能,作者认为相关性的建立比较复杂,如果能有比点积更好的方法可能会带来性能的提升。
实验CD表明,大模型效果更好,并且使用dropout是有必要的。
实验E则是证明可学习的嵌入位置编码与文章使用的结果相近。
总结
针对循环神经网络RNN串行训练效率低的问题,Transformer提出了一种完全基于注意力机制的模型结构,更适合长序列任务。
对该文章解决问题的核心方法总结如下:
自注意力关联输入序列。在该结构中,以往结合本次输入和上步预测的信息关联手段被自注意力计算取代,自注意力计算下每个输入元素都能获得自己与整个输入序列的关联性。
Teacher Forcing提供并行训练数据。并行时仍采用迭代训练方法,训练数据采用Teacher Forcing
方法,将正确输出作为上一步预测直接输入到解码器中,与自注意力一起作为并行训练的基础。
掩码注意力屏蔽后续输出干扰。当下节点的预测结果应该只根据已有数据,但Teacher Forcing将正确输出全部输入到解码器,故在解码器第一层设置掩码注意力,屏蔽当前节点以后的数据,保证预测只来自已有信息。
位置编码提供位置信息。使用自注意力只能使序列获得整体关联信息,而无法使模型利用序列顺序,将位置编码与词嵌入相加可使模型从顺序角度对序列进行关联。
总的来看,Transformer模型中包含更多信息,又摒弃了RNN串行训练的方式,提高训练效率的同时也提高了训练质量,应用领域也由自然语言处理发展到计算机视觉,有如此大的名气确实是实至名归。
相关文章:

Attention Is All You Need论文阅读笔记
Attention is All You Need是如今机器学习研究者必读的论文,该文章提出的Transformer架构是如今很多机器学习项目的基础,说该文章极大推动了机器学习领域的研究也不为过。 但这么重要,也是必读的文章对初学者来说其实并不友好,很多…...
深入理解设计模式之中介者模式
深入理解设计模式之:中介者模式(Mediator Pattern) 一、什么是中介者模式? 中介者模式(Mediator Pattern)是一种行为型设计模式。它通过引入一个中介对象,来封装一组对象之间的交互࿰…...
OpenCV 图像像素的读写操作
一、知识点 1、在OpenCV中,一切图像皆Mat。 2、对图像像素的读写操作,就是对Mat元素的遍历与访问。 3、对Mat使用数组方式遍历与访问。 (1)、函数声明: template<typename _Tp> inline_Tp & Mat::at(int i0, int i1) (2)、参数说明:…...
【前端】【Vue3】vue3性能优化总结
第一章 Vue3性能优化概述 1.1 Vue3性能提升背景 1.1.1 Vue2性能瓶颈分析 1. 响应式原理的局限性 Object.defineProperty 的缺陷:Vue2 使用 Object.defineProperty 来实现响应式。这个方法只能劫持对象的属性,对于新增或删除属性无法自动响应。例如&a…...

如何制作全景VR图?
全景VR图,特别是720度全景VR,为观众提供一种沉浸式体验。 全景VR图能够捕捉场景的全貌,还能将多个角度的图片或视频无缝拼接成一个完整的全景视角,让观众在虚拟环境中自由探索。随着虚拟现实(VR)技术的飞速…...
动态防御新纪元:AI如何重构DDoS攻防成本格局
1. 传统高防IP的静态瓶颈与成本困境 传统高防IP依赖预定义规则库,面对SYN Flood、CC攻击等威胁时,常因规则更新滞后导致误封合法流量。例如,某电商平台曾因静态阈值过滤误封20%的订单接口流量,直接影响营收。以下代码模拟传统方案…...
汽车软件刷写 APP SBL PBL概念
目录 PBL(Primary Boot Loader)SBL(Secondary Boot Loader)PBL与SBL的协作流程在汽车刷写中,APP、PBL、SBL的含义如下: APP:指应用程序(Application),是汽车电子控制单元(ECU)中实现具体功能的软件,如发动机控制、变速箱控制、车身电子稳定系统等功能的程序。在刷…...
自动化中的伦理:驯服人工智能中的偏见与守护合规之路
当算法取代人脑做出关乎就业、信贷、医疗乃至法律判决的决定时,我们赋予机器的不仅仅是效率,更是塑造社会公平的巨大力量。自动化系统在提升生产力的同时,其内在的偏见风险如同暗流涌动,若缺乏道德罗盘与严格约束,本应…...

Flask与PostgreSQL交互教程
目录 1. 项目结构2. 环境准备2.1 安装依赖2.2 使用Docker启动PostgreSQL 3. 数据库配置3.1 环境变量配置3.2 数据库连接配置 4. 定义数据库模型5. 实现API接口5.1 创建用户5.2 获取所有用户5.3 获取单个用户5.4 更新用户5.5 删除用户 6. 运行应用7. API测试7.1 创建用户7.2 获取…...

XJTU-SY轴承振动数据集的json自封装
1.最终形式的形式 不用再去翻文档找对应的故障类型,采样率等信息了,所有的信息自包含在.json文件里,15个测试例,一个测试例对应一整个.json文件。 {"dataset": {"name": "XJTU-SY_Bearing_Datasets&quo…...

Spring AI 系列2: Advisors增强器简介
一、Advisors简介 1.1 Advisors定义 Advisors 是在 AI 应用程序中处理请求和响应的拦截器。我们可以使用它们为提示流程设置额外的功能。例如,可以建立聊天历史、排除敏感词或为每个请求添加额外的上下文。 Spring AI的Advisor,本质上是一个拦截…...

通过Func实现飞书应用通知消息加急处理
前言 在现代企业运作中,及时响应告警信息对保障系统的稳定性和业务的连续性至关重要。随着业务的数字化转型,越来越多的企业依赖于复杂的技术架构,这使得故障和异常事件的及时处理变得愈发重要。传统的告警通知方式往往存在响应不及时、信息…...

【目标检测】【AAAI-2022】Anchor DETR
Anchor DETR: Query Design for Transformer-Based Object Detection 锚点DETR:基于Transformer的目标检测查询设计 论文链接 代码链接 摘要 在本文中,我们提出了一种基于Transformer的目标检测新型查询设计。此前的Transformer检测器中&am…...
Spring Cloud Alibaba 学习 —— 简单了解常用技术栈
Spring Cloud Alibaba 官网:https://sca.aliyun.com/ 什么是 Spring Cloud Alibaba Spring Cloud Alibaba 是 Spring Cloud 规范在阿里生态的扩展实现,结合了阿里自研组件与开源生态,提供面向云原生场景的微服务解决方案。其核心功能可概括…...

智慧工厂整体解决方案
该方案围绕智能工厂建设,阐述其基于工业 4.0 和数字化转型需求,通过物联网、大数据、人工智能等技术实现生产自动化、数据化管理及联网协同的特点。建设步骤包括评估现状、设定目标、制定方案、测试调整、实施计划及持续改进,需整合 MES、ERP 等软件系统与传感器、机器人等硬…...

秋招Day12 - 计算机网络 - TCP
详细说一下TCP的三次握手机制 TCP的三次握手机制是为了在两个主机之间建立可靠的连接,这个机制确保两端的通信是同步的,并且在开始传输数据前,双方都做好了要通信的准备。 说说SYN的概念? SYN 是 TCP 协议中用来建立连接的一个标…...
KubeMQ 深度实践:构建可扩展的 LLM 中台架构
文章简介 在 AI 应用开发中,集成 OpenAI、Anthropic Claude 等多大型语言模型(LLM)常面临 API 碎片化、请求路由复杂等挑战。本文将介绍如何通过 ** 消息代理(Message Broker)** 实现高效的 LLM 管理,以开…...

vueflow
自定义节点,自定义线,具体细节还未完善,实现效果: 1.安装vueflow 2.目录如下 3. index.vue <script setup> import { ref } from vue import { VueFlow, useVueFlow } from vue-flow/core import { Background } from vue-…...

LearnOpenGL-笔记-其十一
Normal Mapping 又到了介绍法线贴图的地方,我感觉我已经写了很多遍了... 法线贴图用最简单的话来介绍的话,就是通过修改贴图对应物体表面的法线来修改光照效果,从而在不修改物体实际几何形状的前提下实现不同于物体几何形状的视觉效果。 因…...
@Docker Compose 部署 Prometheus
文章目录 Docker Compose 部署 Prometheus1. 环境准备2. 配置文件准备3. 编写 Docker Compose 文件4. 启动服务5. 验证部署6. 常用操作7. 生产环境增强建议8. 扩展监控对象 Docker Compose 部署 Prometheus 1. 环境准备 安装 Docker(版本 ≥ 20.10)和 …...

openppp2 -- 1.0.0.25225 优化多线接入运营商路由调配
本文涉及到的内容,涉及到上个发行版本相关内容,人们在阅读本文之前,建议应当详细阅读上个版本之中的VBGP技术相关的介绍。 openppp2 -- 1.0.0.25196 版本新增的VBGP技术-CSDN博客 我们知道在现代大型的 Internet 网络服务商,很多…...
二次封装 Vuex for Uniapp 微信小程序开发
作为高级前端开发工程师,我将为你提供一个针对 Uniapp Vue2 Vuex 的 Store 二次封装方案,使团队成员能够更便捷地使用和管理状态。 封装目标 模块化管理状态 简化调用方式 提供类型提示(在 Vue2 中尽可能实现) 便于维护和查…...

详细到用手撕transformer下半部分
之前我们讨论了如何实现 Transformer 的核心多头注意力机制,那么这期我们来完整地实现整个 Transformer 的编码器和解码器。 Transformer 架构最初由 Vaswani 等人在 2017 年的论文《Attention Is All You Need》中提出,专为序列到序列(seq2s…...
Spring Boot 整合 Spring Data JPA、strategy 的策略区别、什么是 Spring Data JPA
DAY29.2 Java核心基础 Spring Boot 整合 Spring Data JPA Spring Data JPA根据具体的数据库分为不同的子模块,无论是关系型数据库和非关系型数据库,Spring Data都提供了支持 Mysql:Spring Data JPA Redis:Spring Data Redis …...
Vue 3.0 中的路由导航守卫详解
1. 路由导航守卫 1.1. 全局前置守卫 Vue-Router 提供的导航守卫主要用来守卫路由的跳转或取消。它们可以植入到全局、单个路由或组件级别。 全局前置守卫可以使用 router.beforeEach 注册: const router createRouter({... });router.beforeEach((to, from) &g…...

【Sqoop基础】Sqoop生态集成:与HDFS、Hive、HBase等组件的协同关系深度解析
目录 1 Sqoop概述与大数据生态定位 2 Sqoop与HDFS的深度集成 2.1 技术实现原理 2.2 详细工作流程 2.3 性能优化实践 3 Sqoop与Hive的高效协同 3.1 集成架构设计 3.2 数据类型映射处理 3.3 案例演示 4 Sqoop与HBase的实时集成 4.1 数据模型转换挑战 4.2 详细集成流程…...

MySQL + CloudCanal + Iceberg + StarRocks 构建全栈数据服务
简述 在业务数据快速膨胀的今天,企业对 低成本存储 与 实时查询分析能力 的需求愈发迫切。 本文将带你实战构建一条 MySQL 到 Iceberg 的数据链路,借助 CloudCanal 快速完成数据迁移与同步,并使用 StarRocks 完成数据查询等操作,…...
MSVC支持但是Clang会报错的C++行为
MSVC的非标 目的友元别名模板类显式特例化的命名空间限制 目的 因为在使用clang进行ast分析msvc项目的时候,出现了爆红现象,了解到msvc会有一些不严格按照c标准但是允许的语法,在这点上clang就很严格,所以本文以clang为基准&…...

截屏精灵:轻松截屏,高效编辑
在移动互联网时代,截图已经成为我们日常使用手机时的一项基本操作。无论是记录重要信息、分享有趣内容,还是进行学习和工作,一款好用的截图工具都能极大地提升我们的效率。截屏精灵就是这样一款功能强大、操作简单的截图工具,它不…...

【JavaWeb】基本概念、web服务器、Tomcat、HTTP协议
目录 1. 基本概念1.1 基本概念1.2 web应用程序1.3 静态web1.4 动态web 2. web服务器3. tomcat详解3.1 安装3.2 启动3.3 配置3.3.1 配置启动的端口号3.3.2 配置主机的名称3.3.3 其他常用配置项日志配置数据源配置安全配置 3.4 发布一个网站 4. Http协议4.1 什么是http4.2 http的…...