https://www.jianshu.com/p/25fc600de9fb

谷歌最近的一篇BERT取得了卓越的效果,为了研究BERT的论文,我先找出了《Attention is All You Need》,看看里面的Transformer模型作为基础。

Transformer是为了机器翻译任务中的问题所提出的。

传统的RNN神经网络结构是可以处理任意长度的输入,它非常适合于自然语言的建模,所以它在一段时间内占据了整个神经网络中的主流。随着学术的发展,我们也会看到RNN有些不足。

RNN的缺点主要有两点:

  • RNN序列的特性导致其非常难以并行化
  • 在RNN训练中,RNN的网络结构对于长距离和层级化的依赖关系难以建立

关于第二点举个例子:“The dog didn’t cross street because it wastoo tired”,当我们看到“tired”的时候知道这个it指dog 。如果把最后一个词换了,“The dog didn’t cross street because it was too wide”,这时候如果是人看了这句话就很容易发现it 指的是street,因为street because it was wide,不可能是dog too wide。对于人来说很简单,但是机器要分清楚指代关系是非常难的。

所以人们开始探索新的网络结构,例如FaceBook提出的《Convolutional Sequence to Sequence Learning》。

Google在这一问题上的探索结果便是Transformer。Transformer这个网络命名,Transformer在英文翻译过来有变形金刚的意思。

1. 整体结构

从整体上来看,Transformer依旧是一个“Sequence to Sequence”框架,拥有Encoder和Decoder两部分:

 
Transformer的整体结构

Transformer的Encoder其实有6层,Decoder也有6层,从Encoder的角度,低层的Encoder是表层的词法信息,逐步向上进行抽象之后,在上层将表示抽象语义信息。Encoder部分还在最上层连了几条线到每个Decoder的部分,这是为了在Decoder中进行Attention操作,Decoder的网络中和Encoder也有信息传递和交互的。最后一个特点是Decoder和Encoder画的大小是一样的,因为它们层的维度大小是一样的。

 
 

多层的神经网络结构能够对句子层级化信息进行建模,如果我们更精细的去看每一层的结构,就会发现这样的情况:Encode分两个子网络部分,第一个是Self-Attention,第二个部分是Feed Forward。

Self-Attention是自注意力机制层,表征句子当中不同位置词之间的关系,是我们前面提到的it和street 或dog之间的依赖关系。

 
 

2. Self-Attention

首先在做DeepNLP任务时,我们都会使用word2vec等技术生成词向量:

 
 

注:这里对词向量的维数都做了简化,以方便后面说明

那么首先要明白什么是Attention。从语言学的角度,它是表示词与词之间的关联关系,像下图所示,这是一个Self-Attention的示意,它这个it会和其他位置的词发生关系,颜色越深的是说关系越紧密,从中图中看到它很正确的关联到了animal它实际指代的一个词。

 
 

从机器学习的角度,这个Attention是神经网络隐层之间一个相似度的表示,什么是Self-Attention?就是表示句子内部词与词之间的关联关系,就像这里的it到animal,可以用于指代消解等问题。

在Transformer中提出一种扩展性更高、并行度更高的Attention计算方式,它把Attention看作一个基于内容的查询的过程,content based query,它会设置3个vector:QueryVector、Key Vector、Value Vector。并且每一个Vector都是通过它的input embedding和权重的矩阵相乘得到的。利用这个Q、K、V进行各种数值的计算,最终得到Attentionscore。

 
 
 
计算公式
 
 

用一个例子来给大家演示具体的Attention是怎么计算的。如果我们计算“Thinking”这个词,用Self-Attention的话,首先会用它的Query Vector乘以K的向量,如果计算和第二个位置的attention是乘以T2的矩阵得到一个score,这个score再去和它维度的平根根进行相除,这个相除有数学上的含义,能够使它回传的梯度更加稳定,除完后得到一个数值进行softmax,所有Attention都是正数并且相加之和等于1,这是从数学正确上考虑,并且最终得到概率这个值是去定义每一个词在当前位置的表现力。Softmax之后,我们会用softmax得到的乘以它Value的矩阵,这样实际得到Attention的值,最后会把不同位置得到Attention的score加到一起,形成当前位置Attention的Vector,就是Z1,加上逐词计算的话就得到所有位置的Attention。

 
 

使用矩阵形式来表示:

 
 
 
 

3. Multi-head Attention

这个是Google提出的新概念,是Attention机制的完善。不过从形式上看,它其实就再简单不过了,就是把Q,K,V通过参数矩阵映射一下,然后再做Attention,把这个过程重复做h次,结果拼接起来就行了

 
 
 
 
 
 
 
 

4. Positional Encoding

这样的模型并不能捕捉序列的顺序!换句话说,如果将K,V按行打乱顺序(相当于句子中的词序打乱),那么Attention的结果还是一样的。这就表明了,到目前为止,Attention模型顶多是一个非常精妙的“词袋模型”而已。

Position Embedding,也就是“位置向量”,将每个位置编号,然后每个编号对应一个向量,通过结合位置向量和词向量,就给每个词都引入了一定的位置信息,这样Attention就可以分辨出不同位置的词了。

在以往的Position Embedding中,基本都是根据任务训练出来的向量。而Google直接给出了一个构造Position Embedding的公式:

 
 

这里的意思是将id为p的位置映射为一个dpos维的位置向量,这个向量的第i个元素的数值就是PEi(p)。

Position Embedding本身是一个绝对位置的信息,但在语言中,相对位置也很重要,Google选择前述的位置向量公式的一个重要原因是:由于我们有sin(α+β) = sinαcosβ+cosαsinβ 以及 cos(α+β)=cosαcosβ−sinαsinβ,这表明位置p+k的向量可以表示成位置p的向量的线性变换,这提供了表达相对位置信息的可能性。

 
 

这上面的编码结果好像有点问题,我运行了哈佛的代码后的结果如下,也可能我哪里没有理解清楚,希望有明白的大佬给我指点下。

 
 

需要注意的一点,结合位置向量和词向量其实有好几个可选方案,可以把它们拼接起来作为一个新向量,也可以把位置向量定义为跟词向量一样大小,然后两者加起来。Google论文中用的都是后者。

5. Position-wise Feed-Forward Networks

 
 
 
 

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

6. Residual connection和layer-normalization

对于学习CV的人估计对这个结构一点也不陌生,Residual connection是对于较为深层的神经网络有比较好的作用,比如网络层很深时,数值的传播随着weight不断的减弱,Residual connection是从输入的部分,就是图中虚线的部分,实际连到它输出层的部分,把输入的信息原封不动copy到输出的部分,减少信息的损失。

 
 

layer-normalization这种归一化层是为了防止在某些层中由于某些位置过大或者过小导致数值过大或过小,对神经网络梯度回传时有训练的问题,保证训练的稳定性,这是神经网络设计比较常用的case。

基本在每个子网络后面都要加上layer-normalization、加上Residual connection,加上这两个部分能够使深层神经网络训练更加顺利。

 
 

到此为止,Encoder部分其实基本上就已经结束了,Decoder部分其实大多数结构都与Encoder部分相同,但是它的Attention部分还是有一些小小的不同。

7. Encoder-Decoder Attention

 
 

由上图可以看到,Decoder 部分除了Self-Attention的机制之外,还有Encoder-Decoder Attention。

其实,Encoder-Decoder Attention就是平常使用的Attention:

 
 

8. 小节

 
 

总体流程(上图是只画两层的Encoder和Decoder):

  1. 将底层的词的输入转化为embedding的输入,X1、X2
  2. 加上“Positional Encoding”的输入
  3. 输入到第一个Encoder当中,经过self-Attention层,直连的“Residual connection”和归一化层,得到的输出
  4. 将其输入到前馈神经网络中,前馈神经网络出来之后再经过直连层和归一化层,这样就完成了一个Encoder部分
  5. 再以这个输入到第二个Encoder之后,它会把第二个Encoder的输出(这里由于只有两层,所以第二个Encoder就是最后Encoder)作为第一个Decoder的输入,也是依次进行上面的过程
  6. 最后就是通过一个liner层之后由softmax层转化概率输出
 
 

注意:目标端的Attention注意力机制是一个masked注意力机制,为什么?比如在机器翻译当中,在源端能够看到所有的词,但如果你目标端生成翻译时是自左上右,生成翻译时能够看到前面已经生成词的信息,看不到后面层的,这是目标端Attention和源端Attention比较大的区别,所以在目标端所有的Attention都是加Masked的,这个Masked相当于把后面不该看到的信息屏蔽掉

参考:

  1. https://kexue.fm/archives/4765
  2. pytorch代码实现
  3. https://jalammar.github.io/illustrated-transformer/
  4. https://mp.weixin.qq.com/s/w3IKoygTLDsAxk1MB5JrGg

作者:freedom_king
链接:https://www.jianshu.com/p/25fc600de9fb
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

