【论文阅读】Attention is all you need(Transformer)

前言

1.Abstract

在一些 sequence 转换任务中(比如神经翻译,将原语言的sequence转换为目标语言sequence),主流模型都是包含一个 encoder 和一个 decoder 的RNN或者CNN模型。效果最好的模型在encoder-decoder这个架构上加了 attention 机制。

  • 本文提出了一个全新,简单的架构 Transformer

    • 仅仅依靠 attention 机制,完全不需要循环或者卷积
    • 在结果上更优,可以有更多的并行化,训练需要更少的时间
  • 在 WMT 2014 English-to-German 翻译任务中,做到了 28.4 BLEU,比最好的效果高了 2 BLEU 以上

  • 在 WMT 2014 English-to-French 翻译任务中,达到了 41.8 BLEU。在 8 个 GPU 上训练了3.5天,比目前最好的模型快得多

  • 我们还将 Transformer 用在了英文句法成分分析上,其在训练数据很多或者不太多的时候,都表现得很好

2.Introduction

目前,LSTM与GRU在sequence modeling和sequence转换任务中都做得很好,大量的工作动作拓展 循环的 language model 和 encoder-decoder架构。

循环模型通常沿着输入和输出序列来分解计算,就是将序列中符号的位置与时间步对齐,一个时间步计算一个位置(我们常常称计算处在 t t t 时刻),同时会产生隐藏状态 h t h_t ht h t h_t ht 是上一时间步的隐藏状态 h t − 1 h_{t-1} ht1 t t t 位置的输入的函数(就是第 t t t 个时间步的输入)。这种循环所固有的顺序在训练的时候妨碍了并行化(因为想计算 t t t 时间步的值,就必须要知道 t − 1 t-1 t1 时间步的隐藏状态,后一个计算要等前一个算完)。这在序列比较长的时候是很重要的,因为内存约束限制了跨样本的批处理。(翻译的可能不对,序列变长,循环网络的训练时间就更长,一个样本占用内存的时间会更久)近来的工作通过分解技巧(factorization tricks)[21]和条件计算(conditional computation)[32]在计算效率上实现了很大的提升,同时后者使得模型效果得到了提升。然而阻碍计算效率的根本因素顺序性仍然存在

Attention机制已经成为好的序列模型和转换模型不可或缺的一部分,==attention 允许对依赖关系建模,而不考虑它们在输入或输出序列中的距离[2, 19] 。==然而,除了极少数情况下[27],这种注意机制是与循环网络一起使用的。

这篇工作中,我们提出 Transformer,一种模型架构避免了循环,而是完全依赖于注意机制来建立输入和输出之间的全局依赖关系。Transformer允许明显更多的并行化,并且在8个P100 gpu上经过12个小时的训练后,可以在翻译质量上达到一个新的水平。

3.Background

减少序列计算量的目标,也是 Extended Neural GPU [16], ByteNet [18] and ConvS2S [9] 的基础。这些工作都将卷积网络作为基础的 building block,可以对所有输入和输出位置的隐藏状态进行并行计算。在这些模型中,将输入或者输出中的任意两个位置的信号联系起来需要的操作次数随着两个位置之间距离的增大而增多,对 ConvS2S 来说是线性增长的,对 ByteNet 来说是对数增长的。这会使学习两个比较远的位置的相关关系变得更难

  • 以下图为解释,CNN虽然能够在所有位置上进行并行计算,但是想要将两个位置的信息结合起来需要堆叠很多层,离得越远,需要的层数越多,也就是需要的操作数越多

在这里插入图片描述
Transformer 中,操作数被减少到一个常数,尽管这是以减少了有效分辨率为代价的,因为我们平均了 attention-weighted positions(),我们下面会介绍 Multi-Head Attention 来弥补。

Self-attention 有时被称为 intra-attention(内注意力),是一种为了计算整个 sequence 的表达,而将单一 sequence 的不同位置联系起来的注意力机制。Self-attention 已经被成功运用到很多任务中,这包括阅读理解(reading comprehension),摘要提取(abstractive summarization),文本蕴涵(textual entailment)以及学习独立于任务的句子表示[4, 27, 28, 22]。

端到端(end-to-end)的记忆网络是以注意力机制的循环网络而不是序列对齐方式的循环网络为基础的,并且已经在简单的语言问答和语言模型任务当中有很好的表现[34]。

据我们所知,Transformer 是第一个完全依靠 self-attention 机制,而不利用序列对齐的 RNNs 或者卷积来计算其输入和输出表达的转换模型。接下来,我们将介绍 Transformer,说明 self-attention,并且讨论其相较于 [17, 18],[9] 这样的模型的优点。

