Attention Is All You Need 论文精读

题目:Attention Is All You Need

论文地址:NIPS 2017 1706

Abstract 摘要

  主流的序列转导模型基于复杂的递归或卷积神经网络,包括编码器和解码器。性能最好的模型还通过注意力机制连接编码器和解码器。我们提出了一种全新且简单的网络架构——Transformer,它完全基于注意力机制,彻底摒弃了循环和卷积。在两项机器翻译任务上的实验表明,这些模型在质量上更胜一筹,同时具备出色的并行性,训练耗时也大幅减少。在WMT 2014 英德翻译任务中,我们的模型达到了28.4的BLEU值,超越了包括集成模型在内的现有最优结果,BLEU值提高了2个点。在WMT 2014英法翻译任务的单模型状态下,我们的模型在8块GPU上训练3.5天后,BLEU分数达到了41.8,仅耗费了最佳模型训练成本的一小部分。我们还展示了Transformer能很好地推广到其他任务中,通过将其成功应用于使用大量和有限训练数据的英语成分句法分析任务。

1 Introduction 引言

  循环神经网络,尤其是长短时记忆网络(LSTM)[13] 以及门控循环神经网络 [7] ,已在序列建模和转导问题(如语言建模和机器翻译 [35, 2, 5] )中成为公认的先进方法。人们进行了大量努力,不断拓展循环语言模型以及编码器 - 解码器架构的边界 [38, 24, 15] 。

1.1 循环模型:顺序计算的限制

  循环模型通常依据输入和输出序列的符号位置进行因子计算。将这些位置计算时间步相对应,模型会生成一系列隐藏状态 h t h_t ht h t h_t ht 是前一隐藏状态 h t − 1 h_{t - 1} ht1 与位置 t t t 处输入的函数。这种本质上的顺序性特征,使得长序列样本难以进行并行计算,因为内存限制了跨样本的批处理操作。近期的研究通过因式分解技巧 [21] 和条件计算 [32] 在计算效率上取得了显著提升,在后者情况下还改善了模型性能。然而,顺序计算这一根本限制依然存在。

1.2 注意力机制

  注意力机制已成为出色的序列建模和转导模型不可或缺的一部分,它能在 不考虑输入或输出序列中位置间距离的情况下对依赖关系进行建模 [2, 19] 。不过,除少数情况 [27] 外,这类注意力机制通常与循环网络结合使用。

1.3 Transformer架构

  在本研究中,我们提出Transformer架构,它摒弃了循环结构,完全依靠注意力机制来构建输入与输出之间的全局依赖关系。Transformer极大地提升了并行计算能力,在8块P100 GPU上仅训练12小时,就能在翻译质量上达到新的最优水平。

2 Background 背景

2.1 减少顺序计算的目标

  减少顺序计算的目标也是扩展神经GPU [16]、ByteNet [18] 和ConvS2S [9] 的基础,所有这些模型都使用卷积神经网络作为基本构建模块,为所有输入和输出位置并行计算隐藏表示。在这些模型中,将两个任意输入或输出位置的信号关联起来所需的操作数量,在ConvS2S中随位置间距离线性增长,在ByteNet中呈对数增长。这使得学习远距离位置之间的依赖关系变得更加困难 [12] 。在Transformer中,这一数量减少为一个常数,尽管代价是有效分辨率降低,即通过平均注意力加权位置来实现,我们通过3.2.2节所述的多头注意力来应对这一影响。

2.2 自注意力

  自注意力(有时称为内部注意力)是一种注意力机制,用于关联单个序列的不同位置,以计算该序列的表示。自注意力已成功应用于各种任务,包括阅读理解、抽象文本摘要、文本蕴含以及学习与任务无关的句子表示 [4, 27, 28, 22] 。

2.3 端到端记忆网络

  端到端记忆网络基于循环注意力机制,而不是序列设计的循环,并且已被证明在简单的语言问答和语言建模任务中表现良好[34]。

2.4 Transformer模型

  据我们所知,Transformer是第一个完全依赖自注意力来计算输入和输出表示,而不使用序列对齐的RNN和卷积的转导模型。在以下各节中,我们将描述Transformer,阐述自注意力及其在我们模型中的优势,如[17, 18] 和 [9] 。

3 Model Architecture 模型架构

  大多数具有竞争力的神经序列转导模型都具有编码器 - 解码器结构 。

神经序列转导模型是一类用于处理序列到序列转换任务的神经网络模型 ,常见于自然语言处理、语音识别等领域,旨在将一个输入序列转换为目标输出序列 。

  在这里,编码器将符号表示的输入序列 ( x 1 , … , x n ) (x_1, \ldots, x_n) (x1,,xn) 映射为连续表示的序列 z = ( z 1 , … , z n ) \mathbf{z} = (z_1, \ldots, z_n) z=(z1,,zn) 。给定 z \mathbf{z} z ,解码器随后生成符号的输出序列 ( y 1 , … , y m ) (y_1, \ldots, y_m) (y1,,ym) 。在每一步,模型都是自回归的[10],在生成下一步时,将之前生成的符号作为额外的输入。
  Transformer遵循这种总体架构,在编码器和解码器中都使用堆叠的自注意力层逐点全连接层,分别如图1的左半部分和右半部分所示。