《Attention is All You Need》的更多相关文章

  1. 《Attention is All You Need》浅读(简介+代码)

    2017年中,有两篇类似同时也是笔者非常欣赏的论文,分别是FaceBook的<Convolutional Sequence to Sequence Learning>和Google的< ...

  2. bert系列一:《Attention is all you need》论文解读

    论文创新点: 多头注意力 transformer模型 Transformer模型 上图为模型结构,左边为encoder,右边为decoder,各有N=6个相同的堆叠. encoder 先对inputs ...

  3. 关于注意力机制(《Attention is all you need》)

    深度学习做NLP的方法,基本上都是先将句子分词,然后每个词转化为对应的词向量序列.(https://kexue.fm/archives/4765) 第一个思路是RNN层,递归进行,但是RNN无法很好地 ...

  4. 《attention is all you need》解读

    Motivation: 靠attention机制,不使用rnn和cnn,并行度高 通过attention,抓长距离依赖关系比rnn强 创新点: 通过self-attention,自己和自己做atten ...

  5. 《Attention Augmented Convolutional Networks》注意力的神经网络

    paper: <Attention Augmented Convolutional Networks> https://arxiv.org/pdf/1904.09925.pdf 这篇文章是 ...

  6. 王之泰201771010131《面向对象程序设计(java)》第七周学习总结

    王之泰201771010131<面向对象程序设计(java)>第七周学习总结 第一部分:理论知识学习部分 第五章 第五章内容深度学习: 继承:如果两个类存在继承关系,则子类会自动继承父类的 ...

  7. 杨其菊201771010134《面向对象程序设计(java)》第六周学习总结

    <面向对象程序设计(java)>第六周学习总结 第一部分:理论知识 1)类.超类和子类2)Object:所有类的超类 3)泛型数组列表4)对象包装器和自动打包 5)参数数量可变的方法 6) ...

  8. 201871010116-祁英红《面向对象程序设计(java)》第七周学习总结

    项目 内容 <面向对象程序设计(java)> https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cnblogs.com/ ...

  9. 201871010111-刘佳华《面向对象程序设计(java)》第七周学习总结

    201871010111-刘佳华<面向对象程序设计(java)>第七周学习总结 实验时间 2019-10-11 1.实验目的与要求 1) 掌握四种访问权限修饰符的使用特点: (1)进一步理 ...

随机推荐

  1. hdu5443 ST表裸题:求区间最大

    #include<iostream> #include<cstring> #include<cstdio> #include<algorithm> #d ...

  2. Could not get lock /var/lib/apt/lists/lock - open (11: Resource temporarily unavailable)

    今天在对 Ubuntu 进行更新源的时候,突然出现下列错误(为了省事,更新前直接切换了 root 用户) 上网查了一下,网上解释说应该是之前那个更新被强制取消的问题,进程仍然还在.用这个命令查看一下: ...

  3. Windows系统下oracle数据库每天定时备份

    第一步:建立备份脚本oraclebackup.bat 首先建立一个备份bat文件,在D盘下新建备份目录oraclebackup,将oracle安装目录下的EXP.EXE复制到此目录下,再新建一个文本文 ...

  4. 学习C程序设计(一)第一节总览

    1.程序设计面向的问题 一切可计算问题都可以用程序的方法解决.ps:这样程序与计算有关了 1.1程序设计的五个步骤: a.确定问题可以计算:(问题是可计算) b.建立问题的数学模型:(不懂) c.设计 ...

  5. POJ 3190 Stall Reservations【贪心】

    POJ 3190 题意: 一些奶牛要在指定的时间内挤牛奶,而一个机器只能同时对一个奶牛工作.给你每头奶牛的指定时间的区间(闭区间),问你最小需要多少机器.思路:先按奶牛要求的时间起始点进行从小到大排序 ...

  6. python爬取京东价格

    昨天准备爬取一个京东商品的价格,正则写好了一直是空的 后来我去页面里面看了下,价格标签里果然是空的 百度了下,大家都说是js来控制显示价格的 于是去抓包试试,找到了一条mgets的请求 中间很多参数不 ...

  7. C# Winform OpenFileDialog 控件

    OpenFileDialog控件又称打开文件对话框,主要用来弹出Windows中标准的[打开文件]对话框. OpenFileDialog控件的常用属性如下. (1)Title属性:用来获取或设置对话框 ...

  8. asp.net core2.0大白话带你入门

    本系列包括: 1.新建asp.net core项目2.web项目目录解读3.配置访问地址4.环境变量详解5.配置文件6.日志7.DI容器8.服务的生命周期9.session的使用10.cookie的使 ...

  9. POJ 3279 Fliptile (二进制枚举)

    <题目链接> <转载于 >>> > 题目大意: 给定一个M*N矩阵,有些是黑色(1表示)否则白色(0表示),每翻转一个(i,j),会使得它和它周围4个格变为另 ...

  10. windows server 2003 安全加固(一)

    windows server 2003 安全加固 加固主要在如下方面 A 升级系统补丁 B NTFS权限合理设置 C 关闭不需要的服务 D 关闭不需要的端口 E 帐号和密码管理 F 开启安全策略 G ...