4.Model Architecture

大部分优秀的神经序列转换模型,都有 encoder-decoder 架构[5, 2, 35]。这里,encoder 将符号表达为 ( x 1 , ⋯   , x n ) (x_1, \cdots,x_n) (x1,,xn) 的输入序列映射为 z = ( z 1 , ⋯   , z n ) z = (z_1, \cdots,z_n) z=(z1,,zn) 这样的连续表达。给定 z z z,decoder之后会按每次产生一个元素的方式生成符号表达为 ( y 1 , ⋯   , y n ) (y_1,\cdots,y_n) (y1,,yn) 的输出序列。在每一步,模型都是自回归的(auto-regressive)[10],即在产生下一个位置时,都将前面产生的结果作为额外的输出。

Transformer 的大体结构如下所示,在encoder 和 decoder 中都使用堆叠的 self-attentionpoint-wise全连接层。encoder是左边的,decoder是右边的。
在这里插入图片描述

4.1. Encoder and Decoder Stacks

  • Encoder:encoder 由 N = 6 个相同的层堆叠而成。每一层都有两个子层。

    • 第一个是 multi-head self-attention机制
    • 第二个是一个简单的,position-wise 全连接前馈网络。

    我们在两个子层的周围都使用了残差连接[11],然后进行layer normalization[1]。这样导致,每个子层的输出都是 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)是子层本身施加的函数。为了使残差连接更容易,模型中的所有 sub-layer,包括 embedding layers,其输出的维度都是 d m o d e l = 512 d_{model}=512 dmodel=512

  • Decoder:decoder 也是由 N = 6 个相同的层堆叠而成。除了 encoder 中的两个子层之外,decoder 还插入了第三个子层,它对 encoder 堆栈的输出结果进行multi-head attention处理。与 encoder 类似的是,我们也在每个子层周围都进行了残差连接和 layer normalization操作。我们还修改了 decoder 堆栈中的 self·attention 子层,以防止当前位置对后续位置的关注(通过mask实现)。mask基于如下事实:output embedding应该偏移一个位置,从而保证对于位置 i i i 的预测只依靠了 i i i 之前的已知输出(就是把后面不该看到的信息遮住)。

4.2. Attention

Attention 函数可以被描述为将一个query(查询)和一系列 key-value对(键值对)映射为一个输出,query,keys,values都是向量。输出是 values 的加权求和,分配给每个 value 的权重由 query 与相应 key 的兼容性函数计算得到
在这里插入图片描述

4.2.1. Scaled Dot-Product Attention

我们将我们这种特殊的 attention 叫做 ”Scaled Dot-Product Attention“(Figure 2)。输入是 queries,keys,values。其中前两个的维度是 d k d_k dk ,values 的维度是 d v d_v dv。我们计算一个 query 与所有 key 的dot product,并且除以 d k \sqrt{d_k} dk ,然后接一个 softmax 函数来得到 values 对应的权重。

在实践中,我们同时计算一组 queries 的注意函数,我们将一组 queries 打包成一个矩阵 Q Q Q。Keys 和 values 同样被打包成矩阵 K , V K,V K,V。我们最终计算输出矩阵的方式如下:
在这里插入图片描述

两个最常用的 attention 函数是 additive attention[2]和dot-product(multiplicative)attention。除了我们这里用了 d k \sqrt{d_k} dk 这个缩放因子,Dot-product attention和我们的算法是完全一样的。Additive attention通过一个带有单个隐藏层的前馈网络来计算兼容性函数。尽管二者的复杂度理论上是相当的,dot-product在实际使用的时候会更快,并且在空间上是更高效的,因为它可以使用高度优化的矩阵乘法代码来实现。

尽管在 d k d_k dk 比较小的时候,两种 attention 机制表现相当,因为additive attention由于不需要缩放,在 d k d_k dk 比较大的时候,additive attention 比不带缩放的 dot product attention表现得更好。我们推测,这是因为在 d k d_k dk 比较大的时候,点积的会变得很大,将 softmax 函数推向具有极小梯度的区域,为了抵消这种影响,我们将点积除以 d k \sqrt{d_k} dk

应该注意的是,输出是 v v v 的加权求和,因此其输出的维度和输入中 v v v 的维度是相同的

下面我们用图解释一下

  • 将 q 都和所有的 k 去做 attention
    在这里插入图片描述

  • 然后接一个 softmax 以获得权重(概率)
    在这里插入图片描述

  • 通过对 v 进行加权求和,我们得到输出结果
    在这里插入图片描述

  • 同样的方式,我们可以对 k 2 k^2 k2 求 attention,不同 k 的attention 是可以同时进行的,他们互不影响

    在这里插入图片描述

  • 实现并行运算,我们可以将上述操作都写成矩阵的形式

    在这里插入图片描述
    在这里插入图片描述

