[论文笔记]Attention is All You Need

$\qquad$关于Transformer的始祖文章,感觉中文查到的资料鲜有整体讲得比较清(ruo)楚(zhi)的,故记下一篇写写自己的理解。感谢大佬Zack的亲情指导!

INTRODUCTION

$\qquad$ 近年来,句子转换的模型大多数都基于复杂的recurrent或convolutional network(RNN, LSTM, GRU etc.)。为了减少RNN的计算量,很多模型如ConvS2S、ByteNet采用卷积层来计算输入和输出之间的latent space。然而这些方法都是建立在对输入信号的分布有一些假设的基础上的,比如说ConvS2S假设是线性的,ByteNet假设是log的。这种假设对于隔得比较远的点来说误差更大。然而本文模型中的multi-head机制很好得规避了这个问题。google团队单靠attention层实现了一个机器翻译模型Transformer,并且在不同规模的公开数据集上都有良好的表现。

Notation & Overview

$\qquad$以训练语言模型为例(来自OpenAI GPT)),transformer模型的整体结构数学描述如下,具体解释请看下节(MODEL ARCHITECTURE):

模型目标 Model Objective

$\qquad$目标是通过前面[窗口长度]的词预测下一个词是什么。假设给定语料(无标签)为${u_1,…,u_n}$,设$k$为窗口长度。$P$为条件概率,$\Theta$为网络模型的参数,我们的目标就是通过神经网络进行最大似然估计(用前$k$个词预测接下来一个词),也就是:

模型结构 Model Architecture

$\qquad$设$U=(u_{i-k,…,u_{i-1}}) \in R^{k\times n_tokens}$为一个词对应的context(1-hot 编码),$t$为transformer的层数,$n_tokens$为词典词数,$d_embedd=d_model$为词向量维度,$W_e\in R^{n_tokens \times d_embedd}$为词表的embedding matrix,$W_p$为position embedding matrix,$H_i\in R^{k\times d_{model}}$为每次transformer block的输出:

核心部分 Transformer block

$\qquad$设$H_{mid}\in R^{k\times d_{model}}$为一个transformer block的中间层:

Multi-Head Attention

$\qquad$设$H\in R^{k\times d_{model}}$为输入,$W_i^K, W_i^Q \in R^{d_{model}\times d_k}$,$W_i^V \in R^{d_{model}\times d_v}$,$K,Q\in R^{k\times d_k}$,$V\in R^{k\times d_v}$。则$K,Q,V$可由$H$作线性变换得到:

$\qquad$设$m$为head数,$head_i\in R^{k\times d_v}$,$W^O\in R^{m d_v\times d_{model}}$:

Self-Attention

Position-wise Feed Forward Neural Network

$\qquad$实际上是两次线性变换:设$W_1\in R^{d_{model}\times d_{ff}},W_2\in R^{d_{ff}\times d_{model}}$:

MODEL ARCHITECTURE

Encoder and Decoder Stacks

$\qquad$纵观以往的seq2seq系统,皆为input space $ x$ —encoder—> latent space $z$ —decoder—> output space $y$ 的形式。Transformer的大体结构也是如此。下图清晰得表明了Transformer的结构,其中左边一堆是encoder,右边是decoder。细节上,左右均包含6个block(N=6),每个block里的layer之间采用residual的方法连接,并且每一层之后都有layer normalization(即:$output=LayerNorm(x+Sublayer(x))$)。所有的outputdimension为512。

  • 训练时,我们把原句从encoder的input端输入进去,得到encode之后的输出,作为对原句前后信息的编码参与到decode过程中。在decoding部分,输入“\ + 翻译后的句子”, 得到输出的概率分布(softmax后每个位置的的维度为词典的维度),将其与理想的输出概率分布”翻译后的句子 + \“比较(cross entropy),并反向调整模型参数。
  • 测试时encoding端同理,decoding部分无法并行。第一次输入\预测出句子的第一个词,后面以此类推,直到预测出\

Attention

$\qquad$ Attention,本质上来说是想学习出两句话之间词与词的关系。它们可以是不同的两句话,通过attention来找出哪些词是相互对应的(比如机器翻译时有的词顺序调换;文本摘要时只需要其中一些词;阅读理解时可以把context作为一个句子,query连起来作为一个长句);也可以是同一句话,来看长句中上下文之间的对应关系(比如说长从句中的指代关系,如下面左图所示,its对应前面的law)。假设这两个句子分别是A和B,那么理所当然的,我们希望建立这样一个矩阵,它能告诉我B中每个词和A中每个词之间的联系程度(如下面右图所示)。用这个矩阵适当调整输入的句子,可以帮助我们的系统得到更好的结果。

$\qquad$ \下文中的$n$和上面overview中含义不同:overview中为transformer block层数,后文中为一句话中的词数,相当于overview中的$k$。*

$\qquad$本文中主要用的是self-attention机制,也就是自己和自己比较,得到上下文关系。记一个词embedding的维度为$d_{model}$,一句话最长(其他padding)为$n$个词;那么一个句子embedding后为$X\in R^{n\times d_{model}}$;我们把比较的两个句子一个叫做Query,它由原句作线性变换得到,记作$Q\in R^{n\times d_k}$;一个叫做Key,也由原句作线性变换得到,记作$K\in R^{n\times d_k}$;显然在self-attention中他们是互相对称的,两句的角色可以互换,因此维度相同。通过比较他们两我们可以得到$n\times n$的权重矩阵,然后用这个矩阵来调整输入的句子。这个被调整的句子记作$V \in R^{n\times d_v}$,也由原句线性变换得到,调整后的句子记作$Z\in R^{n\times d_v}$。一般情况下$d_k,d_v<d_{model}$,在原文中$d_{model}=512, d_k=d_v=64$。(至于为什么这三个句子不直接用原句而非要线性变换一下,我认为是为了增强模型的拟合能力,同时降维加快计算,另外在multi-head时增强多样性)。

$\qquad$定义好了大体流程,接着我们需要知道详细的计算方法:1. 怎么从$q$和$k$得到$n\times n$的权重矩阵?(原文中说这个求解过程叫compatibility function,我没理解这个词怎么来的) 2. 得到权重矩阵之后怎么用它来调整原句?

求权重矩阵:Scaled Dot-Product Attention

$\qquad$这篇文章中主要提到了两种方法:dot(矩阵点积)或addictive attention(一层全连层)。下图所示为点积法的过程:

$\qquad$整个过程可以表示为:

$\qquad$理论上,dot-product attention和addictive attention的复杂度差不多。但是实际上由于矩阵运算的成熟,dot-product的方法无论在时间复杂度上还是空间复杂度上表现都优异很多。不过当$d_k$很大时点积求得的数也很大,在softmax中的对应点梯度将很小。因此我们点积完先归一化(减去均值除以标准差)再作softmax。而addictive attention就没有这个scaling的问题。

$\qquad$备注:假设$q\in R^{d_k}$和$q\in R^{d_k}$是均值为0方差为1的随机变量,那么点积所得结果$q\cdot k=\sum_{i=1}^{d_k}q_i k_i$的中值为0,方差为$d_k。$

如何调整原句:Multi-head Attention

$\qquad$上面得到的$Z$其实已经可以说是一个调整过的句子了。如果我们把$h$设为1,即$d_k=d_v=d_{model}$,那么它的维度就是$n\times d_{model}$,和原句保持一致了。但是作者团队发现,如果多投影几次$K,Q,V$,每次都有新发现。以及,多头对memory的压力更小(一头可能out of memory),且多个头可以并行。因此,不如降低$d_k,d_v$的维度,多投几次,最后再把结果拼起来线性变换一下(线性变换可真多呀)。最后维度还是和原句一样,而且复杂度也和一次性投完差不多,但是这种multi-head的方法效果更好。

