Attention is all you need 论文学习

Abstract

目前主流的序列转导模型都是基于复杂的递归或卷积神经网络,包含一个编码器和解码器。表现最佳的模型也是通过一个注意力机制,将编码器和解码器联系起来。本文提出了一个新的网络结构,Transformer,只使用了注意力机制,彻底抛弃了递归和卷积操作。在两个机器翻译任务上,实验结果表明这些模型表现非常优异,可以并行计算,大幅度减少了训练时间。在 WMT 2014 英语-德语翻译任务上,该模型取得了 28.4 BLEU 的成绩,提升了现有的最好成绩将近 2 BLEU。在 WMT 2014 英语-法语翻译任务上,该模型取得了新的单模型 SOTA BLEU 成绩,在8个GPU上训练了3.5天就取得了41.8 BLEU 的成绩,训练成本只是现有最佳模型的零头。作者将其成功应用到了英语句法分析任务上,证明 Transformer 对其它任务泛化能力很好。

1. Introduction

递归神经网络、长短期记忆和 gated 递归神经网络是当前序列建模和解决转导问题(语言建模和机器翻译)的 SOTA 方法。人们投入了大量的智慧来推动递归语言模型和编码器-解码器架构的进步。

递归模型通常沿着输入和输出序列的符号位置来分解计算。计算时将位置与步骤对齐,它们会生成一个隐藏状态 h t h_t ht的序列,作为之前状态 h t − 1 h_{t-1} ht1的函数及位置 t t t的输入。这种内在的序列化实质就阻碍了我们去并行地训练样本,对于长序列就很关键,因为内存问题会制约批化样本。最近一些工作通过因式分解和条件计算,在计算效率上取得了显著进展,后者也提升了模型的表现。序列计算的基本问题仍然存在。

注意力机制已经成为SOTA序列建模和转导模型的主要部分,允许我们忽略输入或输出序列中依赖的距离,对依赖关系进行建模。但是有一些方法中,注意力机制都是搭配一个递归网络使用的。

本文作者提出了 Transformer,没有使用递归,而完全依赖于注意力机制,在输入和输出之间提取全局依赖关系。Transformer 可以做到高度的并行化,在 8个 P100显卡上训练 12 个小时,翻译质量就可以达到 SOTA 的效果。

2. 背景

为了达到降低序列计算量的目的,人们提出了Extended Neural GPU、ByteNet 和 ConvS2S,这些方法都将卷积网络作为基础构建单元,为所有的输入和输出位置并行地计算隐藏表示。在这些模型中,为了将两个任意输入或输出位置的信号关联起来,所需的运算数量会随着位置距离增长而增长,对于 ConvS2S 是线性的,对于 ByteNet 是对数的。这就使得我们很难去学习距离较远位置的依赖关系。在Transformer中,运算量可以降低到一个常数,尽管会降低一些有效解析度,因为我们要求注意力加权位置的均值,我们可以通过 Multi-head 注意力来抵消掉它的影响。

自注意力,有时候也叫作内注意力,它关联单个序列的不同位置以计算该序列的表示。自注意力在许多任务上都取得了成功,比如阅读理解、概括总结、文本涵义和学习语句表示等。

端到端的记忆网络基于递归注意力机制而来,而非序列对齐递归方法,被证明在简单-语言问答和语言建模任务上都表现不错。

根据作者所知,Transformer 是第一个完全凭借自注意力机制来计算输入和输出表示的转导模型,没有用序列对齐 RNN 或卷积。

3. 模型结构

大多数神经序列转导模型都有一个编码器-解码器结构。这里,编码器会将符号表示为 ( x 1 , . . . , x n ) (x_1,...,x_n) (x1,...,xn)的输入序列映射到一个连续表示的序列 z = ( z 1 , . . . , z n ) z=(z_1,...,z_n) z=(z1,...,zn)。给定 z z z,解码器然后一次一个元素地生成输出符号序列 ( y 1 , . . . , y m ) (y_1,...,y_m) (y1,...,ym)。在每一步中,模型是自回归的,将之前生成的符号作为额外输入,再来生成下一个。

Transformer 有着如下的整体架构,在编码器和解码器中使用了多个自注意力和 point-wise、全连接层,如图1中的左半部分和右半部分所示。

Attention is all you need 论文学习_第1张图片

3.1 编码器和解码器

编码器:编码器由 N = 6 N=6 N=6个完全相同的层堆叠组成。每层都有2个子层。第一个子层是 multi-head 自注意力机制,第二个是一个简单的、位置完全连接的前馈网络。作者对每个子层再采用了一个残差连接,遵循了层归一化的设计[1]。每个子层的输出就是 LayerNorm ( x + Sublayer ( x ) ) \text{LayerNorm}(x+\text{Sublayer}(x)) LayerNorm(x+Sublayer(x)),其中 Sublayer ( x ) \text{Sublayer}(x) Sublayer(x)是子层本身实现的函数。为了方便这些残差连接,所有的子层和 embedding 层都产生维度是 d m o d e l = 512 d_{model}=512 dmodel=512的输出。