()

3.1 Encoder and Decoder Stacks 编码器和解码器堆叠

3.1.1 Encoder 编码器

  编码器由 N = 6 N = 6 N=6个相同的层堆叠而成。每层有两个子层。第一个子层是多头自注意力机制,第二个子层是简单的逐点全连接前馈网络。我们在这两个子层周围使用残差连接 [11] ,然后进行层归一化 [1] 。也就是说,每个子层的输出是LayerNorm(x + Sublayer(x)) ,其中Sublayer(x) 是由子层本身实现的函数。在模型中,所有子层以及嵌入层都会产生维度为 d m o d e l = 512 d_{model} = 512 dmodel=512的输出。

3.1.2 Decoder 解码器

  解码器同样由 N = 6 N = 6 N=6 个相同的层堆叠而成。除了编码器中的两个子层外,解码器在多头自注意力层之上插入了第三个子层,该子层对编码器堆叠层的输出执行多头自注意力操作。与编码器类似,我们在解码器子层周围使用残差连接,然后进行层归一化。我们还对自注意力子层中的位置进行掩码,以防止后续位置参与关注。这种掩码,再加上输出嵌入会偏移一个位置的事实,确保了位置 i i i的预测仅依赖于位置小于 i i i 的已知输出。

3.2 Attention 注意力机制

  注意力函数可以描述为将一个查询向量和一组键值对映射为一个输出向量,其中查询向量键向量值向量输出向量都是向量。输出是值向量的加权和,其中分配给每个值向量的权重是通过查询向量与相应键向量的兼容性函数来计算的。

3.2.1 Scaled Dot-Product Attention 缩放点积注意力

  我们将我们所采用的特定注意力机制称为“缩放点积注意力”(见图2 )。输入由维度为 d k d_k dk 的查询向量和键向量,以及维度为 d v d_v dv 的值向量 组成。我们计算查询向量与所有键向量的点积,将每个点积结果除以 d k \sqrt{d_k} dk ,然后应用softmax函数来获取值向量上的权重。
在这里插入图片描述

  在实际应用中,我们会同时计算一组查询向量的注意力函数,将它们打包成一个矩阵 Q Q Q 。键向量和值向量也分别打包成矩阵 K K K V V V 。我们按如下方式计算输出矩阵:
Attention ( Q , K , V ) = softmax ( Q K T d k ) V (1) \text{Attention}(Q, K, V) = \text{softmax}(\frac{QK^T}{\sqrt{d_k}})V \tag{1} Attention(Q,K,V)=softmax(dk QKT)V(1)
  两种最常用的注意力函数是加法注意力 [2]点积(乘法)注意力。点积注意力与我们的算法相同,只是少了缩放因子 1 d k \frac{1}{\sqrt{d_k}} dk 1加法注意力使用一个隐藏层的前馈网络来计算兼容性。虽然从理论复杂度来看,二者相似,但点积注意力在实践中要快得多且空间效率更高,因为它可以通过高度优化的矩阵乘法代码来实现。
  对于较小的 d k d_k dk 值,两种机制表现相近,但对于较大的 d k d_k dk 值,在不进行缩放的情况下,点积注意力的表现不如加法注意力 。我们推测,对于较大的 d k d_k dk 值,点积结果会变得非常大,在矩阵运算中,这会使softmax函数进入梯度极小的区域。为解决这个问题,我们对dot - product引入缩放因子 1 d k \frac{1}{\sqrt{d_k}} dk 1

3.2.2 Multi-Head Attention 多头注意力

  我们没有使用维度为 d m o d e l d_{model} dmodel 的键向量、值向量和查询向量执行单一的注意力函数,而是发现通过不同的、可学习的线性投影,将查询向量、键向量和值向量分别投影 h h h,会很有好处。在每次投影得到的版本中,查询向量、键向量和值向量的维度分别为 d k d_k dk d k d_k dk d v d_v dv在这些投影版本上并行执行注意力函数,会产生 d v d_v dv 维的输出值。然后将这些输出值连接起来并再次投影,得到最终的值,如图2所示。
  多头注意力使模型能够同时关注来自不同位置、不同表征子空间的信息。而使用单个注意力头时,求平均的操作会抑制这种能力