Transformer中attention层的具体细节

以上是multi-head attention的通用结构,它在Transformer中具体用在三处:

  • 在encoder的self-attention层中,所有的key,query,value都来自上一层encoder的输出。每一个encoder block都利用了之前block所得结果中所有位置上的信息。
  • decoder中的Masked Multi-head Attention层,利用前面decoder block中所有位置上的信息,得到query。为了让我们的query仅从前面的已知的词得出,完全不受后面词的影响,可以加一个mask,也就是把矩阵中对应位置的结果设置为$- \infin$。比如,输入“我爱喝可乐”,在翻译出“I like”之后,attention层根据“I like”学习出query(next-token probability)(比如后面应该接一个名词),从encoder结果中学习出key和value(比如喝)。此时mask避免了后面“drink cola”对这一级的干扰。
  • 在decoder的encoder-decoder attention层,query为上一层decoder的输出,key和value来自encoder的输出。它又可以学习到输入在所有位置上的信息。

Position-wise Feed-Forward Network

$\qquad$图中的Feed-Forward Network,先将$d_{model}=512$线性变换为$d_{ff}=2048$再变换回512:

$\qquad$和RNN不同的是,每次进入这个网络的是一个句子整体所得结果,因此可以看作是对一个句子中所有词作feed-forward。这里作者说相当于用$1\times 1$的kernel做两次convolution,我其实不太明白(是先用4个kernel拼成2048?然后再pooling回来?)。原代码中直接用两个全连层实现。

Positional Encoding

$\qquad$由于这个模型没有像recurrence那样能够表征顺序的结构,作者考虑用positional encoding将位置信息加入输入数据中。具体做法是将下面两个式子所得的值(如图所示)与原输入相加。

$\qquad$其中pos表示词的位置,i表示embedding中第i维,$d_{model}$表示embedding的维度。作者的想法是这么简单的两个式子,神经网络应该能够轻松得将它学习出来并且作为一个特征。这张图的每一行代表一个词,每一列代表一个维度。从左边的部分可以看出,综合不同维度的信息,这种方式还是可以比较好得对不同位置编码。右半边几乎看不到编码的信息,我猜测可能是因为,只要有一半左右维度上编过码了就足以区分位置了,剩下一半维度可以不编?

$\qquad$关于位置编码,作者还尝试了learned positional embedding的方法,所得结果几乎相同。作者最终选择了这种正弦曲线编码的方式是因为,这种方式还适用于test中句子比train中长的情况。(在BERT中使用的是learn的方法)。

self-attention 的好处都有啥

  • 每一层的复杂度:可以看到,当句子长度很长的时候,self-attention的复杂度飞升。主要是因为它需要算一个$n\times n$的矩阵,当$n$太大时自然不利。但是实际应用时这种情况是不可避免的,比如阅读理解中的context在几百词左右。

    为此提出了一种改进restricted version,就是每个词只考虑和旁边r个邻居的attention。这种做法减小了复杂度,但增加了dependency的长度。

  • 并行:在encoder端显然每次是直接进一整个句子;在decoder端,训练时可以一次性输入整句。

  • long dependency:想要知道A词和B词之间的attention权重时,RNN的方法需要按顺序遍历一边,因此复杂度可达$O(n)$;CNN没有对输入输出句的每个position之间建立联系,尤其是dilated convolution更慢;而本文这种模型,由于attention是按照矩阵存好的,每次只要去相应位置上查就行,复杂度为$O(1)$(矩阵和链表?)

Result

$\qquad$可以看到结果和convS2S差不太多,不过人家快呀。

Reference

一个讲得比较好的网友博客:刘贺的博客

国外友人的详细图解:Illustrated-Transformer此人博客还蛮有趣的,图解了很多~有空看看

知乎上写的比较好的一篇:魔法抓的学习笔记

google源码github:tensor2tensor源码

哈佛的pytorch实现版:[The Annotated Transformer](