解码器:解码器也是由 N = 6 N=6 N=6个完全相同的层堆叠而成。除了编码器层中的两个子层,解码器还插入了第三个子层,对编码器堆栈的输出做 multi-head 注意力。与编码器类似,作者在每个子层都使用了残差连接。作者也修改了解码器堆栈中的自注意力子层,防止位置关注到后面的位置。由于输出 embedding 会偏移一个位置,该掩码保证了位置 i i i的预测只依赖于已知的输出,就是位置小于 i i i的那部分。

3.2 注意力

注意力函数可以描述为将一个 query 和一个 key-value 集合映射到一个输出,其中 query、keys、values 和输出都是向量。输出是 values 的加权和,其中分配给每个 value 的权重是通过 query 与相应 key 的兼容函数计算而来。

Attention is all you need 论文学习_第2张图片

3.2.1 缩放点积注意力

作者将这种特殊的注意力称作“缩放点积注意力”(图2)。输入由维度是 d k d_k dk 的 queries 和 keys,以及维度是 d v d_v dv 的 values 组成。我们计算 query 和所有 keys 的点积,然后每个都除以 d k \sqrt d_k d k,然后使用一个 softmax 函数来获得 values 的权重。

在实践中,我们同时计算一个 queries 集合的注意力,并将它们组合成一个矩阵 Q Q Q。Keys 和 values 也会组合成矩阵 K K K V V V。我们计算输出矩阵为:

Attention ( Q , K , V ) = softmax ( Q K T d k ) V \text{Attention}(Q,K,V) = \text{softmax}(\frac{QK^T}{\sqrt d_k}) V Attention(Q,K,V)=softmax(d kQKT)V

两个最常用的注意力函数是加法注意力和点积注意力。点积注意力与本文算法一样,除了缩放因子 1 d k \frac{1}{\sqrt d_k} d k1。加法注意力使用一个带有单个隐藏层的前馈网络来计算兼容性函数。尽管这两个的理论复杂度相似,点积注意力在实践中要更快,更节省空间,因为它可以通过高度优化的矩阵乘法代码实现。

尽管当 d k d_k dk较小时,这两个注意力机制表现相近,当 d k d_k dk较大时,加法注意力就要优于不带缩放的点积注意力。作者猜测,当 d k d_k dk较大时,点积的增长幅度很大,将 softmax 函数推向梯度极小的区域。为了抵消这个影响,作者缩小点积 1 d k \frac{1}{\sqrt d_k} d k1倍。

3.2.2 Multi-head 注意力

作者发现将 queries、keys 和 values 分别用不同的、学到的线性映射 h h h 倍到 d k , d k d_k,d_k dk,dk d v d_v dv 维度效果更好,而不是用 d m o d e l d_{model} dmodel维的 keys、values 和 queries 执行单个注意力函数。对于每个映射版本的 queries、keys 和 values,然后我们可以并行地执行注意力函数,输出 d v d_v dv维的输出值。将它们连接并再次映射,得到最终的值,如图2所示。

Multi-head 注意力允许模型从不同的表示子空间关注不同位置信息。如果只有一个注意力 head,它的均值会削弱这个信息。

MultiHead ( Q , K , V ) = Concat ( head 1 , . . . , head h ) W O \text{MultiHead}(Q,K,V)=\text{Concat}(\text{head}_1,...,\text{head}_h)W^O MultiHead(Q,K,V)=Concat(head1,...,headh)WO

where head i = Attention ( Q W i Q , K W i K , V W i V ) \text{where} \quad \text{head}_i = \text{Attention}(QW_i^Q, KW_i^K, VW_i^V) whereheadi=Attention(QWiQ,KWiK,VWiV)

其中映射为参数矩阵 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 O ∈ R h d v × d 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^O\in \mathbb{R}^{hd_v\times d_{model}} WiQRdmodel×dk,WiKRdmodel×dk,WiVRdmodel×dv,WORhdv×dmodel

本文,作者使用 h = 8 h=8 h=8个平行注意力层或 heads。对于每个 head,作者使用 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。因为每个head的维度降低,总的计算量和全维度的单个head注意力的计算量相近。

3.2.3 注意力在本文模型中的应用

