Author Unit: Google Brain, Google Research, University of Toronto
Authors: Ashish Vaswani ∗ ^* ∗, Noam Shazeer*, Niki Parmar*, Jakob Uszkoreit*, Llion Jones*, Aidan N. Gomez* † ^† †, Łukasz Kaiser ∗ ^∗ ∗, Illia Polosukhin ∗ ‡ ^{∗ ‡} ∗‡
Code: https://github.com/ tensorflow/tensor2tensor
Conference: 31st Conference on Neural Information Processing Systems (NIPS 2017), Long Beach, CA, USA.
Email: mailto:[email protected], mailto:[email protected], mailto:[email protected], mailto:[email protected], mailto:[email protected], mailto:[email protected], mailto:[email protected], mailto:[email protected]
Paper address: https://papers.nips.cc/paper/2017/hash/3f5ee243547dee91fbd053c1c4a845aa-Abstract.html
bilibili_limu: https://www.bilibili.com/video/BV1pu411o7BE?from=search&seid=8901226919527045603&spm_id_from=333.337.0.0
我们提出了一种新的简单的网络架构,Transformer,它仅基于注意机制,完全抛弃了递归和卷积。
之前主流的RNN:LSTM[12]、GRU[7];很多人努力推动RNN和编码器-解码器架构的边界(boundary)[31, 21, 13]。
RNN依据本身的序列性,虽然做到了可以记录历史信息,但是不能很好的并行化,存在比较强的顺序计算约束。
Attention已经用在了很多RNN与Transduction模型中,它可以允许对依赖项建模,而不考虑它们在输入或输出序列中的距离[2,16](可以将编码器的信息很好的传至解码器)。
Transformer,完全依赖于注意力机制来绘制输入与输出的全局依赖性。由于用了Attention,可以很好的做到并行化。
这一章对应了 相关工作 的部分
在Transformer中,学习不同位置的依赖关系被减少到了常数级的操作(若是卷积的话,基本无法学到左上角的像素和右下角的像素之间的依赖),尽管由于平均注意力加权位置(averaging attention-weighted positions)降低了有效分辨率(effective resolution),我们使用Multi-Head Attention来抵消这一影响(在此对应了conv中的多个输出),如第3.2节所述。
Self-attention,有时也称为intra-attention,是一种将单个序列的不同位置联系起来以计算序列表征的注意机制。[4, 22, 23, 19].
End-to-end memory networks是基于重复注意机制而不是顺序排列的重复,并已被证明在简单语言问答和语言建模任务[28]中表现良好。
Transformer是第一个完全依靠self-attention来计算输入和输出表征,而不使用序列对齐的rnn或卷积的转导模型。
编码器将输入序列 ( x 1 , . . . , x n ) (x_1, ..., x_n) (x1,...,xn) 映射到连续表征的序列 z = ( z 1 , . . . , z n ) z= (z_1, ..., z_n) z=(z1,...,zn)。 给定 z,解码器生成一个输出序列 ( y 1 , . . . , y m ) (y_1, ..., y_m) (y1,...,ym),一次一个元素。 在每一步,模型都是自回归的 [9](auto-regressive),即在生成下一个时,将先前生成的符号作为附加输入使用。
Transformer遵循这种总体架构,为编码器和解码器使用了堆叠的self-attention层和point-wise的完全连接层,分别如图1的左、右两部分所示。
Encoder: 编码器由 N=6 个相同层的堆栈组成。每层有两个子层。 第一个是多头自注意力机制,第二个是简单的、position-wise fully connected feed-forward network( 其实就是MLP )。 我们在两个子层的每一个周围都使用了一个残差连接 [10],然后是层归一化 Layer normalization[1]。 即每个子层的输出是LayerNorm(x+ Sublayer(x)),其中Sublayer(x)是子层自己实现的函数。 为了促进这些残差连接,模型中的所有子层以及embedding层产生维度 d m o d e l = 512 d_{model}=512 dmodel=512 的输出。( 输入x是512维,为了方便计算,子层的输出也设置为了512维 **大道至简啊!**之后调参的时候,只需要调 N N N和 d m o d e l d_{model} dmodel就可以了)
为什么用LayerNorm而不是BatchNorm?
首先,BN是对一个Batch中的列(不同样本,同一特征)做Norm,而LN是一个Batch中的行(可以简单的理解为一哥样本)做Norm。由于一个序列中,每个样本的长度很可能不一样的,所以LN更适合!
Decoder: 解码器也由N = 6个相同的层组成。除了每个编码器层中的两个子层之外,解码器还插入第三个子层,该子层对编码器堆栈的输出执行多头注意(中间的那个)。与编码器类似,我们在每个子层周围使用残余连接,然后进行Layer Norm。我们还修改了解码器堆栈中的自注意子层,以防止当前位置关注后续的位置(即当前位置不能知道后续输出位置的结果)。这种掩蔽,再加上输出embedding被一个位置偏移,确保了对位置i的预测仅依赖于小于i位置的已知输出。
An attention function可以描述为将query和一组key-value pairs映射到一个output,其中query, keys, values, and output都是向量。The output是由value的加权和计算得来,其中给每个value的权重是由query与相应key的相似度(兼容函数,compatibility function)计算得来的。
注意力机制,简单来说,在相同的多个key-value下,对应于不同的query,每个query与哪些key较近,则较近的这些key所对应的value权重就比较大,所以每个query对应的输出就不同。
3.2.1 Scaled Dot-Product Attention
We call our particular attention “Scaled Dot-Product Attention”(图 2)。 输入包括维度为 d k d_k dk 的query和key,以及维度为 d v d_v dv 的值。 我们使用所有keys来计算与query的点积,然后除以 d k \sqrt{d_k} dk,最后应用 softmax 函数来获得相应values的权重。
在实践中,我们同时计算一组queries的注意力函数,打包成矩阵 Q。键和值也一起打包成矩阵 K 和 V。我们计算输出矩阵为:
具体计算过程为:1){ n n n个 d k d_k dk维度的 Q Q Q矩阵} * { m m m个 d k d_k dk维度的 K K K矩阵} = n × m n×m n×m的相似度矩阵,其中第i行、第j列表示第i个query与第j个key的相似度;2)将此矩阵除以 d k \sqrt{d_k} dk,然后做个softmax,再乘以矩阵 V V V,就得到了每个query对应于每个value的权重(以下图片为李沐讲课中的视频截图)
两个最常用的注意力函数是additive attention [2] 和dot-product (multiplicative) attention。 除了缩放因子 1 / d k 1/\sqrt{d_k} 1/dk 之外,dot-product attention与我们的算法相同。 additive attention使用具有单个隐藏层的前馈网络计算相似度函数。 虽然两者在理论复杂度上相似,但点积注意力在实践中速度更快,空间效率更高,因为它可以使用高度优化的矩阵乘法代码来实现。
虽然对于较小的 d k d_k dk 值,这两种机制的表现相似,但在没有对较大值 d k d_k dk 进行缩放的情况下,additive attention要优于dot-product attention[3]。 我们怀疑对于较大的 d k d_k dk 值,点积的量级会变大,从而将 softmax 函数推入梯度极小的区域。 为了抵消这种影响,我们将点积缩放 d k \sqrt{d_k} dk。
在注意力计算的时候,scale后有一个mask,这一步是针对t时间的query_t做的处理,在计算出了与所有key的相似度之后,将与t时间后的key的相似度值设置为负极大值,这样进入softmax之后就会变为0,以达到当前时间t的query_t只会用到(注意到)前t步的key。
我们发现,与使用 d m o d e l d_{model} dmodel 维度的键、值和查询来执行单个注意力函数相比,将查询、键和值分别用学习到的不同线性投影器来进行h次的投影(投影至 d k , d k , d v d_k,d_k,d_v dk,dk,dv维度)是更好的。 然后,在查询、键和值的这些每一个投影版本上,我们并行执行注意力函数,产生 d v d_v dv 维的输出值。 这些输出值会被concat起来然后再次投影,从而产生最终值,如图 2 所示。
由于本身这个点积注意力没有可学的参数,所以作者先将其进行了一个线性投影至低维空间,有点像卷积网络中多个通道的感觉。
多头注意可以使模型在不同位置上共同关注来自不同表征子空间的信息。对于单个注意力头,平均可以抑制这种情况。(With a single attention head, averaging inhibits this. 不是很懂这句话在这里的意义)
在这项工作中,我们使用了 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。由于每个头部的维数减少,总的计算成本类似于具有全维的单头注意力。
3.2.3 Applications of Attention in our Model
Transformer使用多头注意在三种不同的方式:
Attention所做的事就是有效的将编码器中的输出,把想要的东西拎出来。
除了注意子层之外,我们的编码器和解码器中的每一层都包含一个全连接的前馈网络,它分别和相同地应用于每个位置(该网络对每个单词都作用了一次,这也是它为什么叫point-wise)。这包括两个线性转换,其中一个是ReLU激活(实际上就是MLP)。
虽然不同位置的线性变换是相同的,但它们在层与层之间使用不同的参数。 另一种描述方式是kernel size为 1 的两个卷积。输入和输出的维数为 d m o d e l = 512 d_{model}=512 dmodel=512,内层的维数为 d f f = 2048 d_{ff}=2048 dff=2048。
这里是先使用W_1将x映射到了2048维,然后用W_2映射到了512维。
与其他序列转导模型类似,我们使用学习embedding将输入tokens和输出tokens转换为维度 d m o d e l d_{model} dmodel 的向量。 我们还使用通常的学习到的线性变换和 softmax 函数将解码器输出转换为预测的下一个token概率。 在我们的模型中,我们在两个embedding层和最后的 softmax 之前的线性变换linear之间共享相同的权重矩阵,类似于 [24]。 在嵌入层中,我们将这些权重乘以 d m o d e l \sqrt{d_{model}} dmodel(这里与后面的位置编码有关,加上这个可以将每个token scale到差不多相同的维度,,没太看懂)。
embedding就是将任何一个词,学习到一个长度为d的向量来表示他。
由于我们的模型不包含递归和卷积,为了让模型利用序列的顺序,我们必须注入一些关于token在序列中的相对或绝对位置的信息。 为此,我们将“positional encodings”(位置编码)添加到编码器和解码器堆栈底部的输入嵌入中。 位置编码与嵌入具有相同的维度 d m o d e l d_{model} dmodel,因此可以将两者相加。 位置编码有多种选择,学习的或固定好的 [8]。
在这项工作中,我们使用了不同频率的正弦和余弦函数:
其中 pos 是位置,i 是维度。 也就是说,位置编码的每个维度对应一个正弦曲线。 波长形成从2π到10000·2π的几何级数。 选择这个函数是因为我们假设它可以让模型通过相对的位置很容易地学习到,对于任何固定的偏移量 k, P E p o s + k PE_{pos+k} PEpos+k 可以表示为 P E p o s PE_{pos} PEpos 的线性函数。
我们还尝试使用学习位置嵌入[8]来代替,并发现两个版本产生了几乎相同的结果(参见表3 行(E))。我们选择正弦版本是因为它可以让模型预测出比在训练中遇到的序列长度更长的序列。
Self-Attention (restricted) 就是算r个邻居的相似度,而不是全部算n个
在本节中,我们将自注意力层的各个方面与通常用于将一个可变长度的符号表示序列 ( x 1 , . . . , x n ) (x_1, ..., x_n) (x1,...,xn) 映射到另一个等长序列 ( z 1 , . . . , z n ) (z_1, ..., z_n) (z1,...,zn) 的循环层和卷积层进行比较,其中 x i , z i ∈ R d x_i, z_i∈\R^d xi,zi∈Rd,如典型序列转导编码器或解码器中的隐藏层。 为了更有动力的使用自我注意,我们考虑了三个需求。
一个是每一层的总计算复杂度。另一个是可以并行化的计算量,通过所需的最小顺序操作数来度量。
第三个是网络中远程依赖项之间的路径长度( 获取较远信息的代价 )。在许多序列转导任务中,学习远程依赖是一个关键的挑战。影响学习这种依赖关系能力的一个关键因素是向前和向后信号在网络中必须经过的路径长度。输入和输出序列中的任何位置组合之间的这些路径越短,就越容易了解远程依赖项[11]。因此,我们还比较了由不同层类型组成的网络中任意两个输入和输出位置之间的最大路径长度。
如表 1 所示,自注意力层将所有位置连接到具有恒定数量的顺序执行操作,而循环层需要 O(n) 顺序操作。 在计算复杂度方面,当序列长度 n 小于表示维数 d 时,自注意力层比循环层更快,这是机器翻译中最先进模型使用的句子表示的最常见情况 ( 现在由于大数据量,n和d差别不多了 ),例如word-piece [31] 和byte-pair [25] 表示。 为了提高涉及非常长序列的任务的计算性能,可以将自注意力限制为仅考虑输入序列中以相应输出位置为中心的大小为 r 的邻域。 这会将最大路径长度增加到 O(n/r)。 我们计划在未来的工作中进一步研究这种方法。( 这个不常用 )
kernel width k
作为附带利益,自我关注可以产生更多可解释的模型。我们从模型中检查注意力分布,并在附录中提出和讨论例子。单个注意力头不仅清楚地学会了执行不同的任务,许多似乎还表现出与句子的句法和语义结构相关的行为。
使用Self-Attention看起来计算量也不算多,信息融合的比较好,但是这代表着其需要更多的数据与更长的训练来达到与RNN和CNN同样的效果。
本节描述我们的模型的训练机制。
我们使用标准的2014年WMT英德数据库进行训练,该数据库包含大约450万对句子。句子是用byte-pair encoding[3]编码的,它有一个大约37000个token的共享源目标词汇表。对于英法两种语言,我们使用了更大的WMT 2014英法数据集,该数据集包含36M个句子,并将token拆分为32000个word-piece词汇[31]。句子对由近似的序列长度组合在一起。每个训练批包含一组句子对,其中包含大约25000个源token和25000个目标token。
byte-pair encoding指的是把单词的词根提取出来(即一个单词可能有多种语态形式,这里只用了词根作为一个有效的token)
我们在一台拥有8个NVIDIA P100 gpu的机器上训练我们的模型。对于使用本文中描述的超参数的基本模型,每个训练步骤大约需要0.4秒。我们训练了基础模型总共10万步或12个小时。对于我们的大型模型(在表3的底部描述),步长时间为1.0秒。大模型训练了30万步(3.5天)。
我们使用了 Adam 优化器 [17],其中 β 1 = 0.9 β_1= 0.9 β1=0.9, β 2 = 0.98 β_2= 0.98 β2=0.98 和 ϵ = 1 0 − 9 \epsilon = 10^{−9} ϵ=10−9。 我们根据以下公式在训练过程中改变学习率:
这对应于在第一个warmup_step 训练步骤中线性增加学习率,然后与步数的平方根成反比地减少它。 我们使用了warmup_steps= 4000。
我们在训练过程中采用了三种类型的正规化:
Residual Dropout 我们将dropout[27]应用于每个子层的输出,然后将它添加到子层的输入并正则化。此外,我们将dropout应用于编码器和解码器栈的embedding与位置编码的sum。对于基本模型,我们使用 P d r o p = 0.1 P_{drop}= 0.1 Pdrop=0.1的比率。
Label Smoothing 在训练过程中,我们使用了标签平滑 ϵ l s = 0.1 \epsilon_{ls} = 0.1 ϵls=0.1[30]( 这里指的是softmax值大于0.1就可以充当预测结果了 )。这让人感到困惑,因为模型具有了更多的不确定性,但提高了准确性和BLEU分数。
可以改的参数基本也就是 N 、 d m o d e l 、 h N、d_{model}、h N、dmodel、h,其他的可以对应换算出来,这极大的方便了后续人的研究工作。
Train steps就是训练了多少个batch
在表 3 的行 (B) 中,我们观察到减少注意力key大小 d k d_k dk 会损害模型质量。 这表明确定兼容性并不容易,并且比点积更复杂的兼容性函数可能是有益的。 我们在行 © 和 (D) 中进一步观察到,正如预期的那样,更大的模型更好,并且 dropout 非常有助于避免过度拟合。 在行 (E) 中,我们用学习的位置嵌入 [8] 替换了我们的正弦位置编码,并观察到与基本模型几乎相同的结果。
在这项工作中,我们提出了Transformer,第一个完全基于attention的序列转导模型,用多头自我注意取代了编码器-解码器体系结构中最常用的recurrent layers。
我们对基于注意力的模型的未来感到兴奋,并计划将它们应用于其他任务。我们计划将Transformer扩展到涉及文本以外的输入和输出形式的问题,并研究局部的限制性注意机制,以有效地处理图像、音频和视频等大型输入和输出。我们的另一个研究目标是让下一代不那么连续。 ( 属于是预言家了,现在感觉Transformer哪都能用,太了 )