- Vaswani A, Shazeer N, Parmar N, et al. Attention is all you need[C]//Advances in neural information processing systems. 2017: 5998-6008.
Introduction
大名鼎鼎的Transformer,仅依赖于注意力机制,完全不使用RNN和CNN的序列模型
RNN,LSTM,GNU是处理序列模型的几种最优方法。然而循环神经网络中总是沿着词元位置进行计算,这种顺序性阻碍了训练的并行化,这也严重影响了内存对batch的限制程度。
注意力机制也是成功的模型中必不可少的一部分,其可以考虑到模型中的依赖关系。大部分情况下注意力都和RNN捆绑在了一起。
Transformer,完全避开了RNN,并且完全依赖注意力机制来抽取输入和输出的全局关系。并且能有更好的并行化。
相关工作:
- Self-Attention:提取序列不同位置联系的一种方式,可以计算出一个序列的表示形式。
- End-to-end memory :基于循环注意力机制,而不是序列循环网络,在语言建模任务上有优秀表现。
Model Architecture
大部分序列转换模型都是 编码器-解码器 框架。其中编码器将输入序列从离散的符号表示映射到一个连续表示\(z\)。得到\(z\)之后,解码器逐时间步去生成输出序列\((y_1,....,y_m)\)。Transformer也是在这个大框架之下:
编码器-解码器:
- 编码器:主要模块由两个子层Multi-head self-attention和position-wise 全连接构成,并且每个子层都是用了一个残差连接。
- 解码器:增加了一个Masked层,用于处理编码器的输出。同样每层都是用了残差连接设计。另外修改了self-attention层防止前面的元素受到后面的元素的影响。这样对位置i的预测仅能依赖于位置小于i的编码器输出。
Attention
Scaled Dot-Product Attention
两种最常用的注意力评分函数是 加性注意力 和 点积注意力。点积由于矩阵计算的优化,计算上更加效率。然而在大批量上加性注意力效果往往能够超越点积注意力。论文认为这是因为在大批量下,点积结果会数量级膨胀,导致softmax达到一个梯度极小的区域,因此为了解决这种现象,提出了放缩的点积注意力。
\[ a(\mathbf{q}, \mathbf{k})=\mathbf{q}^{\top}\mathbf{k}/\sqrt{d} \]
其中\(d\)为向量长度(显然query和key需要相同长度)。
Multi-Head Attention
相比于在数据上使用单一的一个注意力机制,Multi-Head Attention可以联合多种方式学到的不同信息。其通过\(h\)个可学习的线性变换将query,key,value分别进行线性投影到\(h\)个空间的\(d_k,d_k,d_v\)维度。再在这\(h\)种数据上并行使用注意力机制,最终每个空间都得到\(d_v\)维的output values。将它们都连接起来,并且再进行一次投影,生成最终的values:
\[ MultiHead(Q,K,V)=Concat(h_1,...,h_h)W^O \\ where \ h_i=Attention(QW_i^Q,KW_I^K,VW_I^V) \]
实践中使用了8个head,每个维度都相应的除以8进行降维:\(d_k=d_k=d_{model}/8=64\)。因为由于每个head都降维了,因此实际总计算花费和一个单一的注意力机制差不多。
模型中Attention的使用
- 编码器-解码器:query来自解码器的上一个输出,key和value来自编码器的输出。这使得解码器中每个位置都能与输入序列的所有位置产生联系,这基本上是经典的编码器解码器注意力机制。
- 编码器中的self-attention层:key,value,query都来自编码器的上一个输出。这样编码器中的每个位置都能和之前所有位置产生联系。
- 解码器中的self-attention层:同样,让解码器中的每个位置能和之前(包括自己)的所有位置产生联系。另外解码器中还需要避免使用后方的信息,因此在放缩点积注意力的softmax之前,设置了一个mask来掩盖掉当前位置对后方位置的连接。
Position-wise Feed-Forward Networks
在注意力层之后使用了一个共享参数的全连接层(两个线性层+ReLU),对每个位置单独进行变换(它们参数一样):
\[ FFN(X)=max(0,xW_1+b_1)W_2+b_2 \]
Positional Encoding
由于没有使用卷积和循环框架,想要使用位置信息,则需要在embeddings的基础上与一个 Positional encodings相加:
\[ \begin{split}\begin{aligned} p_{pos, 2i} &= \sin\left(\frac{pos}{10000^{2i/d}}\right),\\p_{pos, 2i+1} &= \cos\left(\frac{pos}{10000^{2i/d}}\right).\end{aligned}\end{split} \]
其中pos是编码的位置,i是编码目标维度(类似于embedding后的维度)。每个维度\(i\)都对应一种正弦波,显然沿着维度升高,正弦波的频率单调降低,波长单调升高。因此也可以知道,对较低的维度,特征重合大,并且变换频率快。
并且这种positional encoding可以很好表示相对位置。对于同样的维度\(2i,2i+1\)上,位置 \(pos+\delta\) 和位置 \(pos\) 之间是线性变换的关系。即通过线性变换,就可以把\((p_{i, 2j}, p_{i, 2j+1})\)投影到\((p_{i+\delta, 2i}, p_{i+\delta, 2i+1})\)。证明如下:令\(\omega_j = 1/10000^{2j/d}\)
\[ \begin{split}\begin{aligned} &\begin{bmatrix} \cos(\delta \omega_j) & \sin(\delta \omega_j) \\ -\sin(\delta \omega_j) & \cos(\delta \omega_j) \\ \end{bmatrix} \begin{bmatrix} p_{i, 2j} \\ p_{i, 2j+1} \\ \end{bmatrix}\\ =&\begin{bmatrix} \cos(\delta \omega_j) \sin(i \omega_j) + \sin(\delta \omega_j) \cos(i \omega_j) \\ -\sin(\delta \omega_j) \sin(i \omega_j) + \cos(\delta \omega_j) \cos(i \omega_j) \\ \end{bmatrix}\\ =&\begin{bmatrix} \sin\left((i+\delta) \omega_j\right) \\ \cos\left((i+\delta) \omega_j\right) \\ \end{bmatrix}\\ =& \begin{bmatrix} p_{i+\delta, 2j} \\ p_{i+\delta, 2j+1} \\ \end{bmatrix}, \end{aligned}\end{split} \]
另外,虽然这种编码和positional embeddings效果差不多,但是正弦编码可以生成比训练数据更长的序列。 (因为是直接定义式,没有需要学习的参数)
Self-Attention 优势
从三个方面进行性能分析:计算复杂度,可并行操作数,长距离依赖路径长度(路径越短,学习到长距离依赖更容易)
在\(n<d\)时,self-attention计算复杂度优于RNN,并且实际中\(n<d\)是大多数情况。针对特别大的\(n\)的情况,self-attention需要被限制在一个\(r\)的邻域之中,但是这增加了长距离依赖路径长度,论文尚未解决。
\(k<n\)的卷积层不能连接所有的元素,因此需要\(O(n/k)\)层连续卷积,或者\(O(\log_k n)\)的空洞卷积,也会导致依赖路径的变长。