生成模型学习笔记(2):Transformer

Transformer 学习笔记

本部分来源于论文 《Attention Is All You Need》

0 摘要

  • 提出了一种新的模型 Transformer ,完全基于注意力机制,彻底省去了卷积和递归。
  • 在两个机器翻译的任务上证明了该模型质量上更优同时由于并行化更好导致所需的训练时间更少。
  • 可以很好的应用到其他的任务上。

1 介绍

  1. RNN由于其固有的训练顺序导致很难并行化训练。
  2. 大部分情况**意力机制仍然搭配RNN一起使用。
  3. Transformer 避免了循环递归,完全依赖于注意力机制来建立输入和输出之间的全局依赖关系,因此该模型对并行化的适应能力更强。

2 背景

  • 卷积神经网络的结构使得学习远距离的特征变得十分困难。
  • 自我注意力机制(内注意力机制)是一种将一个序列不同位置联系起来的机制,用来计算序列的表示。
  • 端到端的记忆网络基于一种递归注意机制,而不是序列化的递归。
  • Transformer 是第一个完全依赖于自我注意而不依赖于RNN或者卷积来计算输入和输出表示的转换模型。

3 模型架构

编码器将一个由符号 (x1, ,xn)\left ( x_{1},\cdots,x_{n} \right ) 代表的输入序列映射到连续表示的 z=(z1, ,zn)z = \left ( z_{1},\cdots,z_{n} \right ) 。给定的 zz ,解码器一次一个元素的生成输出序列 (y1, ,yn)\left ( y_{1},\cdots,y_{n} \right ) 。在每个步骤中,模型都是AR(auto-regressive)的,在生成下一步时使用之前生成的作为附加输入。

转换器就是遵循这一总体架构的一个编码器和解码器,具体架构如图一所示。

生成模型学习笔记(2):Transformer

3.1 编码器和解码器堆

编码器: 编码器由 N=6N = 6 个相同的层堆叠而成,每一层有两个子层。第一层是一个 multi-head 的自注意机制层,第二层是一个简单的、全连接的前馈网络。在两个子层之间使用一个残差链接(residual connection),然后是层标准化。也就是说,每一个子层的输出是 LayerNorm(x+Sublayer(x))LayerNorm\left( x + Sublayer\left( x \right) \right) ,其中 Sublayer(x)Sublayer\left( x \right) 是子层自己实现的函数。为了使残差链接更加方便,这个模型里所有的子层,包括嵌入层(embedding layers),产生的输出维度 dmodel=512d_{model} = 512

解码器: 解码器同样是由 N=6N = 6 个相同的层堆叠而成。除了每个编码器的两个子层之外,解码器还有第三个子层,用来对编码器的输出进行多头注意力机制计算。同样的,在每个子层做残差链接以及层标准化。同时修改了解码器中的自注意层防止注意到之后的位置。这种屏蔽机制加上输出嵌入层偏移了一个位置确保位置 ii 的预测只依赖于 ii 之前位置的数据。

3.2 注意力(attention)

注意力函数可以被描述为将一个 query 和一组键值对映射到输出,其中 query 、 key 、 values 和输出全部都是向量。输出计算为值的加权和,其中分配给每个值的权重由 query 的兼容性函数和对应的 key 来计算。

生成模型学习笔记(2):Transformer

3.2.1 点积注意力(Dot-Product Attention)

输入由 queries ,keys的维度 dkd_{k} ,values的维度 dvd_{v} 组成。利用所有的keys来计算query,每个都除以 dk\sqrt{d_{k}} ,并利用一个 softmax 函数来获得 values 的权重。

在实际操作中,作者同时计算一组 query 上的注意力函数,并将其打包到一个矩阵 QQ 中。keys 和 values 也分别被打包到矩阵 K,VK,V 中。输出矩阵的计算方法如下:

(1)Attention(Q,K,V)=softmax(QKTdk)V Attention\left ( Q,K,V \right ) = softmax\left ( \frac{QK^{T}}{\sqrt{d_{k}}} \right )V \tag{1}

两种最常用的注意力函数是加法注意力(additive attention)和点积注意力(dot-product attention)。除了比例因子 1dk\frac{1}{\sqrt{d_{k}}} 之外,点积注意力和本文的算法相同。加法注意力函数是利用带有单个隐藏层的前馈神经网络来计算兼容性函数。虽然这两种方法在理论上的复杂度相似,但是由于点积注意力可以使用高度优化的矩阵乘法代码来实现,因此其在实际操作中更快也更节省空间。

dkd_{k} 值较小的情况下两种方法的性能是相似的,但是对于较大的 dkd_{k} 值来说,在不缩放的前提下加法注意力是优于点积注意力的。作者怀疑对于较大的 dkd_{k} 值来说,点积的大小会增大,导致把 softmax 函数推到一个梯度非常小的区域。为了抵消这个影响,作者将点积乘上了 1dk\frac{1}{\sqrt{d_{k}}}

3.2.2 多头注意力(Multi-Head Attention)

与使用 dmodeld_{model} 维 keys values queries 的单一注意力函数相比,采用不同的、已经训练好的线性映射模型分别把 queries keys values 映射到 dkd_{k}dkd_{k}dvd_{v} 三个维度上是有益的。在每一个 queries keys values 的投影版本上并行的执行注意力机制,生成 dvd_{v} 维的输出结果。这些得到的值被连接起来进行再进行一次映射到最终结果,如图二所示。

多头注意力机制允许模型再不同的位置一起关注来组不同子空间的信息,用一个注意力头来平均抑制这种情况。

MultiHead(Q,K,V)=Concat(head1, ,headh)WO MultiHead\left ( Q,K,V \right ) = Concat\left ( head_{1},\cdots,head_{h} \right )W^{O}

headi=Attention(QWiQ,KWiK,VWiV)head_{i} = Attention\left ( QW_{i}^{Q},KW_{i}^{K},VW_{i}^{V} \right )

其中映射是参数矩阵 WiQRdmodel×dkW_{i}^{Q} \in \mathbb{R}^{d_{model} \times d_{k}}WiKRdmodel×dkW_{i}^{K} \in \mathbb{R}^{d_{model} \times d_{k}}WiVRdmodel×dvW_{i}^{V} \in \mathbb{R}^{d_{model} \times d_{v}}WiORhdv×dmodelW_{i}^{O} \in \mathbb{R}^{ hd_{v} \times d_{model}}

3.2.3 注意力机制在模型当中的应用

Transformer模型在三个不同的地方利用了多头注意力机制。

  • 在编码-解码器注意力层中,来自于前一层解码器的 queries ,和来源于编码器输出的存储 keys values。这使得解码器中的每个位置都可以出现在输入序列的所有位置上,这模拟了 seq2seq 模型中典型的编码-解码器的注意力机制。
  • 编码器包含self-attention层。在一个self-attention层中,所有的 keys values queries 都来源于同一个位置,在本例中是编码器上一层的输出。编码器中的每一个位置都可以处理编码器上一层的所有位置。
  • 类似的,解码器中的self-attention层允许解码器中的每个位置处理解码器中直到并包含当前位置的所有位置。为了保证解码器的自回归特性,需要防止解码器中向左的信息流动。我们在点积注意力机制之内通过屏蔽(设置为 -\infty )相当于非法链接的 softmax 输入的所有值来实现。

3.3 位置全链接(Position-wise)前馈网络

除了 attention 子层,每一层编码器和解码器都包含了一个分别应用于每个位置上并且相同的全连接前馈神经网络。它由两个线性变换组成,中间采用一个 ReLU **。

(2)FFN(x)=max(0,xW1+b1)W2+b2 FFN\left(x\right) = \max \left(0,xW_{1}+b_{1}\right)W_{2} + b_{2} \tag{2}

虽然在不同位置上的线性变换是相同的,但是它们在不同的层之间使用不同的参数。另一种描述方法是使用两个 kernel size 为1的卷积。

3.4 嵌入和softmax

和其他的序列变换模型类似,transformer 模型利用学习好的嵌入层来把输入符号和输出符号转化成 dmodeld_{model} 维的向量。同样的也利用训练好的线性变换和 softmax 函数把解码器的输出转化为预测下一个符号的概率。在 transformer 模型中,在两个嵌入层之间共享相同的权重矩阵和 pre-softmax 线性变换。在嵌入层,把这些权重乘以 dmodel\sqrt{d_{model}}

3.5 位置编码

由于模型中不包含递归和卷积,为了能够使模型可以利用序列的顺序,作者将位置编码田间道编码器和解码器底部的输入嵌入中。位置编码和嵌入层有相同的维度,因此可以对二者进行求和。有许多的位置编码方式可供选择,包括学习的和固定的。在当前模型中,作者选择了不同频率的正弦和余弦函数:

PE(pos,2i)=sin(pos/100002i/dmodel)PE_{\left ( pos,2i \right )} = \sin \left ( pos/10000^{2i/d_{model}} \right )

PE(pos,2i+1)=cos(pos/100002i/dmodel)PE_{\left ( pos,2i+1 \right )} = \cos \left ( pos/10000^{2i/d_{model}} \right )

其中 pospos是位置 ii 是维数。也就是说,位置编码的每个维度对应着一个正弦曲线,波长形成了一个从 2π2\pi100002π10000 \cdot 2\pi 的等比数列。这个函数可以让模型很容易的学习相对位置,因为对于任意的固定偏移量 kkPEpos+kPE_{pos+k} 可以被认为是一个关于 PEposPE_{pos} 的线性函数。同时它可能允许模型推断出比训练遇到的更长的序列长度。

4 为什么选择 self-attention

  • self-attention 机制
  • 循环递归网络
  • 卷积网络

之间,比较用来把 (x1, ,xn)\left( x_{1}, \cdots ,x_{n} \right) 输入映射到 (z1, ,zn)\left( z_{1}, \cdots ,z_{n} \right) 输出这个任务的

  • 每层的总计算复杂度。
  • 由所需的最小操作数来衡量的可以并行化的计算量
  • 网络中长距离依赖的路径长度

在许多序列转换任务中,远距离依赖关系是一个关键的挑战。影响学习这种依赖关系的一个关键因素是在网络中前向和后向信号必须经过的路径长度。输入和输出序列中任意位置的这种组合的距离越短,就越容易学习这些长距离的依赖关系。因此还比较了由不同类型组成的网络中任意两个输入输出位置之间的最大路径长度。

生成模型学习笔记(2):Transformer

就像在表一中提到的一样,self-attention 网络只需要一个常数次数的操作就可以把所有的位置连接起来,而循环层需要 O(n)O\left( n \right) 个操作。在计算复杂度的方面,当序列长度 nn 小于表示维数 dd 的时候,self-attention 的速度比递归层要快,这是最常见的情况,就像 word-piece 和 byte-pair 这些基于句子的最先进的机器翻译模型。为了提高涉及非常长的序列的任务的计算性能,可以将 self-attention 限制在只考虑输入序列中以各自的输出为中心的距离为 rr 的一个邻域。这将把最大路径长度增加到 O(n/r)O\left(n/r\right)

一个内核宽度 k<nk < n 的卷积层不能链接输入输出的所有位置。

同时作为附加的优势,self-attention 模型可以产生更多的可解释模型。单个的注意力头不仅学会了执行不同的任务,很多还表现出于句子的句法和语义相关的行为。

5 结论

模型的训练与结果在此省略,想要了解该部分请自行翻阅原始论文。

对于翻译任务, Transformer 可以比基于循环或者卷积的结构训练的更快。