MultiHead ( Q , K , V ) = Concat ( head 1 , … , head h ) W O where  head i = Attention ( Q W i Q , K W i K , V W i V ) \begin{align*} \text{MultiHead}(Q, K, V) &= \text{Concat}(\text{head}_1, \ldots, \text{head}_h)W^O \\ \text{where } \text{head}_i &= \text{Attention}(QW_i^Q, KW_i^K, VW_i^V) \end{align*} MultiHead(Q,K,V)where headi=Concat(head1,,headh)WO=Attention(QWiQ,KWiK,VWiV)
  其中投影矩阵为参数矩阵 W i Q ∈ R d m o d e l × d k W_i^Q \in \mathbb{R}^{d_{model} \times d_k} WiQRdmodel×dk W i K ∈ R d m o d e l × d k W_i^K \in \mathbb{R}^{d_{model} \times d_k} WiKRdmodel×dk W i V ∈ R d m o d e l × d v W_i^V \in \mathbb{R}^{d_{model} \times d_v} WiVRdmodel×dv W O ∈ R h d v × d m o d e l W^O \in \mathbb{R}^{hd_v \times d_{model}} WORhdv×dmodel
  在这项工作中,我们使用 h = 8 h = 8 h=8个并行注意力层,即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以三种不同方式使用多头注意力机制:

  • 在“编码器 - 解码器注意力”层查询向量来自解码器的前一层,而记忆键向量和值向量来自编码器的输出。这使得解码器中的每个位置都能够关注输入序列中的所有位置。这模仿了序列到序列模型(如[38,2,9] )中典型的编码器 - 解码器注意力机制。
  • 编码器包含自注意力层:在自注意力层中,所有的键向量、值向量和查询向量都来自同一位置,在这种情况下,来自编码器前一层的输出。因此,编码器中的每个位置都能够关注编码器前一层中的所有位置
  • 类似地,解码器中的自注意力层使解码器中的每个位置都能够关注解码器中包括该位置及之前的所有位置。我们需要防止解码器中信息向左流动,以保持自回归特性。我们在缩放点积注意力内部通过掩码操作(将输入中对应非法连接的所有值设置为 − ∞ -\infty )来实现这一点。见图2。

1.自回归特性(Autoregressive Property)
  自回归特性是指在序列生成任务(如文本翻译、语言建模)中,模型只能利用当前位置之前的上下文信息来预测当前位置的输出,而不能依赖未来的信息。这种特性模拟了人类自然语言的生成过程——逐词生成,且每次生成下一个词时只能看到已经生成的前文。
核心要点:
 (1) 单向依赖性生成第 t t t个位置的 token 时,只能依赖 1 ∼ t − 1 1 \sim t-1 1t1位置的信息,不能看到 t + 1 ∼ n t+1 \sim n t+1n 的未来信息
 (2) 因果关系约束:确保模型在推理阶段(生成新序列)时,不会“偷看到”尚未生成的内容,符合真实场景的生成逻辑。
2.为什么需要防止解码器中信息向左流动?
  在Transformer架构的解码器(Decoder)中,输入通常是已生成的序列(如翻译任务中已生成的目标语言片段)。若不做限制,解码器的注意力机制可能会出现“信息向左流动”,即当前位置的计算依赖未来位置的信息,这会破坏自回归特性。
具体问题:
 (1) 训练与推理不一致:训练时,解码器的输入是完整的目标序列(Teacher Forcing),若允许注意力机制无约束地访问所有位置,模型可能在训练中“偷用”未来信息(如预测第3词时用到第5词的信息),但在推理时只能逐词生成,无法获取未来信息,导致训练与推理结果偏差。
 (2)逻辑矛盾:生成序列的本质是因果过程(未来依赖过去),若模型在训练中依赖未来信息,会导致生成逻辑混乱(如先知道后文再生成前文)。
3.掩码(Mask)如何防止信息向左流动
 (1) 掩码的作用机制
  在解码器的缩放点积注意力(Scaled Dot-Product Attention) 中,通过因果掩码(Causal Mask) 屏蔽未来位置的信息。具体操作如下:
   - 在计算注意力权重时,对于当前位置 t t t,将 t + 1 ∼ n t+1 \sim n t+1n 位置的注意力分数设置为 − ∞ -\infty
   - 经过Softmax函数后,这些位置的注意力权重趋近于0,从而切断当前位置与未来位置的依赖关系。

 (2)数学与直观解释
  假设注意力分数矩阵为 Q K T / d k \mathbf{QK}^T / \sqrt{d_k} QKT/dk ,其中 Q \mathbf{Q} Q(查询向量)和 K \mathbf{K} K(键向量)均来自解码器的输入序列。
  - 未掩码时:每个位置 i i i 可以关注所有位置 j j j(包括 j > i j > i j>i)。
  - 应用因果掩码后:对于位置 i i i,当 j > i j > i j>i时,掩码矩阵对应位置的值为 − ∞ -\infty ,因此:
Attention Score i , j = { 原始分数 , j ≤ i − ∞ , j > i \text{Attention Score}_{i,j} = \begin{cases} \text{原始分数}, & j \leq i \\ -\infty, & j > i \end{cases} Attention Scorei,j={原始分数,,jij>i
  经过Softmax后, j > i j >i j>i的位置权重为0,即 i i i只能关注 j ≤ i j \leq i ji的位置(过去信息)。

 (3)可视化示例
  假设序列长度为4,因果掩码矩阵如下( − ∞ -\infty 用“-”表示):
[ 0 − − − 0 0 − − 0 0 0 − 0 0 0 0 ] \begin{bmatrix} 0 & - & - & - \\ 0 & 0 & - & - \\ 0 & 0 & 0 & - \\ 0 & 0 & 0 & 0 \\ \end{bmatrix} 0000000000
   - 对角线及以下 j ≤ i j \leq i ji)为合法区域,允许注意力计算;
   - 对角线以上 j > i j > i j>i)为非法区域,被掩码屏蔽。
4.为什么选择将非法值设为 − ∞ -\infty ?
 (1)Softmax的数学特性
   Softmax ( x ) = e x ∑ e x \text{Softmax}(x) = \frac{e^x}{\sum e^x} Softmax(x)=exex x = − ∞ x = -\infty x=时, e x ≈ 0 e^x \approx 0 ex0,因此对应的注意力权重趋近于0,确保未来位置的信息不被利用
 (2)计算稳定性
  直接设置为极小值(如 − 1 e 9 -1e9 1e9)在数值计算中可能不够稳定,而 − ∞ -\infty 数学上的严格屏蔽,能更可靠地切断依赖。

3.3 Position-wise Feed-Forward Networks 逐点前馈网络

  除了注意力子层之外,我们的编码器和解码器中的每一层都包含一个全连接前馈网络,该网络分别且相同地应用于每个位置。它由两个线性变换组成,中间有一个ReLU激活函数

ReLU激活函数:ReLU(x)=max(0,x)

FFN ( x ) = max ⁡ ( 0 , x W 1 + b 1 ) W 2 + b 2 (2) \text{FFN}(x) = \max(0, xW_1 + b_1)W_2 + b_2 \tag{2} FFN(x)=max(0,xW1+b1)W2+b2(2)
  虽然不同位置上的线性变换是相同的,但不同层之间使用不同的参数。另一种描述方式是将其看作两个内核大小为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 and Softmax 嵌入层与Softmax

  与其他序列转导模型类似,我们使用可学习的嵌入层,将输入标记和输出标记转换为维度为 d m o d e l d_{model} dmodel的向量 。
  我们还使用常见的可学习线性变换Softmax函数,将解码器的输出转换为预测下一个标记的概率 。
  在我们的模型中,两个嵌入层与Softmax前的线性变换共享相同的权重矩阵 ,这与文献[30]类似 。在嵌入层中,我们将这些权重乘以 d m o d e l \sqrt{d_{model}} dmodel

3.5 Positional Encoding 位置编码

  由于我们的模型既没有循环结构也没有卷积结构,为了让模型能够利用序列的顺序信息,我们必须引入一些关于序列中标记相对或绝对位置的信息。为此,我们在编码器和解码器底部的输入嵌入中添加“位置编码”
  位置编码与嵌入具有相同的维度 d m o d e l d_{model} dmodel,以便二者可以相加位置编码有多种选择,既可以学习得到,也可以是固定的
  在这项工作中,我们使用不同频率的正弦和余弦函数
P E ( p o s , 2 i ) = sin ⁡ ( p o s / 10000 2 i / d m o d e l ) P E ( p o s , 2 i + 1 ) = cos ⁡ ( p o s / 10000 2 i / d m o d e l ) \begin{align*} PE_{(pos, 2i)} &= \sin(pos / 10000^{2i / d_{model}}) \\ PE_{(pos, 2i + 1)} &= \cos(pos / 10000^{2i / d_{model}}) \end{align*} PE(pos,2i)PE(pos,2i+1)=sin(pos/100002i/dmodel)=cos(pos/100002i/dmodel)
  其中 p o s pos pos 是位置, i i i 是维度。也就是说,位置编码的每个维度对应一个正弦曲线。波长从 2 π 2\pi 2π 10000 ⋅ 2 π 10000 \cdot 2\pi 100002π 形成等比数列。我们选择这个函数,是因为我们假设它能让模型轻松学习到标记之间的相对位置,因为对于任何偏移量 k k k P E p o s + k PE_{pos + k} PEpos+k都可以表示为 P E p o s PE_{pos} PEpos的线性函数。

为什么选择这种设计?
 1. 相对位置可表示为线性函数
  对于任意位置偏移量 k k k,位置 pos + k \text{pos}+k pos+k的编码可以表示为位置 pos \text{pos} pos的编码的线性组合。具体来说:
P E pos + k = P E pos ⋅ R ( k ) PE_{\text{pos}+k} =PE_{\text{pos}} \cdot R(k) PEpos+k=PEposR(k)
  其中 R ( k ) R(k) R(k) 是一个仅依赖于 k k k的旋转矩阵。这一特性使得模型可以通过线性运算轻松学习相对位置关系。
 2. 数学推导(以单个维度为例)
  根据三角恒等式:
