学习:Attention Is All You Need
Introduction
本文是谷歌发表的文章,针对nlp里的机器翻译问题,提出了一种被称为”Transformer”的网络结构,基于注意力机制。文章提出,以往nlp里大量使用RNN结构和encoder-decoder结构,RNN及其衍生网络的缺点就是慢,问题在于前后隐藏状态的依赖性,无法实现并行,而文章提出的”Transformer”完全摒弃了递归结构,依赖注意力机制,挖掘输入和输出之间的关系,这样做最大的好处是能够并行计算了。
Background
在此之前,针对机器翻译这个领域,为了应对RNN无法并行问题,已经有过一些使用CNN的解决方案了,例如谷歌的ByteNet,Facebook的FairSeq等等。
自注意力机制(Self-attention)能够把输入序列上不同位置的信息联系起来,然后计算出整条序列的某种表达,目前自注意力机制主要应用于阅读理解、提取摘要、文本推论等领域。
模型结构
大多数自然语言转换模型都包含一个encoder-decoder结构,模型的输入是一个离散符号序列(symbol)x=(x1,x2,⋯,xn),encoder负责将它映射成连续值序列z=(z1,z2,⋯,zn)。而给定z,decoder负责生成一个输出符号序列y=(y1,y2,⋯,ym)。模型是自回归的,即之前生成的输出会作为额外的输入,用于生成下一个输出。
Encoder与Decoder堆叠
Encoder
Transformer模型的Encoder由6个基本层堆叠起来,每个基本层包含两个子层,第一个子层是一个注意力机制,第二个是一个全连接前向神经网络。对两个子层都引入了残差边以及layer normalization。
Decoder
Transformer模型的Decoder也由6个基本层堆叠起来,每个基本层除了Encoder里面的那两个以外,还增加了一层注意力机制,同样引入残差边以及layer normalization。
注意力机制
注意力机制(Attention)简单来说就是给定一个查找(query)和一个键值表(key-value pairs),将query映射到正确的输入的过程。此处的query、key、value和最终的输出都是向量。输出往往是一个加权求和的形式,而权重则由query、key和value决定。
Additive Attention
Scaled Dot-Product Attention
输入包含维的query和key,以及维的value。通过计算query和各个key的点积,除以归一化,然后经过softmax**变成权重,最后再乘value。点积注意力机制的优点是速度快、占用空间小。
Multi-Head Attention
用h(本文取8)个不同的线性变换分别将维的key、value和query映射成维、维和维,然后再代入注意力机制,产生总共维输出,然后拼起来,再用一个线性变换得到最终的输出。
本文使用的注意力机制
本文使用的是Multi-Head Attention,具体体现在三个方面。
- 在“encoder-decoder attention”层中,query来自前一个decoder层,而key和value是encoder的输出。这允许decoder的每个位置都去关注输入序列的所有位置。
- encoder包含self-attention层,在self-attention层中所有的key、value和query都来自前一层的encoder。这样encoder的每个位置都能去关注前一层encoder输出的所有位置。
- decoder包含self-attention层
前向神经网络
这是一个 Position-wise 前向神经网络,encoder和decoder的每一层都包含一个前向神经网络,**函数顺序是线性、RELU、线性。
位置编码
由于本文的模型结构没有使用任何递归结构或卷积结构,为了让模型能利用输入序列的顺序信息,必须引入某种能表达输入序列每个部分的绝对或相对位置的信息才行。文章采取的方法是位置编码(positional encoding),在送入encoder和decoder之前,先对输入进行编码,编码后的向量维度是。具体来说,采用正弦和余弦函数进行编码。
为什么使用self-attention
从三个方面去对比self-attention和递归结构、卷积结构的优劣性,首先是每一层的计算复杂度,其次是能够被并行的计算量,最后是网络中长期依赖的路径长度。对比显示,self-attention表现最好。
训练
训练数据使用WMT English-German数据集,包含450w对语句。句子都被编码过了,使用了一个大小约37000个token的字典。样本被分为若干个batch,每个batch大概25000个token,每个batch中的句子长度保持基本一致。硬件上使用了8块GPU。Optimizer使用了Adam。过拟合方面使用了dropout和Label Smoothing。
结果
不论是英语-德语还是英语-法语的翻译任务,对比之前的一些模型,本文提出的模型都达到更好的BELU值,同时Training Cost也最低。
本文开源代码
https://github.com/tensorflow/tensor2tensor
参考资料
Attention Is All You Need
一文读懂「Attention is All You Need」| 附代码实现
attention实现keras版
attention实现tensorflow版
对Attention is all you need 的理解
#############################分割线##############################
一文读懂「Attention is All You Need」| 附代码实现
赋值链接2
摘要: 前言 2017 年中,有两篇类似同时也是笔者非常欣赏的论文,分别是 FaceBook 的 Convolutional Sequence to Sequence Learning 和 Google 的 Attention is All You Need,它们都算是 Seq2Seq 上的创新,本质上来说,都是抛弃了 RNN 结构来做 Seq2Seq 任务。
序列编码
深度学习做 NLP 的方法,基本上都是先将句子分词,然后每个词转化为对应的词向量序列。这样一来,每个句子都对应的是一个矩阵 X=(x1,x2,…,xt),其中 xi 都代表着第 i 个词的词向量(行向量),维度为 d 维,故?tp=webp&wxfrom=5&wx_lazy=1。这样的话,问题就变成了编码这些序列了。
第一个基本的思路是 RNN 层,RNN 的方案很简单,递归式进行:
不管是已经被广泛使用的 LSTM、GRU 还是最近的 SRU,都并未脱离这个递归框架。RNN结构本身比较简单,也很适合序列建模,但 RNN 的明显缺点之一就是无法并行,因此速度较慢,这是递归的天然缺陷。
另外我个人觉得 RNN 无法很好地学习到全局的结构信息,因为它本质是一个马尔科夫决策过程。
第二个思路是 CNN 层,其实 CNN 的方案也是很自然的,窗口式遍历,比如尺寸为 3 的卷积,就是:
在 FaceBook 的论文中,纯粹使用卷积也完成了 Seq2Seq 的学习,是卷积的一个精致且极致的使用案例,热衷卷积的读者必须得好好读读这篇文论。
CNN 方便并行,而且容易捕捉到一些全局的结构信息,笔者本身是比较偏爱 CNN 的,在目前的工作或竞赛模型中,我都已经尽量用 CNN 来代替已有的 RNN 模型了,并形成了自己的一套使用经验,这部分我们以后再谈。
Google的大作提供了第三个思路:纯 Attention,单靠注意力就可以。
RNN 要逐步递归才能获得全局信息,因此一般要双向 RNN 才比较好;CNN 事实上只能获取局部信息,是通过层叠来增大感受野;Attention 的思路最为粗暴,它一步到位获取了全局信息,它的解决方案是:
其中 A,B 是另外一个序列(矩阵)。如果都取 A=B=X,那么就称为 Self Attention,它的意思是直接将 xt 与原来的每个词进行比较,最后算出 yt。
Attention 层
Attention 定义
Google 的一般化 Attention思路也是一个编码序列的方案,因此我们也可以认为它跟 RNN、CNN 一样,都是一个序列编码的层。
前面给出的是一般化的框架形式的描述,事实上 Google 给出的方案是很具体的。首先,它先把 Attention 的定义给了出来:
这里用的是跟 Google 的论文一致的符号,其中:
如果忽略**函数 softmax 的话,那么事实上它就是三个 n×dk,dk×m,m×dv 的矩阵相乘,最后的结果就是一个 n×dv 的矩阵。
于是我们可以认为:这是一个 Attention 层,将 n×dk 的序列 Q 编码成了一个新的 n×dv 的序列。
那怎么理解这种结构呢?我们不妨逐个向量来看。
其中 Z 是归一化因子。事实上 q,k,v 分别是 query,key,value 的简写,K,V 是一一对应的,它们就像是 key-value 的关系,那么上式的意思就是通过 qt 这个 query,通过与各个 ks 内积的并 softmax 的方式,来得到 qt 与各个 vs 的相似度,然后加权求和,得到一个 dv 维的向量。
其中因子?tp=webp&wxfrom=5&wx_lazy=1起到调节作用,使得内积不至于太大(太大的话 softmax 后就非 0 即 1 了,不够“soft”了)。
事实上这种 Attention 的定义并不新鲜,但由于 Google 的影响力,我们可以认为现在是更加正式地提出了这个定义,并将其视为一个层地看待。
此外这个定义只是注意力的一种形式,还有一些其他选择,比如 query 跟 key 的运算方式不一定是点乘(还可以是拼接后再内积一个参数向量),甚至权重都不一定要归一化,等等。
Multi-Head Attention
这个是 Google 提出的新概念,是 Attention 机制的完善。
不过从形式上看,它其实就再简单不过了,就是把 Q,K,V 通过参数矩阵映射一下,然后再做 Attention,把这个过程重复做 h 次,结果拼接起来就行了,可谓“大道至简”了。具体来说: