人类的视觉注意力
Attention机制借鉴了人类的视觉注意力机制。视觉注意力机制是人类视觉所特有的大脑信号处理机制。人类视觉通过快速扫描全局图像,获得需要重点关注的目标区域,也就是一般所说的注意力焦点,而后对这一区域投入更多注意力资源,以获取更多所需要关注目标的细节信息,而抑制其他无用信息。如下图1:人类用眼睛扫描下面的图片时,红色部分就代表人类在图片中更关注的部分,显然我们把注意力更集中在婴儿的脸部,文本标题,而其它部分信息则不是我们注意力关注的地方。
Attention机制思想与视觉注意力机制一样,本质都是从众多信息中挑选出目前我们要重点关注的对象,挑选出对所处理的问题更关键的信息。
图1
Attention机制发展史
Attention机制的思想最早是在九几年的时候被提出来应用于图像领域。随后在2014年,谷歌发表了《Recurrent Models of Visual Attention》论文,他们在RNN模型上使用了attention机制来进行图像分类,然后取得了很好的性能,Attention机制就逐渐开始火了起来。后面Attention机制开始进入NPL领域。Bahdanau等人在论文《Neural Machine Translation by Jointly Learning to Align and Translate》中首次使用了类似attention的机制,在机器翻译任务上将翻译和对齐同时进行,接着attention机制就被广泛应用在基于RNN/CNN等神经网络模型的各种NLP任务,并取得了不错的效果。2017年,google机器翻译团队发表的《Attention is all you need》中大量使用了自注意力(self-attention)机制来学习文本表示,这篇论文引起了人们大量的关注。因而自注意力机制研究也在那时逐渐成为研究热点,并在各种NLP任务上进行探索,纷纷都取得了很好的性能。
Encoder-Decoder框架
Encoder-Decoder 框架是深度学习中非常常见的一个模型框架,例如在 Image Caption 的应用中 Encoder-Decoder 就是 CNN-RNN 的编码 - 解码框架;在神经网络机器翻译中 Encoder-Decoder 往往就是 LSTM-LSTM 的编码 - 解码框架,在机器翻译中也被叫做 Sequence to Sequence learning(seq2seq)。目前大多数的注意力模型都是依附在 Encoder-Decoder 框架下,但需要注意的是注意力机制作为一种思想可以和多种模型进行结合,其本身不依赖于任何一种框架,并不是只能运用在该模型中。
下面讲解Attention机制的计算流程时,也是以 Encoder-Decoder 框架下的机器翻译的应用为例。
Encoder-Decoder 框架中 Encoder叫做编码器,Decoder叫做解码器,其具体结构如下图2:
图2
以文本翻译翻译为例,假如有一个句子“我爱中国”,翻译成英文就叫做“I love china”。我爱中国这几个字分别会有一个向量进行表示,对应着x1、x2、x3、x4,对于Encoder-Decoder 框架所要做的就是把中文“我爱中国”,即x1、x2、x3、x4,依次丢入Encoder进行编码,之后得到一个中间语义向量,我们希望这个中间语义向量放入Decoder 后依次输出y1、y2、y3,即翻译出“I love china”。文本翻译中,Encoder和Decoder一般用的是RNN处理数据,其过程类似下图3:
图3
图3前半部分代表Encoder阶段。其中ht是代表当前时刻的隐藏状态,一般由上一时刻的隐藏状态 ht−1 和当前时刻的输入 xt 决定的;c是中间语义向量,其得出方式有以下几种(图4):
图4
q表示某种非线性神经网络;
图3的后半部分代表的是Decoder阶段。其根据获取到中间语义向量c和隐藏状态ht-1,依次输出y1、y2、y3,即翻译出“I love china”。
Encoder-Decoder 框架可以看作是处理<Source,Target>的过程,Source就是我们输入的数据(进行encoder),Target就是我们期待通过Source而输出的数据(进行decoder);对于文本翻译来说,Source就是一个句子,我们期待的Target就是把句子翻译成英文或者其它语言。对于语音识别来说,Source就是语音流,Target就是期待输出的文本信息…
Soft Attention模型
在上述的Encoder-Decoder 框架中,未考虑attention机制时,Encoder阶段得到的中间语义向量C是“固定”的,在Decoder阶段输出每个yi时,C都不发生任何变化,这就导致翻译出来的序列的每一个字都是同权地考虑了输入中的所有的词,例如:输出“I love China”时,输出的每一个yi,“我爱中国“里面每个字,即所有的xi,对每一个yi的输出的影响权重都是一样的,这显然不符合实际,比如:当翻译出”China“时,显然此时”中国”两字,即x3、x4对其的翻译更重要,而x1,x2显然对翻译出“China”影响非常小;但当翻译出“love”时,显然此时x2(“爱”)对其更重要,而其余的xi对其影响则非常小。因此,也把这种没有体现出不同输入的重要程度的Encoder-Decoder 框架叫做分心模型。
未引入attention机制进行翻译时,如果句子比较短,翻译时可能问题不大,但如果句子比较长,此时所有的语义信息都只通过一个中间语义向量来表示,单词本身的信息消失,则会导致翻译出来的句子会丢失很多细节信息。
而引入attention机制就是为了从序列中学习到每一个元素的重要程度,然后按重要程度将元素合并。因此,attention机制可以看作是Encoder 和 Decoder 之间的接口,它向 Decoder 提供来自每个 Encoder 隐藏状态的信息。通过该设置,模型能够选择性地关注输入序列的有用部分,从而学习它们之间的“对齐”(对齐是指将原文的片段与其对应的译文片段进行匹配)。这就表明,在 Encoder 将输入的序列元素进行编码时,得到的不在是一个固定的中间语义向量 C ,而是存在多个中间语义向量 Ci,且不同的中间语义向量由不同的序列元素以不同的权重参数组合而成。
例如:上述Encoder-Decoder 框架在引入attention机制后,翻译“I love China”中的“China”时,会给xi分配不同的影响权重,假设为(我,0.1)、(爱,0.1)、(中 ,0.4)、(我,0.4),每个字里面的概率代表当前输出“China”时对其的影响大小,也叫做注意力大小,即翻译“China”时,应该着重关注哪些元素。因为输出不同的yi时,分配给xi的权限系数是不一样的,所以由此产生的中间语义变量C也是变化的,如下图5:
由上述可知,attention机制中,最关键的就是算出这个变化的Ci和当前Ci下的输入元素的权重系数,下面先讲一下这个Ci怎么算。
Ci一般由各个元素按其重要程度加权求和得到,即由下式:
以上述翻译”我爱中国“为例,则有图6:
其中Lx代表序列长度;hi可以看作是xi所代表的信息,因为文本翻译一般用RNN处理,hi也叫做隐藏状态;aij就是一个概率,反映了元素 xj 对 Ci的重要性;
那么每次计算Ci时的各个元素的概率怎么得到?
可以用下图7、图8去描述这个过程:
图7
图8
上图7中是一个简略的attention机制中的Decoder部分展示(采用RNN),图8就是中间语义变量C2中各元素权重系数计算过程,其实就是拿当前要输出的yi的前一时刻的隐藏状态,例:图7中,输出y2时,就是取h‘1,然后把h‘1与输入序列中每个元素的隐藏状态hj进行相关计算(计算过程下面再讲),来获得输出单词yi和每个输入词语的对齐可能性,把计算结果经过Softmax进行归一化就得到了符合概率分布取值区间的注意力分配概率分布数值。
怎么理解输出单词yi和每个输入词语的对齐可能性?
对齐可能性其实就是对其概率,目标句子生成的每个单词对应输入句子单词的概率分布可以理解为输入句子单词和这个目标生成单词的对齐概率。
Attention机制本质思想
从上文讲述的Soft Attention例子中,把Attention机制做进一步抽象,便可得到Attention机制的本质思想,如下图9:
下面对上图9进行解释,我们可以将Source中的构成元素想象成是由一系列的<Key,Value>数据对构成,此时给定Target中的某个元素Query,通过计算Query和各个Key的相似性或者相关性,得到每个Key对应Value的权重系数(也叫attention score),然后对Value进行加权求和,即得到了最终的Attention数值。所以本质上Attention机制是对Source中元素的Value值进行加权求和,而Query和Key用来计算对应Value的权重系数。即可以将其本质思想改写为如下公式:
其中,Lx代表Source中序列长度;在上文所讲述的例子当作不容易看出attention机制的本质思想,因为在机器翻译中,Source中的Key和Value一般指的是同一个东西,即每个词语对应的语义编码。
在开头时我们讲过,把Attention理解为从众多信息中挑选出目前我们要重点关注的对象,挑选出对所处理的问题更关键的信息,忽略大多不重要的信息,这其实就体现在权重系数的计算上,权重越大代表越聚焦于其对应的Value值上,即权重代表了信息的重要性,而Value是其对应的信息。
需要注意的是,计算出来的 attention value 是一个向量,代表序列元素 xj的编码向量,包含了元素 xj 的上下文关系,即同时包含全局联系和局部联系。全局联系很好理解,因为在计算attention value 时考虑了该元素与其他所有元素的相似度计算;而局部联系则是因为在对元素 xj 进行编码时,重点考虑与其相似度较高的局部元素,尤其是其本身。
Attention具体计算过程
进一步,根据现有的大多数attention的计算过程进行总结概括,可有下图10:
如上图,attention机制的计算过程可大致分为3个阶段:
第一阶段,根据Query与某个key i,计算两者的相关行,即计算权重系数,计算函数常见的有以下几种:
第二阶段,在上一阶段产生的分值根据具体使用的方法不同其数值取值范围也不一样,在第二阶段就引入类似SoftMax的函数对第一阶段的得分进行数值转换,进行归一化,将原始计算分值整理成所有元素权重之和为1的概率分布;另一方面也可以通过SoftMax的内在机制更加突出重要元素的权重。即一般采用如下公式计算:
第三阶段,进行加权求和就可以得到最终的attention value:
Hard Attention
上述所讲的Soft Attention的计算过程是会对Source中每个元素赋予一个经过SoftMax函数处理过的match概率,所以才叫做Soft Attention。如果不这样做,直接把source中某个特定的元素(其对target中某个输出元素有很大的影响),与target中某个输出元素对齐,而其它source中的元素硬性地认为对齐概率为0,这就是Hard Attention Model的思想,如下图11:
Self Attention
Self Attention也被称为intra Attention(内部Attention)。在一般任务的Encoder-Decoder框架中,输入Source和输出Target内容是不一样的,比如对于英-中机器翻译来说,Source是英文句子,Target是对应的翻译出的中文句子,Attention机制发生在Target的元素Query和Source中的所有元素(values)之间。而Self Attention顾名思义,指的不是Target和Source之间的Attention机制,而是Source内部元素之间或者Target内部元素之间发生的Attention机制,也可以理解为Target=Source这种特殊情况下的注意力计算机制。
对于上面所述的机器翻译,引入attention机制本质上是为了让Source中的单词与Target中的单词对齐。那么引入Self Attention对机器翻译又有什么好处呢?
Self Attention可以捕获同一个句子中单词之间的一些句法特征或者语义特征,如下图12、图13:
由上图可知,很明显,引入Self Attention后会更容易捕获句子中长距离的相互依赖的特征,因为如果是RNN或者LSTM,需要依次序序列计算,对于远距离的相互依赖的特征,要经过若干时间步步骤的信息累积才能将两者联系起来,而距离越远,有效捕获的可能性越小。但是Self Attention在计算过程中会直接将句子中任意两个单词的联系通过一个计算步骤直接联系起来,所以远距离依赖特征之间的距离被极大缩短,有利于有效地利用这些特征。除此外,Self Attention对于增加计算的并行性也有直接帮助作用。
下面简单介绍一下Self Attention的计算过程:
假设我们有4个序列元素a1、a2、a3、a4,用Self Attention 生成b1、b2、b3、b4,其中bi为以ai为query,其余的为values,进行相关性计算后加权求和得到的结果,即使用了attention机制。
对于a1、a2、a3、a4有下图14:
其中qi、ki、vi的计算过程如下图15(以点积计算方式为例):
对于b1我们有计算过程如下图16:
上图算b1的过程就是用a1的query与a2、a3、a4进行相关性计算得到权重系数,然后把其与a1、a2、a3、a4对应的values进行加权求和即可以得到b1;计算b2、b3、b4同理。计算b2的如下图17: