赞
踩
Attention机制最近几年在NLP中十分火爆,这篇文章主要是对po主在学习过程中的知识做个总结,只涉及比较浅显的概念部分,不涉及具体的数学计算。文章主要参考张俊林大神的知乎专栏:深度学习中的注意力模型(2017版)。
注意力机制最近几年在深度学习各个领域被广泛使用,无论是图像处理、语音识别还是自然语言处理的不同类型任务中,都很容易遇到注意力模型的身影。
第一阶段:Attention机制与图像处理
Attention机制一开始更多的是应用于图像领域,最早也是在视觉图像领域提出来的(大约九几年)。但真正火起来是 2014 年 Google Mind 团队的论文 Recurrent Models of Visual Attention ,他们在 RNN 模型上使用了 Attention机制来进行图像分类。
2015年Kelvin Xu的一篇论文 Show, Attend and Tell: Neural Image Caption Generation with Visual Attention ,在图像描述生成中引入了Attention,文章提出了两种Attention模式,即Soft Attention 和 Hard Attention。
Soft Attention会考虑所有位置,而Hard Attention会专注于很小的区域。
两者各有优缺点: Soft Attention是参数化的,因此可导,可以被嵌入到模型中去,直接训练。梯度可以经过Attention Mechanism模块,反向传播到模型其他部分。
Hard Attention聚焦于部分区域,实现的方法是依概率采样输入端隐状态的一部分来进行计算,而不是整个encoder的隐状态。所以是一个随机的过程,需要采用蒙特卡洛采样的方法来估计模块的梯度。
目前更多的研究和应用还是更倾向于使用Soft Attention。
上图中,白色部分代表注意力随时间的变化。上面是Soft Attention,可以看到相对分散;下面是Hard Attention,可以看到比较集中。
第二阶段:Attention机制与NLP
2014年,Bahdanau 等人在论文 Neural Machine Translation by Jointly Learning to Align and Translate 中,使用Soft Attention 机制在机器翻译任务上将翻译和对齐同时进行,算是第一个将 Attention 机制应用到 NLP 领域中。
上图是将英语翻译成法语的例子,白色方块代表注意力随翻译过程的分布情况,可以看到基本呈对角线分布。举个例子,翻译‘agreement’这个词时,注意力理所应当放在这个词本身。这也证明了Attention机制的有效性。
2015年,Effective Approaches to Attention-based Neural Machine Translation 是继上一篇论文后,一篇很具代表性的论文。告诉了大家Attention在RNN中可以如何进行扩展。这篇论文对后续各种基于Attention的模型在NLP应用起到了很大的促进作用。在论文中他们提出了两种Attention机制,一种是Global Attention,一种是Local Attention。
Global Attention:
和传统的Attention model一样,所有的隐藏节点状态都被用于计算权重。不同的是在计算attention矩阵值的时候,文章提出了几种简单的扩展版本。
Local Attention:
在计算时并不是去考虑源语言端的所有词,而是根据一个预测函数,先预测当前解码时要对齐的源语言端的位置,然后通过上下文窗口,仅考虑窗口内的词。主要是为了减少Attention计算时的耗费。
2017年,Google机器翻译团队发表了Attention is all you need论文,获得了广泛关注和应用。这篇论文提出一种新型网络结构Transformer,该结构实际上是多层Self Attention堆叠,另外还提出了多头注意力(Multi-headed Attention)机制。
该论文提出的Transformer模型并行性好,又适合捕获长距离特征,未来很有可能取代RNN,因为RNN是序列型结构,并行计算能力受限。Transformer也成为GPT、BERT等预训练模型的特征提取器。
所以,介绍了这么多Attention机制的历史,Attention到底是什么呢?
其实Attention的思想很简单,和人类的选择性视觉注意力相似。
看下面这张图:
这是一个人在看这张图时的视觉注意力分布的热力图。可以看到,对于婴儿的头部、文章标题、首段落,分配的注意力明显更多。
其实Attention机制也是这个道理,核心目标也是从众多信息中选择出对当前任务目标更关键的信息,抑制其他无用信息。
介绍这个框架的原因是目前大多数注意力模型依附在Encoder-Decoder框架下,并且介绍Attention的各种文章都基于这个展开。但是Attention模型本身是一种独立的思想,要注意!(摘自大佬原话)
这就是Encoder-Decoder框架的结构,是一个句子(或篇章)生成另外一个句子(或篇章)的通用处理模型,是一种用于机器翻译、文本摘要、问答系统的常用框架。
假设,输入 S o u r c e = < x 1 , x 2 , x 3 , x 4 > Source=<x_1,x_2,x_3,x_4> Source=<x1,x2,x3,x4>,通过编码器Encoder就可以转换成中间语义表示 C = F ( x 1 , x 2 , x 3 , x 4 ) C=F(x_1,x_2,x_3,x_4) C=F(x1,x2,x3,x4)(这里的 F F F就是Encoder的某种非线性变换函数)。而Decoder在输出单词 y i y_i yi时,需要根据中间语义表示 C C C和 i i i时刻之前已经生成的历史信息来生成,即 y i = G ( C , y 1 , y 2 , . . . , y i − 1 ) y_i=G(C,y_1,y_2,...,y_{i-1}) yi=G(C,y1,y2,...,yi−1)。每个 y i yi yi都依次这么产生,那么看起来就是整个系统根据输入句子Source生成了目标句子 T a r g e t = < y 1 , y 2 , y 3 , y 4 > Target=<y_1,y_2,y_3,y_4> Target=<y1,y2,y3,y4>。
这就是Encoder-Decoder处理问题的一个基本流程。这个框架可以用于很多问题,具体到不同问题,对应着不同的输入和输出。
下面,终于到了正题Attention。首先介绍常用的Soft Attention,然后基于此抽象出Attention的本质思想,最后介绍最近很火的也是Transfomer的基础——Self Attention。
继续拿出前面Encoder-Decoder框架那张图。
这个模型现在还没有加入Attention机制,实际上可以称为一种“分心模型”。
为什么叫“分心模型”呢?可以看一下输出
Y
Y
Y的计算过程:
可以看到,不管是输出
y
1
,
y
2
y_1,y_2
y1,y2还是
y
3
y_3
y3,用的都是同一个中间语义表示
C
C
C。而
C
=
F
(
x
1
,
x
2
,
x
3
,
x
4
)
C=F(x_1,x_2,x_3,x_4)
C=F(x1,x2,x3,x4),是由输入Source的每个单词经过Encoder编码产生的。这意味着不论是生成哪个单词,输入Source中任意单词对生成某个目标单词
y
i
yi
yi来说影响力都是相同的。
这就好像人看东西没有焦点一样。
举个例子:
在翻译“杰瑞”这个中文单词的时候,"分心模型"里面的每个英文单词对于翻译目标单词“杰瑞”贡献是相同的,很明显这里不太合理,显然“Jerry”对于翻译成“杰瑞”更重要。
另外,Encoder接收了不管多长的语句,最后输出的只是最后一个中间语义向量 C C C。当语句很长时,这个向量能否有效地表示该语句是很值得怀疑的。
所以,在这里对于每一个输出 y i y_i yi,需要采用不同的中间向量表示 C i C_i Ci,并且这个 C i C_i Ci可以表示出每个英文单词对于翻译当前中文单词不同的影响程度,也就是——注意力分布。这样,输出 Y Y Y的计算过程就变成了这样:
这时候,
C
i
C_i
Ci是这样计算的:
F
F
F依旧代表Encoder的某种非线性变换函数,这个公式的核心是给了一个概率分布值。例如,对于
C
3
C_3
C3,也就是翻译’杰瑞’时所用的中间语义向量,给了一个概率分布值(0.3,0.2,0.5),这个概率分布就体现了不同英文单词对于翻译当前中文单词的重要性,可以看到,‘Jerry’的概率是0.5,显然是对于翻译‘杰瑞’更重要。公式里的
g
g
g代表将每个单词的中间语义表示合成一个语义向量的函数,一般的做法中,g函数就是对构成元素加权求和,即:
其中,
L
x
L_x
Lx代表输入句子Source的长度,
a
i
j
a_{ij}
aij代表在Target输出第
i
i
i个单词时Source输入句子中第j个单词的注意力分配系数,而
h
j
h_j
hj则是Source输入句子中第
j
j
j个单词的语义编码。
那么,问题来了,如何确定注意力分配概率分布值呢?
假设:Encoder采用RNN模型,Decoder也采用RNN模型,则没有采用注意力机制的“分心模型”可以细化如下:
左边白色部分是Encoder的一个简单的RNN序列模型,蓝色部分是中间语义表示,右边紫色部分是Decoder的一个RNN模型。
下面给这个“分心模型”加上Attention机制,变成如下:
假设现在要生成 Y i Y_i Yi,那么我们是已知在生成 Y i Y_i Yi之前的 i − 1 i-1 i−1时刻隐藏层节点的输出值 H ( i − 1 ) H_(i−1) H(i−1)的。这时候,就可以用 H ( i − 1 ) H_(i−1) H(i−1)和Encoder的每个单词对应的RNN隐藏层节点状态 h j h_j hj进行对比,即计算二者的相似性 F ( H i − 1 , h j ) F(H_{i-1},h_j) F(Hi−1,hj),这个相似性测度有很多方法,比如计算点积、加法Attention、乘法Attention等等,具体公式就不介绍了,有兴趣可以自己看论文。
在介绍Attention机制的文章里,经常会看到一个词“对齐”,我的理解这其实就是一种相似性度量。
说到这里,就可以抽象出Attention的本质思想了,如下图所示。
将Source中的构成元素想象成是由一系列的<Key,Value>数据对构成,此时给定Target中的某个元素Query,通过计算Query和各个Key的相似性,得到每个Key的权重系数,然后对Value进行加权求和,就可以得到最终的Attention vector。
所以,Attention机制的本质思想就是:从大量信息中有选择地筛选出少量重要信息并聚焦到这些重要信息上,忽略大多不重要的信息。聚焦的过程体现在权重系数的计算上,权重越大代表相似性越大,重要性越大,越聚焦于其对应的Value值上。即权重代表了信息的重要性,而Value是其对应的信息。
最后,介绍一下最近很火的Self Attention模型。
Self Attention也经常被称为Intra Attention(内部Attention),最近一年也获得了比较广泛的使用,比如Google最新的机器翻译模型内部大量采用了Self Attention模型。
在一般任务的Encoder-Decoder框架中,输入Source和输出Target内容是不一样的,比如对于英-中机器翻译来说,Source是英文句子,Target是对应的翻译出的中文句子。
而Self Attention,顾名思义,指的是某句话内部自己的Attention机制,也可以理解为Target=Source这种特殊情况下的注意力计算机制。
那么,对于某一句话本身,为什么要用Attention机制呢?或者说,在这种情况下,用了Attention机制有什么效果呢?
看这个例子:
这是可视化地表示Self Attention在一个很长的英语句子内单词间产生的联系。左图中,它捕捉到了“make sth(the registration or voting process) more difficult”这个短语结构。右图中,它捕捉到了its的指代对象是Law。Self Attention可以捕获同一个句子中单词之间的一些句法特征或者语义特征,通过这些特征,一个句子可以被更好地表示,为后面训练模型做更好的特征提取准备。
所以,引入Self Attention后会更容易捕获句子中长距离的相互依赖的特征,因为如果是RNN或者LSTM,需要依次序序列计算,对于远距离的相互依赖的特征,要经过若干时间步步骤的信息累积才能将两者联系起来,而距离越远,有效捕获的可能性越小。
除此外,Self Attention对于增加计算的并行性也有直接帮助作用。
下面,简单介绍一下Self Attention的计算过程。(这段摘自The Illustrated Transformer )
Step 1:根据输入向量计算得到三个向量:Query、Key、Value
输入单词经过Embedding向量化后,通过分别和
W
Q
W_Q
WQ、
W
K
W_K
WK、
W
V
W_V
WV(这三个矩阵可以通过训练得到)做矩阵乘法,就可以得到Query、Key、Value。
Step 2:将Query和所有的Key做相似性计算,得到score
现在假设要翻译Thinking这个词,即Query=Thinking。那么就让
q
1
q_1
q1和所有的
k
k
k做点积,得到score。
Step 3:将score除以8(key维数的平方根),为了更稳定的梯度。然后用softmax做归一化。归一化的目的是使所有score转化为0-1之间的值并且加和为一,另外还可以突出值的相对重要性。
Step 4:将softmax分值与value按位相乘。保留关注词的value值,削弱非相关词的value值。然后将所有加权向量加和,产生该位置的self-attention的输出结果即
z
1
z_1
z1。
主要是介绍Transformer,然后简单介绍在其他领域的应用。
Transformer是Google机器翻译团队2017年在论文Attention is all you need中提出来的模型,该结构实际上是多层Self Attention堆叠。Transformer模型并行性好,又适合捕获长距离特征。 Transformer也成为GPT、BERT等表现优异的预训练模型的特征提取器。甚至有人说,未来Transformer可能取代RNN,由此可见其优异的表现。
中间蓝色框框就是Transformer的结构,由多个Encoder和Decoder组成。
下面,具体看看每个Encoder和Decoder的结构。
对于Encoder来说,由一个Self Attention层和一个前向传播层组成。Self Attention层可以帮助编码器在对特定单词编码时查看输入语句中的其他单词。Decoder除了这两层,还有一个Encoder-Decoder Attention层,有助于解码器能够关注到输入句子的相关部分。
那么,Transformer有哪些优点呢?这些优点又是通过什么机制实现的呢?
并行性
每个位置的词仅仅流过它自己的编码器路径。在Self Attention层中,这些路径两两之间是相互依赖的。前向传播层则没有这些依赖性,在流经前向网络时可以并行执行。
多头注意力机制(Multi-headed Attention)
在计算Query、Key、Value时,采用了多个不同的
W
Q
W_Q
WQ、
W
K
W_K
WK、
W
V
W_V
WV,分别得到不同的<Query、Key、Value>三元组。这样做扩展了模型集中于不同位置的能力,赋予attention多种子表达方式 。从下面这个例子就可以看出来:
这是两个Attention head得到的两组<Query、Key、Value>的可视化结果。可以看到,编码"it"时,一个attention head集中于"the animal"(橘色部分),另一个head集中于“tired”(绿色部分),某种意义上讲,模型对“it”的表达合成了的“animal”和“tired”两者。但是,如下图用了8个Attention head时,结果变得难以解释。
3. Positional Encoding:保留输入向量的词序
在向量输入到Encoder之前,通过和Positional Encoding做运算,可以保留输入向量在句子的词序特征。
最后,通过一个动图看一下Transformer的计算过程:
编码器从输入序列的处理开始,最后的编码器的输出被转换为K和V,它俩被每个解码器的“encoder-decoder atttention”层来使用,帮助解码器集中于输入序列的合适位置。
最后的最后,介绍一下Attention机制在图像和音频领域的应用。
根据给定图片生成句子“A person is standing on a beach with a surfboard.”
白色亮块代表在翻译每个单词时的注意力情况。在翻译“person”、“surfboard”等词的时候,注意力是集中于图片上的相应物体的。
语音识别中音频序列和输出字符之间的Attention
可以看到,音频和字符之间的Attention基本是对齐的。
下面,是一些参考文章,这篇博客大部分也都是摘自这些文章的,十分感谢。
深度学习中的注意力模型(2017版) 十分详细通俗的介绍了Attention,这篇博客也是建立在它的基础上的。
The Illustrated Transformer 对Google论文的解读,写的很好很好很好
The Annotated Transformer 哈佛大学对Attention的Pytorch实现
注意力机制(Attention Mechanism)在自然语言处理中的应用
从Word Embedding到Bert模型—自然语言处理中的预训练技术发展史
也是张大神的文章,讲了Word Embedding、ELMO、GPT、BERT。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。