sin ⁡ ( a + b ) = sin ⁡ ( a ) cos ⁡ ( b ) + cos ⁡ ( a ) sin ⁡ ( b ) \sin(a+b) = \sin(a)\cos(b) + \cos(a)\sin(b) sin(a+b)=sin(a)cos(b)+cos(a)sin(b)
cos ⁡ ( a + b ) = cos ⁡ ( a ) cos ⁡ ( b ) − sin ⁡ ( a ) sin ⁡ ( b ) \cos(a+b) = \cos(a)\cos(b) - \sin(a)\sin(b) cos(a+b)=cos(a)cos(b)sin(a)sin(b)
  对于位置编码的某一维度 2 i 2i 2i
sin ⁡ ( pos + k 10000 2 i / d model ) = sin ⁡ ( pos 10000 2 i / d model ) cos ⁡ ( k 10000 2 i / d model ) + cos ⁡ ( pos 10000 2 i / d model ) sin ⁡ ( k 10000 2 i / d model ) \sin\left(\frac{\text{pos}+k}{10000^{2i/d_{\text{model}}}}\right) =\sin\left(\frac{\text{pos}}{10000^{2i/d_{\text{model}}}}\right)\cos\left(\frac{k}{10000^{2i/d_{\text{model}}}}\right)+ \cos\left(\frac{\text{pos}}{10000^{2i/d_{\text{model}}}}\right)\sin\left(\frac{k}{10000^{2i/d_{\text{model}}}}\right) sin(100002i/dmodelpos+k)=sin(100002i/dmodelpos)cos(100002i/dmodelk)+cos(100002i/dmodelpos)sin(100002i/dmodelk)
  即 sin ⁡ ( pos + k ) \sin(\text{pos}+k) sin(pos+k)可以表示为 sin ⁡ ( pos ) \sin(\text{pos}) sin(pos) cos ⁡ ( pos ) \cos(\text{pos}) cos(pos)的线性组合,系数仅与 k k k有关。

 3. 泛化到长序列
  - 正弦余弦函数的周期性允许模型泛化到训练时未见的序列长度(例如,训练时序列最长为512,推理时可处理长度为1000的序列)。
  - 相比之下,可学习的位置编码(如将位置ID作为输入训练嵌入层)通常受限于训练时的最大序列长度

  我们也尝试过使用可学习的位置嵌入 ,发现这两种版本产生的结果几乎相同(见表3的(E)行)。我们 选择正弦版本,是因为它可以让模型外推到比训练中遇到的序列长度更长的序列

4 Why Self-Attention 为什么使用自注意力机制

4.1 三个关键因素

  在本节中,我们将自注意力层的多个方面,与常用于将一个可变长度的符号表示序列 ( x 1 , … , x n ) (x_1, \ldots, x_n) (x1,,xn) 映射为另一个等长序列 ( z 1 , … , z n ) (z_1, \ldots, z_n) (z1,,zn) (其中 x i , z i ∈ R d x_i, z_i \in \mathbb{R}^d xi,ziRd,例如典型序列转导编码器或解码器中的隐藏层)的循环层卷积层进行比较。在考虑使用自注意力机制时,我们思考了三个关键因素
  其一是每层的总计算复杂度
  其二是能够并行化的计算量,通过所需顺序操作的最小数量来衡量。
  其三是网络中任意两个位置之间最长路径的长度。学习长距离依赖关系是许多序列转导任务中的关键挑战。影响网络学习这些依赖关系能力的一个关键因素是前向和后向信号在输入和输出序列中遍历的路径长度。路径越短,任意位置组合学习长距离依赖关系就越容易 [12] 。因此,我们还比较了由不同层类型组成的网络中,任意两个输入和输出位置之间的最长路径长度

4.2 自注意力层 vs 循环层

  如表1所示,自注意力层将所有位置与固定数量的顺序执行操作连接起来。在计算复杂度方面,当序列长度 n n n小于表示维度 d d d 时(在机器翻译中,最先进模型使用的句子表示,如词块 [38] 和字节对 [31] 表示,大多属于这种情况),自注意力层比循环层更快。对于涉及很长序列的任务,通过仅考虑围绕相应输出位置的输入序列中大小为 r r r 的邻域,可以限制自注意力的计算量。这会增加最大路径长度至 O ( n / r ) O(n / r) O(n/r) 。我们计划在未来的工作中进一步研究这种方法。
在这里插入图片描述

4.3 自注意力层 vs 卷积层

  单个内核大小 k < n k < n k<n 的卷积层不会连接所有的输入和输出位置对。这样做需要 O ( n / k ) O(n / k) O(n/k) 个卷积层(在扩张卷积的情况下,内核大小增加,或 O ( log ⁡ k n ) O(\log_{k}n) O(logkn) ),从而增加网络中任意两个位置之间最长路径的长度。卷积层通常比循环层更昂贵,因子为(k) 。然而,对于内核大小 k = n k = n k=n可分离卷积 [16] ,其复杂度会显著降低,为 O ( k ⋅ d ⋅ n + d 2 ) O(k \cdot d \cdot n + d^2) O(kdn+d2) 。即使 k = n k = n k=n ,可分离卷积的复杂度也与我们采用的自注意力层和逐点前馈层组合的方法相当。

4.4 可解释性

  作为一个附带好处,自注意力机制可以产生更具可解释性的模型。我们检查了模型中的注意力分布,并在附录中展示和讨论了示例。不仅各个注意力头能清晰地学习和执行不同任务,而且许多注意力头似乎表现出与句子的句法和语义结构相关的行为

5 Training 训练

  本节描述我们模型的训练方案。

5.1 Training Data and Batching 训练数据与批处理

  我们在标准的WMT 2014 英德 数据集上进行训练,该数据集包含约450万个句子对。句子采用字节对编码 [3] 进行编码,这种编码方式使用一个源 - 目标共享词汇表,约有37000个词元。
  对于英语-法语,我们使用了更大的WMT 2014英语-法语数据集,该数据集由3600万个句子组成,并将标记拆分为32000个单词的词汇[38]
  句子对按大致的序列长度分组在一起。每个训练批包含一组句子对,其中包含大约25000个源标记25000个目标标记

5.2 Hardware and Schedule 硬件与训练计划

  我们在一台配备8块NVIDIA P100 GPU的机器上训练模型。
  对于我们使用整篇论文中描述的超参数的基础模型,每个训练步骤大约需要0.4秒。我们对基础模型进行了总共100000步或12小时的训练。
  对于我们的大型模型(如表3底部所示),步进时间为1.0秒。大模型训练了300000步(3.5天)。

5.3 Optimizer 优化器

  我们使用Adam优化器[20] ,其参数 β 1 = 0.9 \beta_1 = 0.9 β1=0.9 β 2 = 0.98 \beta_2 = 0.98 β2=0.98 ϵ = 10 − 9 \epsilon = 10^{-9} ϵ=109
  在训练过程中,我们根据以下公式调整学习率
lrate = d model − 0.5 ⋅ min ⁡ ( step_num − 0.5 , step_num ⋅ warmup_steps − 1.5 ) (3) \text{lrate} = d_{\text{model}}^{-0.5} \cdot \min(\text{step\_num}^{-0.5}, \text{step\_num} \cdot \text{warmup\_steps}^{-1.5}) \tag{3} lrate=dmodel0.5min(step_num0.5,step_numwarmup_steps1.5)(3)
  这意味着在 warmup_steps \text{warmup\_steps} warmup_steps 个训练步骤中,学习率线性增加;在此之后,学习率与训练步数的平方根成反比下降。我们设置 warmup_steps = 4000 \text{warmup\_steps} = 4000 warmup_steps=4000

5.4 Regularization 正则化

  我们在训练过程中采用三种类型的正则化方法

5.4.1 Residual Dropout 残差丢弃

  我们在每个子层的输出添加到子层输入并进行归一化之前,对其应用丢弃法 [33] 。
  此外,我们还对编码器和解码器堆叠中嵌入向量与位置编码的和应用丢弃法
  对于基础模型,我们使用的丢弃率 P d r o p = 0.1 P_{drop} = 0.1 Pdrop=0.1

5.4.2 Label Smoothing 标签平滑

  在训练过程中,我们采用值 ϵ l s = 0.1 \epsilon_{ls} = 0.1 ϵls=0.1标签平滑方法 [36] 。这会增加模型的困惑度,因为模型会变得更加“不确定”,但它能提高准确率和BLEU分数

BLEU 分数(Bilingual Evaluation Understudy)是机器翻译领域最常用的自动评价指标之一,用于衡量机器生成的译文与人工参考译文的相似程度。它由 IBM 团队于 2002 年提出,核心思想是通过统计n-gram(n 元语法)的匹配度来评估译文质量,具有计算高效、可复现的优点。

6 Results 结果

6.1 Machine Translation 机器翻译

6.1.1 英德翻译任务

  在WMT 2014 英德翻译任务 中,大型Transformer模型(表2中的Transformer (big) ) 超越了此前最佳的已报道模型(包括集成模型),BLEU得分提高超过2.0,达到了新的当前最优水平(28.4)。该模型的配置列于表3底部行。在8块P100 GPU上训练耗时3.5天。即使是我们的基础模型,也超越了之前许多模型的集成结果。

在这里插入图片描述

6.1.2 英法翻译任务

  在WMT 2014 英法翻译任务 中,我们的大型模型取得了41.0的BLEU得分,超越了此前所有已发表的单一模型,且训练成本不到之前最优模型的1/4 。用于英法翻译的Transformer (big) 模型使用的丢弃率 P d r o p = 0.1 P_{drop} = 0.1 Pdrop=0.1 ,而不是 0.3 0.3 0.3

6.1.3 翻译任务训练和验证的设定

  对于基础模型,我们使用最后5个检查点的平均值得到单个模型,这些检查点每隔10分钟保存一次。对于大型模型,我们对最后20个检查点取平均
  我们使用束搜索,束宽为4,长度惩罚 α = 0.6 \alpha = 0.6 α=0.6,这些超参数是在开发集上实验后选定的。我们将推理时的最大输出长度设置为输入长度加50,但在可能的情况下尽早终止 。

1.束搜索(Beam Search)核心思想
  为什么需要束搜索?
   - 贪心搜索局限性:每步仅选概率最高词,可能错过全局最优序列。
   - 束搜索策略每步保留概率最高的 k 个候选序列(k 为束宽),平衡效率与精度。
2.束宽(Beam Width)=4 的作用
  参数含义:每步保留概率最高的4个候选序列。
  权衡:小束宽(如k=1)退化为贪心搜索;大束宽计算开销大,k=4在机器翻译中常平衡效果与效率。
3.长度惩罚(Length Penalty)α=0.6 的作用
  (1)为什么需要惩罚?
   模型倾向生成短序列(概率连乘导致长序列总概率低)。
  (2) 长度惩罚公式的公式影响
   α=0.6 时,短序列惩罚小,长序列惩罚适中,鼓励生成合理长度输出。
4.最大输出长度与提前终止
  最大长度:设为输入长度+50,防止无限生成,覆盖多数场景。
  提前终止:生成 <eos> 或分数低于阈值时终止,减少计算量。

6.1.4 结果+训练成本比较

  表2总结了我们的结果,并将我们的翻译质量和训练成本与文献中的其他模型架构进行了比较。我们通过将训练时间使用的GPU数量以及每个GPU的持续单精度浮点容量的估计值 相乘,来估计训练一个模型所需的浮点运算次数

6.2 Model Variations 模型变体

  为了评估Transformer 不同组件的重要性 ,我们以不同方式对基础模型进行改动,在开发集newstest2013上测量英德翻译任务中的性能变化。我们采用前一节所述的束搜索方法,但不进行检查点平均。我们在表3中展示这些结果。
在这里插入图片描述

6.2.1 改变注意力头的数量+注意力键和值的维度

  在表3的(A)行,我们改变注意力头的数量以及注意力键和值的维度,同时保持计算量不变,如3.2.2节所述。单头注意力比最佳设置的BLEU得分低0.9,而头数过多时翻译质量也会下降。

6.2.2 注意力键的大小 d k d_k dk+点积函数

  在表3的(B)行,我们发现 减少注意力键的大小 d k d_k dk 会损害模型质量。这表明确定兼容性的简单点积函数可能并非最佳选择,使用更复杂的兼容性函数可能有益。

6.2.3 更大的模型+丢弃法

  我们在 ( C ) (C) (C)行和 ( D ) (D) (D)行进一步观察到,更大的模型效果更好,并且丢弃法对防止过拟合非常有帮助

6.2.4 可学习的位置嵌入 vs 正弦位置编码

  在(E)行,我们用可学习的位置嵌入替代正弦位置编码,结果与基础模型几乎相同。

6.3 English Constituency Parsing 英语成分句法分析

6.3.1 探索泛化性:对英语成分句法进行分析

  为了评估Transformer是否能泛化到其他任务,我们对英语成分句法分析进行了实验。这项任务存在特定挑战:输出受到很强的结构约束,并且显著长于输入。此外,循环神经网络(RNN)的序列到序列模型在小数据体制下难以达到当前最优结果 [37] 。

6.3.2 数据集

  我们宾州树库(Penn Treebank)的 《华尔街日报》(WSJ) 部分(约40,000个训练句子)上训练了一个4层的Transformer,其中 d m o d e l = 1024 d_{model} = 1024 dmodel=1024
  我们还在半监督设置下进行训练,使用更大置信度的BerkeleyParser语料库(约1700万个句子) [37] 。我们仅为WSJ设置使用16,000个词元的词汇表为半监督设置使用32,000个词元的词汇表

半监督学习(Semi-Supervised Learning)的定义
核心概念:利用少量标注数据大量未标注数据进行训练的机器学习范式。
典型流程
  1. 无标注数据预训练:用大量未标注数据训练模型(如语言模型预训练),学习通用语义表示。
  2. 标注数据微调:用少量标注数据调整模型,适配具体任务(如分类、翻译)。
优势:降低标注成本,利用海量未标注数据提升模型泛化能力。

6.3.3 开发集上进行超参数的选择

  我们在第22节开发集上进行少量实验,以选择丢弃率注意力残差(section 5.4)学习率以及束宽,所有其他参数与英德基础翻译模型保持不变。在推理过程中,我们将最大输出长度增加到输入长度加300。对于仅使用WSJ数据和半监督设置,我们都使用束宽为21, α = 0.3 \alpha = 0.3 α=0.3

1.注意力机制(Attention Mechanism)
核心思想
  模拟人类视觉的注意力聚焦能力,让模型在处理序列时动态分配不同位置的权重,重点关注关键信息。
在Transformer中的应用
  - 自注意力(Self-Attention):计算序列内部各位置的依赖关系(如“我吃饭”中“我”是动作主体)。
  - 交叉注意力(Cross-Attention):处理编码器与解码器之间的交互(如机器翻译中源语言与目标语言的对齐)。
 ;作用:捕获长距离依赖、提升模型对语义关联的敏感度。
2.残差连接(Residual Connection)
核心思想:在神经网络层间添加跳跃连接,使梯度直接传递,缓解深层网络的“梯度消失”问题。
数学表达 输出 = 输入 + 层映射 ( 输入 ) \text{输出} = \text{输入} + \text{层映射}(输入) 输出=输入+层映射(输入)
在Transformer中的应用
  - 每个子层(如注意力层、前馈网络层)后均添加残差连接和层归一化(LayerNorm)。
  - 确保深层网络仍能有效优化,支持模型堆叠更多层(如12层、24层Transformer)。

6.3.4 结果

  我们在表4中的结果表明,在没有针对特定任务进行调优的情况下,我们的模型表现出人意料地好,优于除递归神经网络语法(Recurrent Neural Network Grammar) [8] 之外的所有先前报道的模型。
  与RNN序列到序列模型 [37] 相比,在40,000个句子的WSJ训练集上进行训练时,Transformer的表现优于BerkeleyParser [29] 。
在这里插入图片描述

7 Conclusion 结论

  在这项工作中,我们提出了Transformer,这是第一个完全基于注意力机制的序列转导模型,它用多头自注意力机制取代了编码器 - 解码器架构中最常用的循环层
  对于翻译任务,与基于循环层或卷积层的架构相比,Transformer的训练速度要快得多。在WMT 2014英德和WMT 2014英法翻译任务中,我们的模型都达到了当前最优水平。在前者任务中,我们的最佳模型甚至超越了此前所有已报道的集成模型。
  我们对基于注意力机制的模型的未来发展前景感到兴奋,并计划将其应用于其他任务。我们打算拓展Transformer,使其能够处理文本以外的输入和输出模态,并研究如何让局部、受限的注意力机制更高效地处理大型输入和输出,如图像、音频和视频。让生成过程减少序列依赖性是我们的另一项研究目标。(Making generation less sequential is another research goals of ours.

  我们用于训练和评估模型的代码可在https://github.com/tensorflow/tensor2tensor获取。

Acknowledgements 致谢

  我们感谢Nal Kalchbrenner和Stephan Gouws富有成效的讨论、建议和启发。

在这里插入图片描述

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

### 关于 'Attention Is All You Need' 论文模型的 PyTorch 实现 在探索 'Attention Is All You Need' 这篇经典论文中的 Transformer 模型时,可以利用开源社区提供的资源来快速获取其实现代码。以下是对该问题的具体解答: #### 开源实现 存在一个基于 PyTorch 的高质量实现项目,该项目实现了 'Attention Is All You Need' 中描述的核心机制——Transformer 模型[^1]。此项目的地址为:[https://gitcode.com/gh_mirrors/at/attention-is-all-you-need-pytorch](https://gitcode.com/gh_mirrors/at/attention-is-all-you-need-pytorch),它提供了完整的代码框架和详细的文档说明。 #### 基础知识需求 为了更好地理解和运行这些代码,建议学习者具备一定的 Python 编程能力和 PyTorch 使用经验。此外,熟悉 Transformer 架构及其核心概念(如自注意力机制)会非常有帮助[^2]。如果尚未掌握这些基础知识,则可能需要额外的时间去深入研究相关内容。 #### 数据准备与训练流程概述 除了理论部分外,在实际操作过程中还需要考虑数据预处理环节的重要性。例如,在某些教程中提到过应该先准备好相应的语料库作为输入给定模型进行训练前准备工作之一[^3]。因此,在尝试复现整个过程之前,请确保已经了解清楚所需的数据形式以及如何正确加载它们到程序当中。 以下是简单的代码片段展示如何定义一个多头注意层(MultiHead Attention Layer): ```python import torch.nn as nn import math class MultiHeadedAttention(nn.Module): def __init__(self, h, d_model, dropout=0.1): super().__init__() assert d_model % h == 0 self.d_k = d_model // h self.h = h self.linears = clones(nn.Linear(d_model, d_model), 4) self.attn = None self.dropout = nn.Dropout(p=dropout) def forward(self, query, key, value, mask=None): if mask is not None: mask = mask.unsqueeze(1) nbatches = query.size(0) query, key, value = \ [l(x).view(nbatches, -1, self.h, self.d_k).transpose(1, 2) for l, x in zip(self.linears, (query, key, value))] x, self.attn = attention(query, key, value, mask=mask, dropout=self.dropout) x = x.transpose(1, 2).contiguous()\ .view(nbatches, -1, self.h * self.d_k) return self.linears[-1](x) ``` 上述代码展示了多头注意力模块的设计思路,并通过线性变换分别作用于查询(Query)、键(Key) 及值(Value) 上完成计算。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值