Transformer 以三个不同的方式来使用multi-head:

  • 在“编码器-解码器注意力”层,queries 来自于之前解码器层的输出,keys 和 values 则来自于编码器的输出。这就使得解码器中的每个位置都能关注到输入序列的所有位置。这模仿了 sequence-to-sequence 中典型的编码器-解码器注意力机制。
  • 编码器包含了自注意力层。在自注意力层中,所有的 keys、values 和 queries 都来自于同一个位置,在这个情形中,就是编码器中前一层的输出。编码器的每个位置都可以关注到编码器前一层的所有位置。
  • 解码器的自注意力层允许解码器的每个位置都能知道解码器直到并包括该位置的所有位置。为了保持自回归的特性,我们需要防止向左的信息流。在缩放点积注意力中,作者通过屏蔽softmax输入中所有不合法连接的值(设置为 − ∞ -\infty )来实现该操作,看图2。

3.3 基于位置的前馈网络

除了注意力子层,编码器和解码器中的每一层都包含了一个全连接的前馈网络,单独并相同地应用到每个位置上。它由两个变换构成,之间有一个 ReLU 激活:

FFN ( x ) = max ⁡ ( 0 , x W 1 + b 1 ) W 2 + b 2 \text{FFN}(x)=\max(0,xW_1 + b_1)W_2 + b_2 FFN(x)=max(0,xW1+b1)W2+b2

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

3.4 Embeddings 和 Softmax

与其它序列转导模型类似,作者使用了可学习的 embeddings,将输入 tokens 和输出 tokens 转换为维度是 d m o d e l d_{model} dmodel的向量。作者也用了常用的可学习线性变换和 softmax 函数来将解码器的输出转换为预测的下一个token的概率。在模型中,作者在两个 embedding 层和 pre-softmax 线性变换之间共享相同的权重矩阵。在 embedding 层,作者将权重乘以 d m o d e l \sqrt d_{model} d model

3.5 位置编码

由于本文模型没有用到递归和卷积,为了利用序列的顺序信息,我们必须在序列中加入一些 token 的相对或绝对位置的信息。为此,作者将“位置编码”信息加入到解码器和编码器堆栈底部的输入 embedding 中。位置编码与 embedding 有着一样的维度 d m o d e l d_{model} dmodel,这样二者可以相加。位置编码可以有许多选择,例如通过学习得到的位置编码和固定的位置编码。

本文中作者使用了不同频率的 sine 和 cosine 函数:

P E ( p o s , 2 i ) = s i n ( p o s / 100 0 2 i / d m o d e l ) PE_{(pos,2i)}=sin(pos/1000^{2i/d_{model}}) PE(pos,2i)=sin(pos/10002i/dmodel)
P E ( p o s , 2 i + 1 ) = c o s ( p o s / 100 0 2 i / d m o d e l ) PE_{(pos,2i+1)}=cos(pos/1000^{2i/d_{model}}) PE(pos,2i+1)=cos(pos/10002i/dmodel)

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

作者也对可学习的位置 embeddings 做了实验,发现这两个版本结果几乎一样。因为正弦曲线允许模型推断比训练时遇到的序列更长的序列,所以作者选择了正弦曲线。

4. 自注意力

这一章节,作者比较了自注意力层与递归和卷积层的各个方面,它们通常用于映射变长的符号序列表示 ( 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\in \mathbb{R}^d xi,ziRd,比如一个典型的序列转导编码器或解码器中的隐藏层。作者使用自注意力是考虑到了三个问题。

一个是每层的计算复杂度。另一个是可以并行化的计算量,以所需的最小序列操作的个数来衡量。

第三个就是网络中长距离依赖之间的路径长度。在许多序列转导任务上,学习长距离依赖都是个关键挑战。影响学习这种依赖性能力的一个关键因素就是,前向和后向信号必须在网络中传播的路径长度。输入和输出序列中任意位置的组合之间的这些路径越短,长距离依赖性学习就越容易。因此,作者也比较了由不同层类型组成的网络中,任意两个输入和输出位置之间最大的路径长度。

如表1所示,自注意力层将所有位置连接到恒定数量的顺序执行的操作,而递归层需要 O ( n ) O(n) O(n)顺序操作。在计算复杂度方面,当序列长度 n n n小于表示维度 d d d时,自注意力层比递归层快。这是机器翻译中最先进的模型最常见的情况。为了提高涉及很长序列的任务的计算性能,可以将自注意力限制在仅考虑大小为 r r r的邻域内。 这会将最大路径长度增加到 O ( n / r ) O(n/r) O(n/r)

内核宽度为 k < n kk<n的单层卷积不会连接每一对输入和输出的位置。要这么做,在临近内核的情况下,需要 O ( n / k ) O(n/k) O(n/k)个卷积层,在扩展卷积的情况下需要 O ( log ⁡ k ( n ) ) O(\log_k(n)) O(logk(n))个层,它们增加了网络中任意两个位置之间最长路径的长度。卷积层通常比递归层更昂贵,与因子 k k k有关。然而,可分卷积大幅度减少复杂度到 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,一个可分卷积的复杂度等同于自注意力层和 point-wise 前向层的组合,即本文模型采用的方法。

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

你可能感兴趣的:(NLP,注意力)