想研究BERT模型?先看看这篇文章吧!

最近,笔者想研究BERT模型,然而发现想弄懂BERT模型,还得先了解Transformer。
本文尽可能贴合Transformer的原论文,但考虑到要易于理解,因此并不是逐句翻译,而是根据笔者的我的理解进行翻译,其中有一些论文没有解释清楚或者笔者未能深刻理解的地方,都有放出原文,若有不当之处,请各位多多包含,并但愿获得指导和纠正。git

论文标题

  • Attention Is ALL You Need

论文地址

摘要

序列转换方式由基于复杂递归神经网络(RNN)和卷积神经网络(CNN)的编码器和解码器模型主导。表现最佳的模型也只是经过一个注意力机制来链接了编码器和解码器。咱们提出一个新的简单网络架构——Transformer。相比表现最佳的模型,该架构仅仅基于注意力机制,彻底摒弃了递归和卷积。从两个机器翻译任务的实验结果显示,Transformer的效果更优秀,同时有更好的并行性,显著的减小了训练的时间。咱们的模型在WMT2014年发布的“英-德”翻译任务上达到了28.4 BLEU【注解1】,超越了该任务上现有的最好的记录2个BLEU,包括整体效果。在英-法翻译任务上,咱们的模型在8块GPU上训练了3.5天,并创造了单模型最好BLEU分数——41.8。相比文献中的最佳模型,这个训练成本不高。Transformer在其它任务上也有好的泛化能力,咱们将其应用于English constituency parsing(英语成分句法分析),不管在大量的训练数据上仍是有限的训练数据上都得到了成功。github

1 引言

RNN,LSTM和GRNN已是序列建模、语言建模、机器翻译领域公认的最好方法。以后,仍然有不少人努力推动循环语言模型(recurrent language models)和encoder-decoder架构的边界。算法

循环模型(RNN)一般将输入和输出序列的符号的位置做为因素进行计算。将位置与计算时间步对齐的过程当中,会根据前一个隐藏状态ht-1和位置t的输入来生成一系列的隐藏状态ht【注解2】。这种固有的相继的性质使得训练样本没法并行训练,这个问题在面对更长序列,而且内存不足以提供更大的批训练的时候尤为关键。近期,人们经过因式分解(factorization)技巧和条件计算(conditional computation),改善了计算效率(后者同时提升了模型的表现)。然而,固有的相继的性质尚未获得解决。网络

注意力机制在各类序列建模和转换模型的任务中,已经成为不可分割的部分。它使得能够在对符合间的依存关系进行建模的时候,不考虑符号间的距离。然而,大多数状况下,这样的注意力机制是和RNN一块儿使用的。架构

此处,咱们提出Transformer,该模型架构摒弃了循环,而采用彻底依赖注意力机制来绘制输入和输出之间的全局依存关系的方式。Transformer模型有着更好的并行性,在翻译质量上达到了新的高度,而这样的Transformer模型在8块P100GPU上训练仅须要12小时。app

2 背景

减小循序计算(sequential computation)的目标也构成了Extended Neural GPU,ByteNet和ConvS2S的基础,这些都使用CNN做为基础构建块,为全部输入和输出的位置并行的计算隐藏表征。对于这些模型,从2个任意的输入或输出位置关联信号所须要的操做次数会随着位置之间的距离的增长而增长,在ConvS2S中是线性增长,在ByteNet中是对数增长。这使得在两个远距离的位置间的依存关系的学习变得更加困难。在Transformer中,这个问题减轻为一个常量次数的操做,这当然会由于通过平均注意力加权的位置而下降有效的信息分辨率,咱们应对的策略是采用Multi-Head Attention来抵消这个问题。(大体的理解:注意力机制虽然将序列操做次数固定为一个常量,但自己会丢失一些位置信息,经过Multi-Head 的方式能够弥补这个问题)less

Self-attention,有时候又称为intra-attention,是一种关联单一序列的不一样位置的注意力机制,为了计算该序列的表征。Self-attention 已经被用在各类任务上,包括阅读理解,抽象式摘要,文本蕴含(textual entailment),学习独立于任务的句子表征。函数

端到端的记忆网络是基于一个循环的注意力机制,而不是按序列对齐(sequence-aligned)的序列循环,而且在简单语言问答和语言建模任务上表现的不错。性能

然而,据咱们所知,Transformer是第一个彻底依赖self-attention来计算输入和输出表征的转换模型,它没有使用序列对齐(sequence-aligned)的RNN或者卷积。下面的章节咱们将对Transformer进行阐述,进一步讨论self-attention的优点。学习

3 模型架构

大多数有竞争力的神经序列转换模型都有一个encoder-decoder结构。这里,编码器将一个用符号(通常是向量)表示的输入序列(x1,...,xn)映射到一个连续的表征序列z=(z1,...,zn)。解码器拿到z后,生成一个符号表示的输出序列(y1,...,yn),这里是每一个时间步生成一个yi,i表示从1到n任意一个数字。每一步,模型都自动消费前一步生成的符号,好比生成y2的时候会以y1做为额外的输入。

Transformer使用堆叠的self-attention层和明确的指向性来遵循上面这个架构,图1的左半部分和右半部分分别展出了编码器和解码器的完整链接。

3.1 堆叠的编码器和解码器

编码器: 编码器由6个相同的层堆叠而成。每一层包含2个子层。第一个子层是multi-head self-attention 机制,第二个子层是一个简单的,位置分明的全链接前馈网络。咱们在每一个子层都使用了一个残差链接(residual connection)【注解3】,并跟上一个归一化层(normalization layer)。也就是说,每一个子层的输出是LayerNorm(x + Sublayer(x)),其中的Sublayer(x)表示各子层本身实现的函数,好比self-attention层有本身的一套实现,而feed-forward层也有本身的实现。为了方便使用这些残差连接,全部子层包括词嵌入层的输出维数都为512。这里由于残差链接会用到矩阵加法,因此要保持维数统一,至于为何是512,估计是应为选择了维数是512的词嵌入向量。具体参考下图:

解码器: 解码器也是由6个相同的层堆叠而成。每一层除了和编码器那样有两个子层外,解码器插入了第三个子层,用于在编码器最后的输出上执行multi-head attention。和编码器同样,咱们也在解码器的各子层中引入了残差链接,并跟上一个归一化层。咱们还修改了解码器的self-attention子层,来防止其将注意力扩散到当前处理位置的后续的位置上。笔者理解这里的意思是,编码器的self-attention子层的注意力机制是关联到当前处理词和其余词的,由于输入的序列的全部词都是明确的,而解码器的self-attention子层只关联到当前处理词以前的词,由于当前处理词还没预测出来,以后的词固然更还没预测出来。因此解码器的self-attention子层的当前处理位置的后续位置都是用-inf来标识的,又称之为mask。这里放上论文中本段落最后的原文:This masking, combined with fact that the output embeddings are offset by one position, ensures that the predictions for position i can depend only on the known outputs at positions less than i.这样应该比较好理解了。

3.2 注意力(Attention)

注意力函数能够描述为将一个查询(query)和一组键值对(key-value)映射到一个输出(output),这里的query,keys,values和output都是向量。output是经过values的加权求和来计算的,这里的权重是经过一个query和对应的key的兼容函数来计算的。

3.2.1 Scaled Dot-Product Attention

咱们称咱们特殊的attention为“Scaled Dot-Product Attention”(下图左)。

其输入由dk维数的queries和keys以及dv维数的values构成。
咱们计算query和全部keys的点积,而后除以dk的平方根,而后经过一个softmax函数,其输出就是values的权重。

实际上,咱们是在一组queries上同时计算注意力(attention),具体是将queries打包到一个矩阵Q中。keys和values也是分别打包到K和V矩阵中。咱们进行矩阵计算的输出公式以下:

两个最经常使用的attention 函数是additive attention和dot-product(multiplicative)attention。Dot-product attention和咱们的算法同样,除了咱们的算法多了一个缩放因子1/(dk的平方根)。Additive attention计算使用一个feed-forward 网络,该网络仅有一个隐藏层。两个算法在理论上具备相同的复杂度,然而,实践中,dot-product attention更快而且更省空间,由于它能够利用到高度优化的矩阵乘法代码。

虽然在dk不大的时候,这两个算法的执行是效率是类似的,可是对于较大的dk值,additive attention 优于不带缩放的dot-product attention算法。咱们猜测dk越大,点积的量级也会增加【注解4】,这会将softmax函数值推向很是小的梯度所在的区域,为了弥补这点,咱们才引入缩放因子1/(dk的平方根),将其与点积相乘【注解5】。

3.2.2 Multi-Head Attention

咱们发现,相比使用keys,values和queries执行一个单一的注意力函数,线性投影h次不一样的keys,values和queries,分别学习到dk,dk,dv维数上的线性投影会更有优点。(原句:Instead of performing a single attention function with dmodel-dimensional keys, values and queries, we found it beneficial to linearly project the queries, keys and values h times with different, learned linear projections to dk, dk and dv dimensions, respectively。) 每个queries,keys,values的投影版本上,咱们并行的执行注意力函数,而后各自获得一个dv维数的输出值。而后将这些输出值(其实就是h个矩阵)拼接(concatenated)起来,在作一次投影【注释6】,获得最后的结果,就像图2的右半部分展现的那样。

Multi-head attention让模型能够连带注意到不一样位置上的来自不一样表征子空间的信息。用一个attention head,会抑制这种能力。
(原句:Multi-head attention allows the model to jointly attend to information from different representation subspaces at different positions.With a single attention head, averaging inhibits this.)


这里介绍了公式中矩阵W的含义和形状。笔者的理解是全部出现的W都是一种投影矩阵。

此处,咱们采用h=8个并行attention层,或称为头。对于每一层咱们使用dk=dv=dmodel/h = 64。这里dmodel是指词嵌入向量的维数,能够推出其值为64* 8=512。因为每一个头减小了维数,总计算成本和用一个采用完整维数的attention头是差很少的。

3.2.3 Attention在咱们的模型中的应用

Transformer 以三种不一样的方式使用multi-head attention :

  • 在“encoder-decoder attention”层,queries来自前一个decoder层,keys和values来自encoder的输出。这使得decoder的每一个位置可以考虑到输入序列的全部位置。这模拟了sequence-to-sequence模型中采用的经典的encoder-decoder注意力机制。
  • encoder包含self-attention层。在一个self-attention层,全部的keys,values和queries来自相同的地方,这里是来自encoder的前一层的输出。当前encoder层的每一个位置均可以关注到前一层encoder的全部位置。
  • 相似的,decoder中的self-attention层容许decoder层每一个位置关注到decoder层的全部位置,包括当前位置。为了保证自回归性(auto-regressive property)【注解 8】,咱们须要阻止解码器中向左的信息流动。咱们在点积注意力算法内部实现了这一点,具体是经过屏蔽(set to -∞)softmax层的输入中的全部符合非法链接的值来实现的,见图2左。(笔者的理解就是将当前decoder中self-attention层当前处理词的后面的位置设置为负无穷大)。

3.3 Position-wise Feed-Forward Networks 位置前馈网络

除了attention子层外,每一个编码器和解码器层还包含一个全链接前馈网络,该网络以相同的状态分别应用于每一个位置。该网络由两个线性变换构成,在这两个变换中间有一个ReLU激活。公式表达以下:

虽然不一样的位置作的是同样的线性变换,可是不一样的层使用了不一样的参数。另外一个描述这个的方法是就像使用了size为1的卷积核作了2次卷积。该网络的输入和输出的维数都是512,内部层的维数dff = 2048。(这里做者没有详细解释,因此笔者也不太肯定,貌似是说这里利用1* 1的卷积核作了一次升维和一次降维。)
附上原句:

3.4 Embeddings and Softmax

和其余的序列转换模型类似,咱们使用通过学习的词嵌入模型来将输入词和输出词转换成dmodel维数的向量。咱们也使用通过学习的线性变换和softmax函数来转换decoder输出为预测的下一个词的几率。在咱们的模型中,咱们在2个embedding层和softmax前的线性变换层共享相同的权重矩阵 。在embedding层,咱们会将权重乘以dmodel的平方根。

3.5 Positional Encoding 位置编码

既然咱们的模型没有包含循环(recurrence)和卷积(convolution),为了让模型肯定序列的顺序,咱们必须给模型注入序列中各个词的相对或绝对的位置信息。为此,咱们将encoder和decoder栈的底层的embeddings分别与一个“positional encodings”作加法 。positional encodings和embeddings具备相同的维数,以便执行相加操做。有许多作positional encodings的方法,包括通过学习的方式和固定的方式。

此处,咱们使用不一样频率的sine和cosine函数:

这里pos是词在句子中的位置,好比句子长度是L,则pos=0,1,2,3,...,L-1。
i是positional encoding向量的某一维度,positional encoding向量的维数=dmodel,因此当dmodel维数=512时,i=0,1,...,255。
也就是说,每一个positional encoding的维度对应一个正弦曲线(具体说是每一个偶数维对应一个正弦曲线,每一个奇数维对应一个余弦曲线)。
每一个维度对应的曲线的波长的取值范围能够是一个从2Π到10000* 2Π的等比数列。
咱们选择这个函数,是由于咱们猜想,既然对任意固定的偏移量k,PEpos+k都能用PEpos的线性函数来表示,那么这可让模型更容易经过相对位置来学习注意力。

注:要理解上面这句话需先回顾一下三角函数的"和角"公式:

这里,能够把α看做pos位置,把β看做k位置,则α+β能够当作是位置pos+k,因为PE(pos,2i)和PE(pos,2i+1)公式分别是用的sin和cos,因此PE公式也知足这个和角公式。则能够获得以下推导:

由此公式能够看出,对任意固定的偏移量k,PEpos+k确实都能用PEpos的线性函数来表示。
至于为何这样能够表示相对位置信息,若是把上面的公式当作当计算pos和pos+k的位置编码维度(2i)时,公式表示(2i)和(2i+1)的线性加权求和;当计算pos和pos+k的位置编码(2i+1)时,公式表示(2i+1)和(2i)的线性加权求和,也就是说位置编码就是(2i)与(2i+1)的线性变换。因此能够表示相对位置信息就比较好理解了。

另外,做者也实验了使用通过学习的位置嵌入来代替上面的方案,而后发现这两个方案产生了几乎相同的结果。做者选择正弦曲线方案是由于即便序列的长度比训练期间的任何序列的长度长,模型也可以支持对该序列的推测(extrapolate)。

能够在下面的函数中查看生成positional encoding的代码:
get_timing_signal_1d

更贴合论文公式的代码实现以下:

4 为何使用Self-Attention

本节咱们从各个方面比较self-attention和recurrent、convolutional层,recurrent和convolutional层一般用来作不定长度的符号表征序列
(x1, ..., xn)到另外一个相同长度的序列( (z1, ..., zn))的映射,诸如一个典型的序列转换编码器或解码器中的隐藏层。让咱们更想选择self-attention的缘由有三个。

第一个是每层总的计算复杂度。第二个是能够并行计算的数量,经过须要的序列操做的最小次数来度量。
第三个是网络中远距离依存的路径长度。在许多序列转换任务中,远距离依存的学习都是一个关键挑战。影响这种能力的关键因素是前向和反向信号在网络中须要通过的的路径长度。输入和输出序列中,任意位置的组合间的路径越短,越容易学习到远距离依存关系。所以咱们也比较了不一样类型的层的任意两个输入和输出中的位置的最大路径长度。以下图:

