题目: Attention Is All You Need
主要作者: Ashish Vaswani,Noam Shazeer
主要机构: Google Brain,Google Research
发表时间: 2017年
1. 要解决什么问题?
基于RNN/CNN的Encoder-Decoder或者RNN带Attention的Encoder-Decoder不能并行计算或者并行计算的复杂度会随着输入输出距离的增加而大幅度增加,以及RNN带来的长序列依赖问题。
2. 用了什么方法解决?
提出了Transformer,仅依赖于Attention机制的Encoder-Decoder。(但是并行计算只有在Encoders中,Decoder还是类似循环网络的结构)
3. 效果如何?
在 WMT 2014 English-to-German 翻译任务上得到了 BLEU 28.4,是目前最好的结果(包含ensembles);在WMT 2014 English-to-French 翻译模型上得到 BLEU 41.8,不仅是最好的,训练成本也大大降低。
4. 还存在什么问题?
Encoder-Decoder 是一个模型框架,以翻译为例,这个框架模仿人类思考的过程,从看到原文,将其构思成自己的理解(Encoding过程),然后再构思如何逐字输出(Decoding)。Encoder-Decoder可以应用于很多场景,NLP方向可以是,文字->文字,音频->文字,图片->文字;CV方向可以是图像分割等。
再细看一下构思,构思的方式有很多,最开始仅仅包含各类RNN或CNN。在图像分割,Enocder中我们可以用CNN对图片进行“压缩”,压缩至一个向量或者一个矩阵,随后在Decoder中再“解压”得到结果。
上面两幅图片描述的就是最原始的 Encoder-Decoder 模型。
可是我们也能发现一个问题:无论是CNN based还是RNN based,在Encoder和Decoder之间只有一个被狠狠压缩的向量,Decoder要得多牛才能从这个小小的向量中解压出那么多东西呢??所以说如果图片原本就小,句子原本就短,那么解压的时候还比较能还原。问题是 当输入是很长的句子,一个小向量不足以抓住所有信息!就造成了 information bottleneck。
为了解决这个问题,2015年 Bahdanau et al. (pytorch 代码)就提出在Encoder-Decoder中引入 Attention 机制。随后 Xu et al. 2015 以及 Luong et al. 2015 都给出了不同的 with Attention 模型(Luong的pytorch代码)。
核心思想 是希望Decoder在每次输出的时候都花点注意力在原文中的单词(或者是提取出来的特征)。
Bahdanau et al. 的模型中提到的Attention属于Global Attention,也就是当前 Decoder 的输出会参考Encoder中所有hidden states。
根据上图简单理解,当 Decoder 根据前一个状态 s i − 1 s_{i-1} si−1 与 Encoder中所有隐藏状态分别做点乘(也可以是其他操作),经过softmax得出状态 s i − 1 s_{i-1} si−1需要对它们分配多少注意力,再得到 c i c_i ci。不过对于前两个公式中的 f f f函数和 g g g函数不太确定,因为这两个似乎都直接包含了 c i c_i ci,后面需要再找找代码实现是怎么样的。
分配多少注意力 这个过程被称为 软对齐(soft alignment),即译文中的单词需要花20%的注意力在原文单词1,70%的注意力在原文单词2,10%的注意力在原文单词3上。还有对应的就是硬对齐,即译文只关注原文单词1或原文单词2等。
Xu et al. 的模型参考了Attention Ecoder-Decoder 的思想,并用在了图像上,目的是自动根据图像生成一段文字描述。其中涉及到了两种注意力机制的变种:hard attention 和 soft attention,主要是为了能够直接获取Encoder中CNN提取的图像的底层特征(底层特征会包含更多有利于生成描述的信息)。在Decoder部分使用了LSTM,但与普通的LSTM不同,它的输入除了隐藏层和前一时间步的输出还有一个 z t z_t zt 值,代表的是捕捉了特定区域视觉信息的上下文向量,换一种话来说就是特定时间步去重点关注某一些特定区域的视觉信息和少量关注在其他的区域,将结果转成了一个向量。
有了关注值 a a a 和关注度(权重) α \alpha α就可以来计算 z t z_t zt。
hard attention : 它不关注每个attention的占比,它只关注是否要这个区域的attention,所以权重只有0或者1。如何选择0还是1,作者主要通过伯努利、最大似然和蒙特卡洛采样来得到,此处不展开。
soft attention :不像hard对特定时间特定区域只有关注和不关注,soft里对每个区域都关注,只是关注的重要程度不一样,所以就是权重乘上attention之和作为 z t z_t zt。
Luong et al. 又提出了两个配合Encoder-Decoder的attention方法,分别是Global Attention 和 Local Attention。
Global Attention :和Bahdanau 提出的和心思想是一样的,只是计算方式稍有差别
缺点:每次计算attention都会参考原文所有内容,一是会导致计算效率低二是当原文是一个很长的文章、段落时在做翻译的时候就不切实际。
Local Attention :Local即只关注一部分原文,这个思想是从啊对没错就是从Xu et al.的hard/soft attention那来的,local attention选择性地关注一个小的上下文窗口,并且是可微分的。它提高了计算效率和避免了复杂的训练。
步骤:
还有两种local attention的变种:
Global Attention 和 Local Attention 各有优劣,实际中 Global 的用的更多一点,因为:
自回归模型(AR),又称时间序列模型,数学表达式为:
AR模型是一种线性预测,利用前期若干时刻的随机变量的线性组合来描述以后某时刻随机变量的线性回归模型。NLP中的 seq2seq 和 Transformer 都是AR模型。
相对应的还有Non-Autoregressive,以机翻为例子:
自回归(Autoregressive Translation , AT)模型需要用已生成的词来预测下一个位置的词,用概率模型来表示为
这种自回归的解码方式符合阅读和生成句子时的习惯,能有效地捕捉到真实翻译的分布情况。它在机器翻译等任务上取得了较好的性能,并且波束搜索也能够为寻找近似最优译文提供了一种有效的局部搜索方法。但是也有其自身的缺点,主要表现在以下两个方面:
非自回归 (Non-Autoregressive Translation, NART)模型打破了生成时的串行顺序,希望一次能够解码出整个目标句子,一个简单的非自回归模型直接假设目标序列的每个词都是独立的。
然而这一独立性假设过强,显然与实际问题不符。为了缓解独立性假设过强的问题,一个方案是引入隐变量z来建模目标序列的相关性:我们首先从先验分布中采样z,然后对z进行条件化来非自回归地生成翻译,得到:
隐变量提供一种声明性语言,用于指定复杂数据集中的先验知识和结构关系,能够轻松地通过条件独立性来指定模型约束。同时,深度学习可以使用功能强大的函数逼近器对这些条件概率进行参数化 ,可以天然的将两者结合起来。但条件概率的深度参数化通常使后验推断难以解决,而潜变量又会引入不可微点使反向传播复杂化。
背景结束开始过正文
主流的序列转导模型都是那些有着Encoder-Decoder架构、基于复杂的循环或卷积神经网络的模型。表现最好的也是借助了Attention机制将Encoder-Decoder相连的模型。于是我们提出了一个简单的网络结构,Transformer,仅仅是基于Attention机制。在两个机器翻译任务上表现了这个模型的强并行能力和训练时间少的特点。
该模型在 WMT 2014 English-to-German 翻译任务上得到了 BLEU 28.4,是目前最好的结果(包含ensembles);在WMT 2014 English-to-French 翻译模型上,我们搭建了一个新的单独的模型,并在8个GPU上训练了3.5天,最终得到 BLEU 41.8,这个训练成本相比目前文献中最佳模型的成本,只占了很小的一部分。
RNN、LSTM、GRU都是序列或者转导SOTA模型中常被使用的,比如在做language model和机器翻译的时候。大家也花了很多努力尝试去拓宽循环语言模型和Encoder-Decoder框架带来的边界。循环模型通常伴随着输入和输出序列的符号位置考虑计算。将 输出序列单词的位置和计算时间中的步骤进行对齐,进而生成一组隐藏状态序列 h t h_t ht,将这组序列作为关于前一个隐藏状态 h t − 1 h_{t-1} ht−1和输入位置 t t t的函数。正是因为这样的序列性使得训练样本的时候排除了并行计算的可能性,当长序列输入的时候也是的内存限制限制了样本之间的批处理。当下也有人为了提高计算效率通过使用了一些因式分解的小技巧和条件计算(提高了模型的性能)来完成,但这些都没有解决序列模型带来的限制。
Attention机制后来也作为编译序列模型和转导模型的一部分,它使得模型的依赖性与输入输出序列相距的距离无关。基本上所有cases都是将attention机制和循环网络结合使用。
我们提出的Transformer是一种模型框架回避了循环、替代了完全依靠于attention机制来获取输入输出之间的全局依赖(global attention)。Transformer只要在八个 P100 GPU上并行训练12个小时就可以得到一个sota的翻译质量。
为了减少序列计算,人们利用卷积神经网络作为基础,构建了Extended Neural GPU,ByteNet,ConvS2S等等。但在这些模型中,操作的次数是和输入输出位置距离相关的,所以对于远距离处理的时候就会更难计算依赖关系。在Transformer中,这种操作数量被减少至恒值,尽管通过平均注意力加权的位置会造成有效分辨率的降低,但这种影响将会通过多头注意力(Multi-Head Attention)抵消。
自注意力(Self-Attention,也叫intra-attention),是一种将单个序列的不同位置关联起来以计算序列表示的注意力机制。 自注意力在不同的任务中被成功地应用:阅读理解,抽象总结,文本蕴含,学习任务无关的句子的表示。
End-to-end 记忆网络是基于循环attention机制而非序列对齐循环,并且在简单语言问答和语言模型任务上有着不错的表现。目前Transformer是第一个完全依靠于self-attention的transduction model,用来计算输入和输出的表示。
Encoder-Decoder框架中的Encoder主要是将一组符号表示的输入序列KaTeX parse error: Undefined control sequence: \codts at position 6: (x_1,\̲c̲o̲d̲t̲s̲,x_n)变成了一组连续表示的序列 z = ( z 1 , ⋯ , z n ) =(z_1,\cdots,z_n) =(z1,⋯,zn)。然后将 z传给Decoder,decoder再根据它在每个时间步生成一个符号,最终组成一个符号序列 ( y 1 , ⋯ , y n ) (y_1,\cdots,y_n) (y1,⋯,yn)。模型中的每一步都是自回归的。
Transformer通过堆叠的self-attention和逐点(point-wise)遵循先前提到的整个框架,并且在Encoder和Decoder之后都会有fc。
Encoder:堆了 N = 6 N=6 N=6个一样的层。每层包含了两个sub-layers。第一个sub-layer是一个multi-head self-attention机制,第二个是一个简单的逐层(position-wise)的fc ffnn。在两个sub-layers里面都引入了残差连接(residual connection),并且紧跟一个layer normalization。为了促成残差连接,这个模型中的所有sub-layers,包括embedding layers都输出 d m o d e l = 512 d_{model} = 512 dmodel=512维度的向量。
Decoder:也堆了 N = 6 N=6 N=6个一样的层。除了Encoder中的两个sub-layers,还有第三个sub-layer,这一层对Encoder堆的输出做了multi-head attention。同时也类似Encoder,对每一个sub-layer做了残差连接,并跟一个Layer normalization。同样改了第一层sub-layer中的self-attention,防止当前位置关注后续序列的位置。这种masking与输出embedding偏移一个位置的事实相结合,确保对位置 i i i 的预测只能依赖于位置小于 i i i 的已知输出。
一个Attention函数可以描述为将查询(query)和一组键值对(Key-value pairs)映射到输出(outputs),query/keys/values/outputs都是向量。通过计算values的加权和得到的output,然而values的权重是通过query和对应key的一个兼容函数(compatibility function)来计算得到的。
我们这个专门的Attention呢就叫“Scaled Dot-Product Attention”,输入是由维度 d k d_k dk的queries和keys,维度 d v d_v dv的values组成的。我们计算一个query和所有keys的点乘,并除以 d k \sqrt{d_k} dk,然后应用一个softmax来得到要给values的权重。
实际上,我们会同时计算一组query的attention函数,把它们打包在一个大的矩阵 Q Q Q里。keys和values也被打包在大矩阵 K K K和 V V V。然后矩阵们计算之后的输出:
最常用来计算 Q Q Q和 V V V的方法是additive和dot-product(multiplicative),本文用的是dot-product,除了我们用 1 d k \frac{1}{\sqrt{d_k}} dk1来scale
一下。Additive Attention使用具有单个隐藏层的ffnn计算兼容性函数。虽然两者理论上是一样复杂的,但实际上dot-product attention会更快在空间上效率也更高,因为它可以使用高度优化的矩阵乘法代码来实现。尽管当 d k d_k dk 比较小的时候,两种机制表现相当,但当在 d k d_k dk较大的时候不做scaling时,Additive attention反而有更好的表现。我们猜测当 d k d_k dk 大的时候,dot product增长幅度很大,进而使得输入softmax函数的数据落在饱和区域,也就是梯度极其小的地方。为了抵消这个影响,我们对dot product的结果进行了 1 d k \frac{1}{\sqrt{d_k}} dk1 的scaling。
除了用一个用 d m o d e l d_{model} dmodel维度的keys, values和queries作为输入的attention函数,我们发现将keys, values和queries以不同的、学习的方式分别线性投影到 d k , d q , d v d_k,d_q,d_v dk,dq,dv维度上 h 次会更有效果。对于每一个keys, values和queries的投影版本,我们并行地使用attention函数,产生 d v d_v dv维度的输出。这些结果将被拼接,然后再次被投影,得到最后的结果。
有效体现在哪里呢?多人注意力机制允许模型在不同的位置去从不同的角度来联合地表达一些信息。
实例:下图是有八个Attention,先看右图,这八个Attention用八种不同的颜色表示,从蓝色到灰色。然后我们可以看到一个单词,在这八个Attention上对句子里每个单词的权重,颜色越深,代表权重越大。我们只挑出橙色和绿色(即第二个和第三个色块),看它们分别是怎样的注意力。然后把橙色和绿色的色块拉长就得到了左边这个图。
对于 it 来说,橙色attention中 animal 是最受注意的,表明可能在“东西”这个层面,it 会注意它是一个动物;绿色attention中 tired 是最受注意的,表明可能在“状态”这个层面,it 会注意它是疲惫的。但是对于单头注意力来说,平均化会抑制这样的情况。
投影指的是参数矩阵 W i Q ∈ R d m o d e l × d k , W i K ∈ R d m o d e l × d k , W i V ∈ R d m o d e l × d v , W i O ∈ R h d v × m o d e l W_i^Q \in \mathbb{R}^{d_{model} \times d_k}, W_i^K \in \mathbb{R}^{d_{model} \times d_k}, W_i^V \in \mathbb{R}^{d_{model} \times d_v}, W_i^O \in \mathbb{R}^{hd_v \times{model}} WiQ∈Rdmodel×dk,WiK∈Rdmodel×dk,WiV∈Rdmodel×dv,WiO∈Rhdv×model。
本文中,我们令 h = 8 h=8 h=8平行attention层或者说head,所有的计算成本和满维度的单头注意力的相似。
Transformer由三种不同使用多头注意力的方式:
关于Attention计算不懂的也可以移步 上下文表示 后文有相关内容。
除了attention子层以外,我们encoder和decoder中的每一层还包含一个全连接FFN,这个FFN会分别应用于每一个位置,但是做同样的事情。这个过程包含了两个线性变换,中间还加了一个ReLU:
这个线性变化对于不同位置都是一样的,但是他们的参数在不同层是不一样的。另外一种描述方法,就是可以当成两个kernel size为1的卷积。此FFN的输入输出都是512维度,中间层是2048维度。
和其他序列转导模型模型一样,我们用学习过的embedding将输入输出token转换成 d m o d e l d_{model} dmodel维向量。我们也使用了线性变换和softmax函数来将deocder的输出转换成下一个token的预测概率。在我们的模型里,我们在两个embedding层和pre-softmax线性变换共享的是同一个权重。在embedding层,我们对这些权重乘上了 d m o d e l \sqrt {d_{model}} dmodel
因为我们的模型不包含循环和卷积,为了使得模型能够利用序列的顺序,我们必须注入一些序列中token的相对或者绝对位置。为此,我们在encoder和decoder堆的最底下,也就是输入embedding的时候加入了“位置编码”。位置编码也有和embedding一样的维度这样两者就可以相加。对于编码位置有很多选择,可以是学习的可以是固定的。
在本文,我们利用不同频率的sine和cosine函数:
其中 p o s pos pos是位置, i i i是维度。也就是说,位置编码的每一个维度对应了一个正弦函数。波长形成了一个从 2 π 2\pi 2π- 10000 ⋅ 2 π 10000 \cdot2\pi 10000⋅2π的几何级数。我们之所以选择这个函数是因为我们假设它可以轻松的学到相对位置,因为对于任意固定的偏差 k k k, P E p o s + k PE_{pos+k} PEpos+k都可以通过一个有关 P E p o s PE_{pos} PEpos的线性函数来表达。
我们也用学习的位置embedding做了实验,但我们发现两者结果基本上大差不差。我们选着正弦函数版本是因为它可能允许模型推断出比训练期间遇到的序列长度更长的序列长度。
我们比较了self-attention层的不同方面和循环/卷积层(那些通常用来将一串字符序列表示转换成等长的实数序列表示的序列的方法)。
我们考虑了三个必须: 每一层的所有计算复杂度;可以被并行的计算量,通过需要最小的序列操作数量来计算;网络中长范围以来的路径长度。
学习到长范围依赖是许多序列任务中的关键挑战。一个最主要的影响学习依赖能力的因素是将信号前向和后向在网络中传播的时候的路径长度。在输入和输出的序列中,如果任意位置的组合的长度越短,那么就更容易学到长范围依赖。 因此,在不同类型的层中,我们也比较任意输入输出位置之间的最长路径。
表1,一个self-attention层在顺序执行操作的时候,只需要恒定的时间复杂度来链接所有位置,但是循环层需要 O ( n ) O(n) O(n)来完成顺序操作。在计算复杂度下,当序列长度 n n n小于向量表示的维度 d d d时(这也是经常会在机器翻译中出现的情况,比如word-piece或者byte-pair),self-attention层会比循环层更快。
为了改进那些有着超长序列的任务的计算性能时,self-attention可以通过限制只考虑输出位置所对应的输入位置的周围 r r r个位置。这可以将最大路径长度增加到 O ( n / r ) O(n/r) O(n/r)。但这会在未来继续调研。
单个的有着kernel-size k < n k
作为附带好处,self-attention可以产生更多可解释模型。不仅单个注意力头清楚地学习执行不同的任务,而且许多似乎表现出与句子的句法和语义结构相关的行为。
在WMT 2014 English-German(4.5 million个句子对)上训练。通过byte-pair encoding对句子进行encoding,得到了37000个共享的源目标vocab。对于English-French,我们用了更大的包含了36 million个句子,将tokens划分32000个单词片的vocab。句子对根据大致序列长度进行批划分。每个训练batch包含一组大约包含25000源tokens和目标tokens的句子对。
用了8块nvidia p100 GPU。base model用的的超参前面提到,每个训练step大约花费0.4s。对base model训练了大约100,000steps或者说12h。对大模型(table 3的最后一行),一个step是1s,训练了300,000steps(3.5天)
使用Adam optimizer, β 1 \beta_1 β1 = 0.9, β 2 \beta_2 β2 = 0.98 和 ϵ \epsilon ϵ = 1 0 − 9 10^{-9} 10−9。学习率跟着训练step变化的公式:
l r a t e = d m o d e l − 0.5 ⋅ m i n ( s t e p n u m 0.5 , s t e p _ n u m ⋅ w a r m u p _ s t e p − 1.5 ) lrate = d_{model}^{-0.5} \cdot min(step_num^{0.5},step\_num \cdot warmup\_step^{-1.5}) lrate=dmodel−0.5⋅min(stepnum0.5,step_num⋅warmup_step−1.5)
这相当于在第一个warmup_steps训练步骤中线性地增加学习率。此后按步骤数的反平方根的比例降低。我们使用 warmup_steps = 4000。
训练过程中使用了三种正则化。
Residual Dropout: 对每个sub-layer的输出都加了dropout,然后再加上sub-layer的输入,进行归一化。此外,在embddings的和只有也加入了dropout,以及在encoder和decoder的位置编码处也加入了dropout。对于base model,我们使用了dropout rate = 0.1。
**Label smoothing: **在训练过程中,我们使用了label smoothing,设置 ϵ l s = 0.1 \epsilon_{ls} = 0.1 ϵls=0.1。虽然会有害于perplexity,使得模型学会了更多不确定因素,但是会提高准确度和BLEU值。
在WMT2014 英语-德语的翻译任务上,大Transformer model比先前所有的模型在BLEU上高出2.0,得到BLEU 28.4。Table3给出了对于这个模型的配置。训练在8 P100 GPU上花费了3.5天。base model也超过了之前所有的模型,而训练成本只是任何竞争模型的一小部分。
在WMT2014 英语-法语,big model 的BLEU 41,并且只花费了四分之一的cost。这里使用了0.1的dropout rate。
对于base model,我们使用了通过平均最近5个检查点得到的单一模型,这些检查点是以10分钟的时间间隔写入的。对于大模型,我们平均了最后20个checkpoint。使用beam search,beam大小为4,长度惩罚 α = 0.6 \alpha = 0.6 α=0.6。这些超参是基于开发集选择的。我们将推理过程中的最大输出长度设定为输入长度+50,但尽可能提前终止 。
表2总结了结果,并将翻译质量和训练成本与文献中的其他模型架构进行了比较。通过将训练时间、所使用的GPU数量和每个GPU的持续单精度浮点能力的估计值相乘来估计训练一个模型所使用的浮点运算的数量。
为了研究Transformer中不同组成的重要性,做了几种改变,并在英语-德语翻译的开发集中做测试。使用了beam search,但没有做checkpoint averaging。结果在Table3中。
A行中,我们改变了attention heads的个数,attention 的key和value的维度,并保证计算量不变。虽然单头attention比最好的设置低了0.9BLEU,但是质量也会因为头数变多而下降。
B行中,减少key的维度会有害于模型质量,这表明,确定兼容性并不容易,一个比点积更复杂的兼容性函数可能是有益的。C行和D行中,意料之中,更大的模型会更好,dropout也有益于避免过拟合。E行,替换了正弦曲线的位置编码,而用学习得到的位置编码,与原来的效果基本一致。
(成分解析是通过将句子分解为子句(也称为成分)来进行分析的过程。)
为了评估Transformer的泛化性,我们在英语成分解析上做了实验。这个任务展现了一个具体的挑战:输出会受到强大的结构约束,并且明显长于输入。此外,RNN序列对序列 模型还不能在小数据系统中达到最先进的结果。
我们在WSJ(大约40K的训练句)上训练了一个4层的Transformer,模型维度在1024。也在半监督设置下,使用更大的有着高置信度的BerkleyPaeser词库、有着大约17M的句子上做训练。我们在仅有WSJ的设置中使用了16K的词汇,在半监督设置中使用了32K的词汇。
我们只进行了少量的实验来选择dropout rate,包括attention和residual,学习率和开发集上的beam size,所有其他参数 都与英译德基础翻译模型保持一致。在推理过程中,我们 将最大输出长度增加到输入长度+300。我们使用了21的beam size和α = 0.3 对于仅有的WSJ和半监督设置,我们都使用了21个波束大小和α=0.3。
我们在表4中的结果显示,尽管缺乏特定任务的调整,我们的模型表现得出奇的好,产生了比以前报道的所有模型更好的结果,除了Recurrent Neural Network Grammar。
与RNN序列到序列模型相比,即使只在WSJ的40K句子训练集上进行训练,Transformer也比BerkeleyParser更出色。
在这项工作中,我们提出了Transformer,这是第一个完全基于注意力的序列转换模型,用多头的自我注意力取代了编码器-解码器架构中最常用的递归层。
对于翻译任务,Transformer的训练速度明显快于基于递归或卷积层的架构。在WMT 2014英译德和WMT 2014英译法的翻译任务上,我们实现了新的技术状态。在前一项任务中,我们的最佳模型甚至超过了之前报道的所有组合。
我们对基于注意力的模型的未来感到兴奋,并计划将其应用于其他任务。我们计划将Transformer扩展到涉及文本以外的输入和输出模式的问题,并研究局部的、有限的注意力机制,以有效地处理大型输入和输出,如图像、音频和视频。使生成的顺序性降低是我们的另一个研究目标。
参考链接
跟着Harvard nlp过一遍pytorch版的代码。
所有模型 https://huggingface.co/docs/transformers/model_summary#summary-of-the-models
新论文阅读 https://zhuanlan.zhihu.com/p/517063868