文章目录
Attention机制的发家史
Attention机制最早是应用于图像领域的,九几年就被提出来的思想。随着谷歌大佬的一波研究鼓捣,2014年google mind团队发表的这篇论文《Recurrent Models of Visual Attention》让其开始火了起来,他们在RNN模型上使用了attention机制来进行图像分类,然后取得了很好的性能。然后就开始一发不可收拾了。。。随后Bahdanau等人在论文《Neural Machine Translation by Jointly Learning to Align and Translate》中,使用类似attention的机制在机器翻译任务上将翻译和对齐同时进行,他们的工作算是第一个将attention机制应用到NLP领域中。接着attention机制就被广泛应用在基于RNN/CNN等神经网络模型的各种NLP任务中去了,效果看样子是真的好,仿佛谁不用谁就一点都不fashion一样。2017年,google机器翻译团队发表的《Attention is all you need》中大量使用了自注意力(self-attention)机制来学习文本表示。这篇论文引起了超大的反应,本身这篇paper写的也很赞,很是让人大开眼界。因而自注意力机制也自然而然的成为了大家近期的研究热点,并在各种NLP任务上进行探索,纷纷都取得了很好的性能。
Attention机制的理解
在进行某种任务时,想要得到的结果肯定与上下文不同位置有着不同程度的关系,而attention机制就是求出这些“程度“(数字)。
总结来说就是不同位置分布不同的权重。
引入attention
Seq2seq模型
一个典型的序列到序列(seq2seq)模型,接收的输入是一个(单词、字母、图像特征)序列,输出是另外一个序列。一个训练好的模型如下图所示:
Encoder-Decoder
模型是由编码器(Encoder)和解码器(Decoder)组成的。其中,编码器会处理输入序列中的每个元素,把这些信息转换为一个向量(称为上下文(context))。当我们处理完整个输入序列后,编码器把上下文(context)发送给解码器,解码器开始逐项生成输出序列中的元素。
在机器翻译任务中,上下文(context)是一个向量(基本上是由数字组成的数组)。编码器和解码器一般都是循环神经网络(你可以看看 Luis Serrano写 的 一篇关于循环神经网络 的精彩介绍)
虽然我们将编码器的上下文向量传给解码器。但实际上,上下文向量是这类模型的瓶颈。因为这使得模型在处理长文本时面临非常大的挑战。
在Decoder中引入Attention
在 Bahdanau et al., 2014 和 Luong et al., 2015 两篇论文中,提出了一种解决方法。这 2 篇论文提出并改进了一种叫做注意力(Attention)的技术,它极大地提高了机器翻译的效果。注意力使得模型可以根据需要,关注到输入序列的相关部分。
首先,编码器会把更多的数据传递给解码器。编码器把所有时间步的 hidden state(隐藏层状态)传递给解码器,而不是只传递最后一个 hidden state(隐藏层状态)。
第二,注意力模型的解码器在产生输出之前,会做一些额外的处理。为了把注意力集中在与该时间步相关的那些输入部分。解码器做了如下的处理:
-
查看所有接收到的编码器的 hidden state(隐藏层状态)。其中,编码器中每个 hidden state(隐藏层状态)都对应到输入句子中一个单词。
-
给每个 hidden state(隐藏层状态)打一个分数(我们先不说明这个分数的计算过程)。
-
将每个 hidden state(隐藏层状态)乘以经过 softmax 归一化的对应分数,从而使得,得分高对应的 hidden state(隐藏层状态)会被放大,而得分低对应的 hidden state(隐藏层状态)会被缩小弱化。
这个加权平均的步骤,会发生在解码器的每个时间步。
现在,让我们把所有内容都融合到下面的图中,来看看注意力模型的整个过程:
- 注意力模型的解码器 RNN 的输入包括:一个 的词嵌入向量,和一个经过初始化的解码器 hidden state(隐藏层状态)。
- RNN 处理上述的 2 个输入,产生一个输出(注意这里的输出会被忽略)和一个新的 hidden state(隐藏层状态向量,图中表示为 h4)。
- 注意力的计算步骤:我们使用编码器的 hidden state(隐藏层状态)和 h4 向量来计算这个时间步的上下文向量(C4)。
- 我们把 h4 和 C4 拼接起来,得到一个向量。
- 我们把这个向量输入一个前馈神经网络(这个网络是和整个模型一起训练的)。
- 前馈神经网络的产生的输出表示这个时间步输出的单词。
- 在下一个时间步重复这个步骤。
下图,我们使用另一种方式来可视化注意力,看看在每个解码的时间步中关注输入句子的哪些部分:
请注意,注意力模型不是盲目地把输出的第一个单词对应到输入的第一个单词。实际上,它从训练阶段学习到了如何在两种语言中,找到对应单词的关系(在我们的例子中,是法语和英语)。下图展示了注意力机制的准确程度(图片来自于上面提到的论文):
seq2seq中的attention机制
- 我们在encoder的过程中保留每个RNN单元的隐藏状态(hidden state)得到(h1……hN)
- 然后对于decoder的每一个timestep,因为有此时decoder的输入和上一步的隐藏状态输出,所以我们可以得到当前步的隐藏状态。假设第t步的(根据上一步隐藏状态输出与当前输入得到的)隐藏状态为St,
在每个第t步利用St和hi进行dot点积得到attention score,也称为“相似度“或者“影响度”,或者“匹配得分”。 - α t = s o f t m a x ( e t ) α^t=softmax(e^t) αt=softmax(et) , 利用softmax函数将dot products转化为attention scores的概率分布。
a
t
=
∑
i
N
α
i
h
i
a_t=\sum_{i}^{N} \alpha_i h_i
at=i∑Nαihi
按照刚才的概率分布,计算encoder的hidden states的加权求和。到这里其实attention的计算就结束了,得到的这个
a
t
a^t
at就已经是decoder的第t时刻的注意力向量了(在后面的文章中,这个
a
t
a_t
at也称作是上下文向量(context vector),符号表示也可能是用
c
t
c_t
ct来表示的)。
最后将注意力向量 a t a_t at,以及decoder的t时刻的hidden state ( s t s_t st),并联起来,然后做后续的步骤(比如加个全连接层做标签预测之类的)。
Attention的通用定义
按照Stanford大学课件上的描述,attention的通用定义如下:
- 给定一组向量集合values,以及一个向量query,attention机制是一种根据该query计算values的加权求和的机制。
- attention的重点就是这个集合values中的每个value的“权值”的计算方法。
- 有时候也把这种attention的机制叫做query的输出关注了(或者说叫考虑到了)原文的不同部分。(Query attends to the values)
Attention的计算变体
首先从大的概念来讲,针对attention的变体主要有两种方式:
1.一种是在attention 向量的加权求和计算方式上进行创新
2.另一种是在attention score(匹配度或者叫权值)的计算方式上进行创新
当然还有一种就是把二者都有改变的结合性创新,或者是迁移性创新。
针对attention向量计算方式变体
大概分成这么几种:
- Soft attention、global attention、动态attention
- Hard attention
- “半软半硬”的attention (local attention)
- 静态attention
- 强制前向attention
Soft attention、global attention、动态attention
这三个其实就是Soft attention,也就是我们上面讲过的那种最常见的attention,是在求注意力分配概率分布的时候,对于输入句子X中任意一个单词都给出个概率,是个概率分布,把attention变量(context vecor)用 c t c_t ct表示,attention得分在经过了softmax过后的权值用 α \alpha α表示
论文:Neural machine translation by jointly learning to align and translate
Hard attention
Soft是给每个单词都赋予一个单词match概率,那么如果不这样做,直接从输入句子里面找到某个特定的单词,然后把目标句子单词和这个单词对齐,而其它输入句子中的单词硬性地认为对齐概率为0,这就是Hard Attention Model的思想。
Hard attention的这个pt,我也没有详细研究,不过我觉得可能跟下面讲的local attention机制的找法差不多。据说Hard attention 一般用在图像里面,当图像区域被选中时,权重为1,剩下时候为0。
https://www.cnblogs.com/Determined22/p/6914926.html
local attention (半软半硬attention)
Soft attention 每次对齐的时候都要考虑前面的encoder的所有hi,所以计算量会很大,因此一种朴素的思想是只考虑部分窗口内的encoder隐藏输出,其余部分为0,在窗口内使用softmax的方式转换为概率。这个local attention相反概念的是global attention,global attention其实就是softmax attention,这里不多赘述global attention了。
论文:Effective Approaches to Attention-based Neural Machine Translation
在这个模型中,对于是时刻t的每一个目标词汇,模型首先产生一个对齐的位置 pt(aligned position),context vector 由编码器中一个集合的隐藏层状态计算得到,编码器中的隐藏层包含在窗口[pt-D,pt+D]中,D的大小通过经验选择。
上式之中,大S指的是源句子的长度,Wp和vp是指的模型的参数,通过训练得到,为了支持pt附近的对齐点,设置一个围绕pt的高斯分布,其中小s是在以pt为中心的窗口中的整数,pt是一个在[0,S]之间的实数。小Sigma σ 一般取窗口大小的一半。
静态attention
静态attention:对输出句子共用一个St的attention就够了,一般用在Bilstm的首位hidden state输出拼接起来作为st(在图所示中为u)
论文:Teaching Machines to Read and Comprehend 以及
Supervised Sequence Labelling with Recurrent Neural Networks
上面这个图是我从论文摘过来的静态attention的示意图,有同学可能会注意到的是:这个前面的每个hidden state 不应该都和这里的 u 算一次attention score吗,怎么这里只有一个r和u进行了交互?
其实他这里的r表示的是加权平均的self attention,这个权就是attention ct向量,这个图里面把attention ct的计算过程省略了。直接跳到了ct和st计算真正的s’t的部分。他这个里面用的实际的attention score的计算并不是用点积,是additive attention,什么是additive attention呢?这个下面就会讲根据按照attention score计算的不同的attention model变体。
针对Attention score的计算方式变体
attention score的计算主要有以下几种:
q
q
q时query向量,
x
i
x_i
xi是value向量。
self-attention
Attention机制的计算流程
Attention机制的实质其实就是一个寻址(addressing)的过程,如上图所示:给定一个和任务相关的查询Query向量 q,通过计算与Key的注意力分布并附加在Value上,从而计算Attention Value,这个过程实际上是Attention机制缓解神经网络模型复杂度的体现:不需要将所有的N个输入信息都输入到神经网络进行计算,只需要从X中选择一些和任务相关的信息输入给神经网络。
在软性注意力机制(soft attention)中有两种类别:普通模式(Key=Value=X)和键值对模式(Key!=Value)。(与soft attention对应的是hard attention,上一小节讲过了)。
一种强大的Attention机制:为什么自注意力模型(self-Attention model)在长距离序列中如此强大?
(1)卷积或循环神经网络难道不能处理长距离序列吗?
当使用神经网络来处理一个变长的向量序列时,我们通常可以使用卷积网络或循环网络进行编码来得到一个相同长度的输出向量序列,如图所示:
从上图可以看出,无论卷积还是循环神经网络其实都是对变长序列的一种“局部编码”:卷积神经网络显然是基于N-gram(可以理解为窗口)的局部编码;而对于循环神经网络,由于梯度消失等问题也只能建立短距离依赖(RNN具有梯度消失的缺陷,缓解方法是LSTM)。
(2)要解决这种短距离依赖的“局部编码”问题,从而对输入序列建立长距离依赖关系,有哪些办法呢?
如果要建立输入序列之间的长距离依赖关系,可以使用以下两种方法:一 种方法是增加网络的层数,通过一个深层网络来获取远距离的信息交互,另一种方法是使用全连接网络。 ——《神经网络与深度学习》
由上图可以看出,全连接网络虽然是一种非常直接的建模远距离依赖的模型, 但是无法处理变长的输入序列。不同的输入长度,其连接权重的大小也是不同的。
这时我们就可以利用注意力机制来“动态”地生成不同连接的权重,这就是自注意力模型(self-attention model)。由于自注意力模型的权重是动态生成的,因此可以处理变长的信息序列。
总体来说,为什么自注意力模型(self-Attention model)如此强大:利用注意力机制来“动态”地生成不同连接的权重,从而处理变长的信息序列。
(3)自注意力模型(self-Attention model)具体的计算流程是怎样的呢?
同样,给出信息输入:用X = [x1, · · · , xN ]表示N 个输入信息;通过线性变换得到为查询向量序列,键向量序列和值向量序列:
上面的公式可以看出,self-Attention中的Q是对自身(self)输入的变换,而在传统的Attention中,Q来自于外部。
self-Attention计算过程剖解(来自《细讲 | Attention Is All You Need 》)
注意力计算公式为:
自注意力模型(self-Attention model)中,通常使用缩放点积来作为注意力打分函数,输出向量序列可以写为:
参考文献
https://zhuanlan.zhihu.com/p/35571412
https://zhuanlan.zhihu.com/p/265182368
https://blog.csdn.net/hahajinbu/article/details/81940355
https://zhuanlan.zhihu.com/p/53682800