4.2.2.Multi-Head Attention

与其用 d m o d e l d_{model} dmodel 维的 query、key 和value 执行单个的 attention 函数,我们发现将query、key和value分别用不同的、学习到的线性映射映射 h 次效果更好。这些线性映射将输入分别映射成 d k . d k , d v d_k.d_k,d_v dk.dk,dv 维。在每个版本(因为映射了 h 次,一共有 h 个版本)映射后的 queries, keys, values上,我们并行执行 attention 函数,产生 d v d_v dv 维度的输出。之后将这些输出连接到一起,然后再进行一次映射,从而产生最终的结果,像 Figure2(右边)描述的那样。

Multi-head attention(多头注意)允许模型在不同位置共同注意来自不同表示子空间(h个子空间)的信息。如果只有一个 attention head(注意力头),他进行平均操作会削弱这个效果。

在这里插入图片描述

其实就是把一个向量拆分成 h 个,然后对每一个拆分后的向量都执行 self-attention 操作,最后再将这 h 的 self-attention 的结果拼接起来,得到一个完整的向量

  • 下图代表有两个 head,红色部分属于将所有向量拆分成两份的第一份
  • 其他的向量代表拆分成两份中的第二份
  • 两份各自进行 self-attention 操作,然后将结果拼在一起
  • 好处:不同head关注的重点可能不一样,这也就是上面说的允许模型在不同位置共同注意来自不同表示子空间(h个子空间)的信息

在这里插入图片描述

在我们的工作中,我们设置 h = 8 h=8 h=8个并行的 attention 层(8个头)。对每一个 attention,我们使用 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。(这里可以回忆一下,上面说了,为了使得残差更容易进行,我们令每个子层的输出维度都是 512,这里 512/ 8 = 64)因为每个 head 对应的输出维度都减少了,虽然 head 变多了,其实总的计算量和直接使用全维度的单头 attention 差不多

4.2.3. Applications of Attention in our Model

Transformer 在三种不同方式上使用了 multi-head attention

  • encoder-decoder attention 层中,queries 来自 decoder 的前一层,keys 和 values 都来自 encoder 的输出。这允许,decoder 中所有位置都能关注到输入序列中的所有位置。这其实模拟了典型sequence-to-sequence模型中的 encoder-decoder attention机制,比如[38,2,9]。
  • encoder 中包含了 self-attention 层。其,queries,keys,values都来自encoder前一层的输出。每个位置都能注意到前一层的所有位置
  • decoder中也有 self-attention 层,每个位置只能注意到前面(包括自己),我们需要防止 decoder 中的想做信息流来保持自回归属性。通过在进入 softmax时,将右边的值都mask住(将他们的值都设为 − ∞ -\infin )。见 Figure 2。

4.3. Position-wise Feed-Forward Networks

除了 attention 子层外,encoder 和 decoder 中的每一层还都包含一个全连接前馈网络,该前馈网络单独且相同地应用于每个位置。它由两个线性变换组成,之间有一个ReLU激活。

在这里插入图片描述

尽管线性变换在不同位置上是相同的,但它们使用层与层之间的不同参数。它的另一种描述方式是两个kernel size为1的卷积。 输入和输出的维度为 d m o d e l = 512 d_{model}=512 dmodel=512,内部层的维度为 d f f = 2048 d_{ff}=2048 dff=2048

4.4.Embeddings and Softmax

和其他的序列转换任务类似,我们使用学习到的 embeddings 将输入 tokens 和输出 tokens 转换成 d m o d e l d_{model} dmodel 维的向量。我们还使用普通的线性变换和softmax函数将 decoder 的输出转换为预测的下一个词符的概率。在我们的模型中,两个 embedding层之间和 pre-softmax 线性变换共享相同的权重矩阵,类似于在[30]。在 embedding 层中,我们将这些权重乘以 d m o d e l \sqrt{d_{model}} dmodel

4.5. Positional Encoding

由于我们的模型不包含循环和卷积,为了让模型利用序列的顺序,我们必须注入序列中关于词符相对或者绝对位置的一些信息。为此,我们将“位置编码”添加到 encoder 和 decoder 堆栈底部的input embedding中。位置编码和 embedding 的维度 d m o d e l d_{model} dmodel 相同,所以它们俩可以相加。有多种位置编码可以选择,例如通过学习得到的位置编码和固定的位置编码[9]。

在这项工作中,我们使用不同频率的正弦和余弦函数:

在这里插入图片描述

其中pos 是位置,i 是维度。也就是说,位置编码的每个维度对应于一个正弦曲线。这些波长形成一个几何级数,从2π 到10000 ⋅ 2π。我们选择这个函数是因为我们假设它允许模型很容易学习对相对位置的关注,因为对任意确定的偏移 k, PEpos+k可以表示为 PEpos 的线性函数。

我们还使用学习到的位置 embeddings[9]进行了试验,并且发现这两个版本几乎产生了相同的结果((see Table 3 row (E))。我们选择了正弦曲线版本,因为它可以允许模型推断比训练期间遇到的更长的序列。

5.Why Self-Attention

本节,我们比较self-attention与循环层和卷积层的各个方面,他们通常用于将一个代表符号序列的变长的 sequence ( x 1 , ⋯   , x n ) (x_1,\cdots,x_n) (x1,,xn)映射到另一个等长的序列 ( z 1 , ⋯   , z n ) (z_1,\cdots,z_n) (z1,,zn),其中 x i , z i ∈ R d x_i,z_i \in R^d xi,ziRd。例如典型的序列转换任务的encoder或decoder中的一个隐藏层。我们使用self-attention是考虑到解决三个问题。

一个是每层计算的总复杂度。 另一个是可以并行的计算量(以所需的最小顺序操作的数量来衡量)。第三个是网络中长距离依赖之间的路径长度。==学习长距离依赖性是许多序列转换任务中的关键挑战。==影响学习这种依赖性能力的一个关键因素是前向和后向信号必须在网络中传播的路径长度。在输入和输出序列中任意位置之间的结合的这种路径长度越短,学习远距离依赖性就越容易[12]。因此,我们还比较了由不同类型的层组成的网络中任意两个输入和输出位置之间的最大路径长度。

在这里插入图片描述

如表 1 所示,self-attention层将所有位置连接,需要顺序操作的数目是一个恒定的值,而循环层需要 O ( n ) O(n) O(n) 顺序操作。在计算复杂性方面,当序列长度 n 小于其向量表示的维度 d 时,self-attention比循环层更快,这是机器翻译中最先进的模型最常见情况,不如 word-piece[38] 和 byte-pair[31] 表示。为了提高包含长序列的任务的计算效率,可以将self-attention限制为仅考虑大小为r 的邻域。这会使得最大路径长度提高到 O ( n / r ) O(n/r) O(n/r)。我们打算再之后的工作中进一步研究这种方式。

一个 kernel 宽度 k < n k < n k<n 的单一卷积层没法将输入和输出中的任意位置成对得连接起来。要做到这样,在邻近 kernel 的情况下,需要堆叠 O ( n / k ) O(n/k) On/k 个卷积层,在扩展卷积[18]的情况下,需要堆叠 O ( log ⁡ k ( n ) ) O(\log_k(n)) O(logk(n)) 层,这会使网络中任意两个位置的最大路径长度增加。卷积层通常比循环层更昂贵,与因子k有关。然而,可分卷积[6]大幅减少复杂度到 O ( k ⋅ n ⋅ d + n ⋅ d 2 ) O(k\cdot n \cdot d + n \cdot d^2) O(knd+nd2)。就算 k = n k=n k=n,可分卷积的复杂度也才等于一个 self-attention 层和一个 point-wise 前馈层的和,这也就是我们在模型中使用的方法。

间接的好处是self-attention可以产生更可解释的模型。们从我们的模型中研究attention的分布,并在附录中展示和讨论示例。 每个attention head不仅清楚地学习到执行不同的任务,许多似乎展现与句子的句法和语义结构相关的行为。

6.总结

在这项工作中,我们提出了 Transformer,第一个完全基于 attention 的序列转换模型,用multi-headed self-attention取代了 encoder-decoder 架构中最常用的循环层。

对于翻译任务,Transformer可以比基于循环或卷积层的体系结构训练更快。 在WMT 2014 English-to-German 和WMT 2014 English-to-French 翻译任务中,我们都取得了最好的结果。 在前面的任务中,我们最好的模型甚至胜过以前报道过的所有整合模型。

我们对基于attention的模型的未来感到兴奋,并计划将它们应用于其他任务。我们对基于attention的模型的未来感到兴奋,并计划将它们应用于其他任务。并研究局部的,受限 attention 机制以有效处理大型输入和输出,如图像、音频和视频。使生成具有更少的顺序性是我们另一个研究目标。

猜你喜欢

转载自blog.csdn.net/qq_52852138/article/details/124904169