图中所示,self-attention层用一个恒定的循序执行操做的次数来链接全部的位置,而recurrent层须要O(n)复杂度的循序操做。从计算复杂度来看,当序列的长度n比表征维数d小的时候,self-attention层比recurrent层更快,这种状况在最好的机器翻译模型使用的表征例子中是常见的,好比word-piece和byte-pair表征。为了改善涉及很长序列任务的计算性能,能够限制self-attention只考虑输入序列中以各自的输出位置为中心的一个大小为r的邻域。(笔者注:应该是相对默认的self-attention机制会考虑全部的输入的位置来讲的)这会增长最大路径长度为O(n/r)。咱们计划在未来的工做中进一步研究这种方法。

一个单一的卷积层,使用k<n大小的卷积核,不能链接全部的输入和输出位置对。...
这段主要是讲采用卷积层的代价比recurrent和self-attention层都大,具体细节能够自行参考原文,因为笔者未能所有理解,就不翻译了。

self-attention有附加的优点,就是模型的可解释性更强。咱们从模型中观察注意力分布,并在附录中呈现和讨论了一个示例。单个注意力头不只清晰的学会了执行不一样的任务,还呈现出许多和句子的语义结构、句法有关的行为。

5 Training 训练

本节描述模型的训练机制。

5.1 Training Data and Batching

咱们在标准的WMT 2014 English-German数据集上训练,其包含450w句子对。句子用包含37000个词的原目标词汇表的byte-pair encoding来编码。对于English-French,咱们使用大的多的WMT 2014 English-French数据集,其由3600万个句子组成,并将单词分割成32000个不一样单词组成的词汇表。句子对按照相近序列长度进行批次划分。每一个训练批次包含一组含有接近25000原始单词(source tokens)和25000目标单词(target tokens)的句子对。

5.2 Hardware and Schedule

咱们在8块NVIDIA P100 GPU上训练咱们的模型。咱们的基础模型使用了本论文描述的超参数,每一个训练步耗时0.4秒。咱们训练基础模型用了总共100000步,花费12小时。对于咱们的大型模型,(table3的最后一行有描述),每步耗时1秒。大型模型训练了300000步,耗时3.5天。

5.3 Optimizer 优化器

咱们使用Adam优化器,采用β1 = 0.9, β2 = 0.98 and epsilon= 10−9 。咱们根据以下公式随着训练过程而改变学习率:

这里,咱们在首个warmup_step训练步线性增长学习率,而后按照step_num平方根的倒数成比例下降学习率。咱们设置warmup_steps=4000。

5.4 Regularization 正则化

咱们在训练期间采用了三种正则化方法。

Residual Dropout 咱们在每一个子层的输出加入下一个子层的输入和归一化以前上应用了dropout。
(原句:We apply dropout [33] to the output of each sub-layer, before it is added to the sub-layer input and normalized.)
另外,咱们在encoder和decoder栈的embeddings和positional encodings相加后,应用了dropout。对于基础模型,咱们使用的比率Pdrop = 0.1。

Label Smoothing 在训练期间,咱们采用label smoothing,值以下:

这使得模型学到了更多的不肯定因素,可是改善了准确度和BLEU得分。

6 Results

6.1 Machine Translation 机器翻译

在 WMT 2014 English-German 翻译任务上,大型transformer模型(Transformer(big) in Table 2) 赛过以前最好的模型(包括 ensembles)2.0个BLEU,创造了新的BLEU分数记录——28.4。这个模型的配置在Table3的末行有展现。训练在8块P100GPU上耗时3.5天。甚至咱们的基础模型也优于全部先前发布的模型和集成(ensembles),而且训练成本比其余任何模型的成本都低。

在 WMT 2014 English-to-French 翻译任务上,咱们的大型模型达到了41.0的BLEU分数,赛过全部发布的单个模型,而且只使用了最好模型的1/4的训练成本。Transformer(big) 在训练English-to-French的时候使用了Pdrop = 0.1的dropout rate(失活率),而不是0.3。

下面这段,笔者也有不明白的地方,笔者会尝试解释,可是未必准确,因此放出原句:
For the base models, we used a single model obtained by averaging the last 5 checkpoints, which were written at 10-minute intervals. For the big models, we averaged the last 20 checkpoints. We used beam search with a beam size of 4 and length penalty α = 0.6 [38]. These hyperparameters were chosen after experimentation on the development set. We set the maximum output length during inference to input length + 50, but terminate early when possible [38].

对于基础模型,咱们使用一个单一的从最新的5个训练检查点平均求出的模型,这些检查点的写入间隔是10分钟。对于大型models,咱们用的是最新的20个检查点。咱们使用beam search算法,beam的大小=4,长度的惩罚系数α = 0.6 。这些超参数是在开发集上实验以后得出的。咱们设置推理过程当中的最大的输出长度为输入长度+50,可是会在能够终止的时候尽早终止。(笔者注:不明白为何这么作。)

Table 2 中比较了咱们的模型和其余模型架构的表现,包括翻译质量和训练成本。咱们经过乘以训练时间,GPU的使用数量,以及对各GPU持续单精度浮点容量的估计(咱们对K80, K40, M40 and P100型号的GPU分别使用 2.8, 3.7, 6.0 和 9.5 TFLOPS , respectively),来评估用于训练模型的浮点运算的数量。

6.2 Model Variations

为了评估Transformer不一样部分的重要性,咱们将基础模型进行不一样方式的变化,以此度量在开发集和测试集上模型表现的改变。咱们使用beam search算法(和上节提到的同样,可是没有对检查点取平均)。咱们在Table 3中呈现了这些。

在Table 3的A行,咱们改变attention heads的数量,以及attention key和value的维数,以此保持总计算量的不变,就像3.2.2小节中描述的那样。虽然单头注意力比最佳设置(8个头)差0.9个BLEU,但过多的头也会下降质量。

在Table 3的B行,咱们观察到,较小k的维数,会下降模型的表现。这暗示着肯定兼容性并不容易,并且一个比点积更复杂的兼容性函数多是有益的。咱们进一步观察C行和D行,如预料的那样,大型模型更好,dropout对避免过拟合很是有用。在E行,咱们用通过学习的位置嵌入方式来代替正弦曲线位置编码的方式,对于基础模型来讲效果几乎是同样的。

6.3 English Constituency Parsing 英语成分解析

为了评估Transformer是否能够泛化到其余任务上,咱们在English constituency parsing上作了实验。此任务有着特别的挑战:输出受强结构约束,而且比输入长的多。此外,基于RNN的sequence-to-sequence的模型尚未在小数据集上达到过最早进的结果。

咱们在Wall Street Journal (WSJ) portion of the Penn Treebank数据集上训练了一个4层的transformer,维数dmodel =1024,大概有40K个训练句子。咱们还在半监督的环境中对其进行了训练,使用了更大的高置信度和BerkleyParser语料库,语料库中有大约1700万句话。咱们在WSJ only 设置中使用了包含16K个惟一单词的词汇表,在半监督设置中使用了32K个惟一单词的词汇表。

咱们只用了少许的实验来选择droput,不管是attention、residual、学习率、beam size 都是如此,全部其余剩余的参数和English-to-German的基础翻译模型的同样。在推理阶段,咱们增长了最大输出长度为输入的长度+300。对于WSj only 和半监督设置,咱们使用beam size=21,α = 0.3。

Table 4 显示,尽管咱们的模型缺乏特定任务的调优,其仍然执行的很是好,除了Recurrent Neural Network Grammar(
Dyer等人提出)之外,比其余模型都好。

与RNN序列到序列模型相比,即便只在 WSJ 的40K句训练集上进行训练,Transformer的性能也优于BerkeleyParser[29]。

7 总结

在本次工做中,咱们展现了Transformer,首个彻底依赖注意力机制的序列转化模型,用multi-headed self-attention替换了encoder-decoder架构中经常使用的recurrent层。

在翻译任务中,Transformer 的训练比基于recurrent或convolutional层的架构的模型都要快的多。在WMT 2014 English-to-German 和 WMT 2014 English-to-French 翻译任务上,咱们创造了新的记录。在前一个任务中,咱们的最佳模型甚至优于全部先前报告的模型的集成。

咱们对基于注意力的模型的将来感到兴奋,并计划将其应用于其余任务。咱们计划将Transformer扩展到涉及文本之外的输入和输出模式的问题上,并研究局部的、受限的注意机制,以便有效地处理大量输入和输出,如图像、音频和视频。Making generation less sequential is another research goals of ours。(注:这句没翻译,是由于不知道“Making generation less sequential ”具体是指什么。)

咱们用于训练和评估咱们模型的代码可经过这个地址获取: https://github.com/ tensorflow/tensor2tensor

致谢 咱们感谢Nal Kalchbrenner和Stephan Gouws富有成效的评论、纠正和启发。

参考文献

请从原论文末尾查找。

Attention Visualizations 注意力可视化


图3:能够看到,在编码making的时候,注意力的关注状况。上面的图只将making的注意力展现出来了。颜色越深的头注意力越集中。


图4:Top: head 5的完整注意力。Bottom: 仅是从head 5 和head 6中剥离出来的对单词‘its’的注意力。


图5:许多注意力头表现出的行为看起来都和句子的结构有些关系。咱们给出了2个例子,来自编码器中不一样的注意力头。注意力头显然学会了执行不一样的任务。

注解

  1. BLEU:全称 bilingual evaluation understudy。是一种使用机器代替人工评估翻译结果好坏的方法。评估思路是将模型翻译的結果和一组人工翻译的结果进行比较得出一个综合分数,分数越高的模型越好。
  2. ht: 第t个时间步的激活值,若是不理解,请先了解神经网络结构中的激活函数。
  3. residual connection: 残差链接.引入残差链接,通常是为了不梯度爆炸和弥散问题,这里估计也是为了解决这个问题。
  4. 为何维数越大,点积越大?看下面的公式,其中dk是维数,q·k是点积 :

    根据图中的公式,直觉上以为dk越大q·k就越大是显然的,然而,论文中做者对此的解释提到了均值和方差,这里笔者还没能弄明白为何要经过均值和方差来讲明点积会随着维数的增长而增长。
    原句以下:

  5. 要理解“咱们猜测dk越大,点积的量级也会增加,这会将softmax函数值推向很是小的梯度所在的区域,为了弥补这点,咱们才引入缩放因子1/(dk的平方根),将其与点积相乘”这句话,须要看下面三个图:



    x轴显示的是输入的向量中的各个份量,y轴表示输入的向量中的各个份量对应的softmax的输出。
    笔者将第一幅图的输入向量的各个份量设置为从0到19,步长为1,则输入维数为20,;第二幅图的输入向量的各个份量增大到从0到59,步长为3,则输入维数一样是20。对比两幅图,明显第二幅图中有更多的梯度很是小的区域。而在深度学习神经网络中,咱们知道很是小的梯度将致使很是慢的学习速度。因此做者引入了一个缩放因子,那么第三幅图就是笔者将第二幅图的输入除以其维数的平方根后的图,能够看到落在很是小的梯度的区域的值变少了。
    绘制曲线的代码以下,你们能够自行调整参数以作测试:

import matplotlib.pyplot as plt
import numpy as np

def softmax(inputs):
    return np.exp(inputs) / float(sum(np.exp(inputs)))

def line_graph(x, y, x_title, y_title):
    plt.plot(x, y, markerfacecolor='blue',marker='o')
    plt.xlabel(x_title)
    plt.ylabel(y_title)
    plt.show()

