参考文章: https://blog.csdn.net/Tink1995/article/details/105012972
在NLP中Encoder-Decoder框架主要被用来处理序列-序列问题,也就是输入一个序列,生成一个序列的问题,可以做文本摘要、翻译和QA系统,这个框架所使用的模型主要有seq2seq模型和Transformer。
Encoder编码器将输入
缺点:每个输入对于输出的效果是一样的,不合理。仅有一个中间编码C也不足以表述完整的输入信息(过长时)。因此提出了注意力机制。
attention就是模仿人的注意力机制,可以根据当前时刻的不同输出关注对应的不同输入(对应到多个中间状态C)。
比如:当我们在预测Y1时,可能Y1的注意力是放在C1上,那就用C1作为语义编码,当预测Y2时,Y2的注意力集中在C2上,那就用C2作为语义编码,以此类推,就模拟了人类的注意力机制。因此,计算的关键就是如何算出C1,C2,C3…Cn值,从而判断每次在做解码的时候注意力应该放在哪个位置。
AM模型的关键就是:在生成每个单词Yi的时候,由原来固定的中间语义表示C换成了根据当前输出单词来调整成加入注意力模型的变化的Ci。
以翻译任务"Tom chase Jerry" —— "汤姆追逐杰瑞"为例,我们希望输出杰瑞时注意力在Jerry上分配的最多,下为注意力模型分配给不同英文单词的注意力大小:
(Tom,0.3)(Chase,0.2)(Jerry,0.5)
每个Ci对应不同输入单词的注意力分配概率分布:
f2("Tom"),f2("Chase"),f2("Jerry")就是对应的隐藏层的值h("Tom"),h("Chase"),h("Jerry")。g函数就是加权求和,αi表示权值分布。因此Ci的公式就可以写成:
因此,现在的问题就只剩下,怎么知道attention模型所需要的输入单词注意力分配概率分布值呢?也就是αij ?
decoder上一时刻的输出值Yi-1与上一时刻传入的隐藏层的值Si-1通过RNN生成Hi,然后计算Hi与h1,h2,h3…hm的相关性,得到相关性评分[f1,f2,f3…fm],然后对Fi进行softmax就得到注意力分配αij。然后将encoder的输出值h与对应的概率分布αij进行点乘求和,就能得到注意力attention值了。
Attention机制并不是一定要像上文一样,基于Encoder-Decoder框架。
参照上图理解Attention,将Source中的构成元素想象成是由一系列的
Lx表示source的长度,Similarity(Q,Ki)计算如下:
点积:就是将Query和Keyi进行点积,Transformer中就是用的这种方法。
Cosine相似性-余弦相似度:分子就是两个向量Query与Key的点积;分母就是两个向量的L2范数,(L2范数:向量各元素的平方和然后求平方根)。
计算出Query和Key_i的相似性后,引入类似SoftMax的计算方式对其相似性得分进行数值转换,一方面可以进行归一化(将原始计算分值整理成所有元素权重之和为1的概率分布)另一方面也可以通过SoftMax的内在机制更加突出重要元素的权重。即一般采用如下公式计算:
其计算结果 ai 即为 Value_i 对应的权重系数,然后进行加权求和即可得到Attention数值:
以上的三个阶段的计算similarity、softmax和加权求和,即可求出针对Query的Attention数值,是目前绝大多数的注意力机制计算方法。总结如下:
阶段1:Query与每一个Key计算相似性得到相似性评分s;
阶段2:将s评分进行softmax转换成[0,1]之间的概率分布;
阶段3:将[a1,a2,a3…an]作为权值矩阵对Value进行加权求和得到最后的Attention值。
总的来说,Attention机制不再依赖于RNN,解决了RNN不能并行计算的问题,速度快。但只能在Decoder阶段实现并行运算,Encoder部分依旧采用的是RNN/LSTM这些按照顺序编码的模型,这部分还是无法实现并行,不够完美。而且,正是因为Encoder部分目前仍旧依赖于RNN,所以对于中长距离之间,两个词相互之间的关系没有办法很好的获取。
为了改进这两个缺点,就提出了Self-Attention。
在一般任务的Encoder-Decoder框架中,输入Source和输出Target内容是不一样的,例如中译英,Attention机制发生在Target的元素和Source中的所有元素之间。而Self Attention可以理解为Target=Source这种特殊情况下的注意力计算机制,其他过程则是一样的,只是计算对象发生了变化而已,相当于是Query=Key=Value(之前K和V是来自source,Q来自target)。
上述为例,想知道这句话中的its指代的是什么,与哪一些单词相关,那么就可以将its作为Query,然后将这一句话作为Key和Value来计算attention值,找到与这句话中its最相关的单词。通过self-attention发现its在这句话中与之最相关的是Law和application,也确实如此。
引入Self Attention后会更容易捕获句子中长距离的相互依赖的特征,因为如果是RNN或者LSTM对于远距离的相互依赖的特征,要经过若干时间步骤的信息累积才能将两者联系起来,而距离越远,有效捕获的可能性越小。但是Self Attention在计算过程中会直接将句子中任意两个单词的联系通过一个计算步骤直接联系起来,所以远距离依赖特征之间的距离被极大缩短,有利于有效地利用这些特征。除此外,Self Attention对于增加计算的并行性也有直接帮助作用。正好弥补了attention机制的两个缺点。