# graph_x = range(0, 20) #数值小的时候
graph_x = range(0, 60,3) # 维数相同,数值大的时候
print(len(graph_x))
graph_x = np.array(graph_x)/(float(len(graph_x)) ** 0.5) # 加入缩放因子
graph_y = softmax(graph_x)
print("GraphXreadings: {}".format(graph_x))
print("GraphYreadings: {}".format(graph_y))
line_graph(graph_x, graph_y, "Inputs", "SoftmaxScores")
  1. projected: 投影。具体的操做是用当前矩阵乘以另外一个矩阵,另外一个矩阵一般就是一个权重矩阵,其中的值一开始是随机初始化的,而后经过不断的学习获得合适的值。

  2. Auto-regressive : 简称AR,核心思想是: 下一个观测值约等于前n个观测值的某种线性加权和。因此做者须要将decoder中上一个预测词的左向信息流给 mask 掉(即右侧全部位置的值设置为负无穷)。

笔者总结

ok,终于翻译完成了。让咱们来回顾一下论文做者的思路以作个总结。
本论文中,做者提出了Transformer模型架构,该架构用在序列到序列的转换领域,好比机器翻译,能够是语言到语言的翻译,也能够是任何序列到另外一个序列的转换。

Transformer中用到了一种注意力机制,直观上理解就是在编码句子中的某个词的时候,会同时注意句子中的"其余词","其余词"中各个词越和当前词相关,获得的注意力越多。

Transformer利用这种注意力机制来给相关词打分,来获得最终的输出,而后经过训练样本集和相应的损失函数不断更新网络的权重系数来获得一个有效的序列到序列转换的模型。
也就是说,训练好的模型会知道如何将一个句子序列映射到另外一个句子序列,好比英文到中文的翻译。

在这个过程当中,做者提出了query,key,value的概念,注意力分数就是用这三个概念参与计算出来的,其中还用到了query和key的点积。而这三个概念做者只用了一段话描述:”注意力函数能够描述为将一个查询(query)和一组键值对(key-value)映射到一个输出(output),这里的query,keys,values和output都是向量。output是经过values的加权求和来计算的,这里的权重是经过一个query和对应的key的兼容函数来计算的。“。
笔者的尝试直观的解释一下(不必定准确,仅做参考,请大佬指正。),就是做者把
query看成当前词的词嵌入向量在某个注意力空间的投影;
key 看成句子中全部词在注意力空间上的键投影;
value看成句子中全部词在注意力空间上的值投影。
而编码器中query和key作点积,就是为了找到注意力空间中其余词和当前编码词的注意力相关性,这些相关性将做为value的权重,也就是其余词对当前编码词的注意力集中度。
解码器中的query和编码器的key作点积,是为了在计算注意力的时候再加入对已经解码的词的考量。
为了让模型在注意力上考虑的更全面,做者使用了8个注意力头,也就是计算了8次上面涉及q,k,v的过程,而后将结果拼接在一块儿。
可是这个过程并无考虑到句子中词和词之间的位置关系,因此为了弥补,做者引入了positional encoding,就是要让Transormer可以考虑到位置信息。不至于打乱一个句子的词汇后,获得的转换结果和没打乱同样。

相比基于注意力机制的循环或卷积的架构模型,Transformer的显著特色是其彻底依赖注意力机制,而摒弃了循环和卷积。由此获得的好处包括:计算复杂度下降了,并行计算的数量增长了,句子中任意两个词离得越远,越不容易学习其依存关系的问题被减轻了。

若是你仍是隐隐以为不能彻底搞懂论文的全部思想也没关系,由于论文自己确实比较难读懂,毕竟是论文,不是教学为目的。可是至少经过本文,你应该大体明白了论文在讨论什么,其提出的attention机制是为了解决什么问题。

ok,本篇就这么多内容啦~,感谢阅读O(∩_∩)O,88~

相关文章
相关标签/搜索