提纲:
1. 动机
2. 发展过程
3. 应用点
4. 代码实现
1. 动机
1.1 人类的视觉注意力
视觉注意力机制是人类视觉所特有的大脑信号处理机制,人类通过快速扫描全局图像,获得需要重点关注的目标区域,也就是一般所说的注意力焦点,而后对这一区域投入更多的注意力资源,以获得更多所需要关注目标的细节信息,而抑制其他无用信息。
这是人类利用有限的注意力资源从大量信息中快速筛选出高价值信息的手段,是人类在长期进化过程中的一种生存机制,人类视觉注意力机制极大地提高了视觉信息处理的效率和准确性。
下图形象化展示了人类在看到一副图像时是如何高效分配有限的注意力资源的,其中红色区域表明视觉系统更关注的目标,很明显对于下图的场景,人们会把注意力更多投入到人的脸部、文本的标题以及文章首句等位置。
深度学习中的注意力机制从本质上讲和人类的选择性视觉注意力机制类似,核心目标也是从众多信息中选择出对当前任务目标更关键的信息。
1.2 Encoder-Decoder框架
在传统的编码器-解码器结构中,编码器将输入序列编码为固定长度的向量表示,然后解码器基于这个表示进行解码并输出序列。这样问题在于:输入序列不论长短都会被编码成一个固定长度的向量表示,而解码则受限于该固定长度的向量表示,尤其在输入序列比较长时,模型的性能会变得很差。
既然采用固定长度的向量表示输入序列会限制模型性能,那能不能让解码器每次接收的输入都不一样呢?在每次输出时,让解码器有侧重地关注输入序列的不同部分(比如,在机器翻译中,输出“machine”时,应更加关注“机”和“器”,输出“learning”时,应更加关注“学”和“习”),这就是attention机制的思想。
2. 发展过程
2.1 Show, Attend and Tell: Neural Image Caption Generation with Visual Attention
ICML2015,Attention机制最初由本文在视觉图像领域提出来,文章讨论的场景是图像描述生成,模型框架如下:
文章提出了两种attention模式,即hard attention和soft attention,效果直观上如下:
可以看到,hard attention会专注于很小的区域,而soft attention的注意力相对分散。
模型的encoder利用CNN(VGG net),提取出图像的L个D维的向量ai,i = 1, 2, ……, L,每个向量表示图像的一部分信息。decoder是一个LSTM,每个timestamp t的输入包括3个部分,即context vector Zt、前一个timestep的hidden state ht-1、前一个timestep的output yt-1。Zt由ai和权重ati通过加权得到,这里的权重ati通过attention模型fatt来计算得到,而本文中fatt是一个多层感知机。
源码:https://github.com/kelvinxu/arctic-captions
2.2 Neural Machine Translation by Jointly Learning to Align and Translate
ICLR2015,这是第一个将attention应用到NLP领域(机器翻译任务)的论文。本文旨在扩展encoder-decoder框架下采用固定长度向量表示的限制,允许在预测目标端word时,可以自动搜索源端句子的不同部分。
传统RNN解码每个word时公式如下,其中c表示从encoder来的context vector,一般取最后一个时刻的隐层状态。
本文提出的方法中,解码每个word的公式如下,和上面的区别在于,对于不同的yi,它的context vector 是不一样的。
其中,si表示RNN在 i 时刻的hidden state
ci表示RNN在i时刻的context vector,来自于源端各个隐层状态的加权和,权重通过当前hidden state和源端hidden state计算出来
本文具体采用的RNN结构如下:
其中,si~表示updated state, zi表示update gates,允许前一时刻的信息多大程度的保留,ri表示reset gates,控制前一时刻的信息哪些需要重置。
Alignment model如下:
源码:https://github.com/spro/torch-seq2seq-attention
2.3 Effective Approaches to Attention-based Neural Machine Translation
EMNLP2015,本文旨在探索基于注意力机制的NMT的有效结构,提出了两种attention的改进版本,即global attention和local attention。
这些结构的不同在于ct的计算方式,得到ct之后后面的计算都是一样的。具体地,给定目标端hidden state ht和源端context vector ct之后,将ht和ct拼接之后计算得到attentional vector ht~,然后经过softmax得到yt,即:
Global attention
Global attention 在计算context vector ct的时候会考虑 encoder 所产生的全部hidden state。记 decoder 时刻t的target hidden为ht,encoder的全部hidden state为hs-,s=1, 2, ……, n,对于其任意的hs-,其权重ats为:
其中score(ht, hs-),文章给出了四种计算方法:
其中,第4种为特殊情况,仅仅与位置有关,与ht-无关。
Local attention
Global attention 可能的缺点在于每次都要扫描全部的source hidden state,计算开销较大,对于长句翻译不利,为了提升效率,提出local attention,每次只focus一小部分的source position。
这里,context vector ct的计算只focus窗口[pt-D, pt+D]内的2D+1个source hidden states(若发生越界,则忽略界外的source hidden states)。其中pt是一个source position index, 可以理解为attention的“焦点”,作为模型的参数,D根据经验来选择(文章采用10)。关于pt的计算,文章给出了两种计算方式:
Monotonic alignment (local-m):
Predictive alignment (local-p):
其中Wp,Vp是模型的参数,S是source sentence的长度,易知pt属于[0, S]。
权重at(s)的计算如下:
可以看出,距离中心pt越远的位置,其位置上的source hidden state对应的权重就会被压缩地越厉害。
源码:https://github.com/lmthang/nmt.matlab
2.4 谷歌上线基于注意力机制的翻译系统
2016年Google上线了基于神经网络的机器翻译系统,相对传统模型翻译效果大幅提升,翻译错误率降低60%,其架构就是上文所述的加上attention机制的encoder-decoder框架,主要区别在于它的encoder和decoder均采用了8层的LSTM模型。
2.5 模型统一表示
接下来看一下Google对attention模型的高度抽象概况,将source中的构成元素想象成是由一系列的<key, value>数据对构成,此时给定target中的某个元素query,通过计算query和各个key的相似性或者相关性,得到每个key对应value的权重系数,然后对value进行加权求和,即得到了最终的attention数值。说明一下,在机器翻译任务中,key和value是一样的。
本质上,attention机制是对source中元素的value值进行加权求和,而query和key用来计算对应value的权重系数,因此可以写成如下公式:
从上图还可以将attention机制看作一种软寻址(Soft Addressing):source可以看作存储器内存储的内容,元素由地址key和值value组成,当前有个key=query的查询,目的是取出存储器中对应的value值,即attention数值。通过query和存储器内元素key的地址进行相似性比较来寻址,之所以说软寻址,指的不像一般寻址只从存储内容里面找出一条内容,而是可能从每个key地址都会取出内容,取出内容的重要性根据query和key的相似性来决定,之后对value进行加权求和,这样就可以取出最终的value值,也就attention值。所以,不少研究人员将attention机制看作软寻址的一种特例。
Attention机制的具体计算过程如下图,包括:(1)根据query和key计算相似性或相关性;(2)对原始分值进行归一化处理;(3)根据权重系数对value进行加权求和。
3. 应用点
文本翻译
给定一个法语句子作为输入序列,需要输出翻译为英语的句子,attention机制被用在输出输出序列中的每个词时会专注考虑输入序列中的一些认为比较重要的词。
文本摘要
给定一篇文章作为输入序列,输出一个对应的摘要序列,attention机制被用于关联输出摘要中的每个词和输入中的一些特定词。
语义蕴含
给定一个英文描述的前提和假设作为输入,输出假设与前提是否矛盾、是否相关或者是否成立,attention机制被用于关联假设和前提描述文本之间词与词的关系。
图片描述
给定一张图片作为输入,输出对应的英文文本描述,attention机制被用在输出输出序列的每个词时会专注考虑图片中不同的局部信息。
语音识别
给定一个英文的语音片段作为输入,输出对应的音素序列,attention机制被用于对输出序列的每个音素和输入语音序列中一些特定帧进行关联。
4. 代码实现
以下代码实现了dot_score,general_score,concat_score三种attention方式。
class Attention(torch.nn.Module):
def __init__(self, method, hidden_size):
super(Attention, self).__init__()
self.method = method
if self.method not in ['dot', 'general', 'concat']:
raise ValueError(self.method, "is not an appropriate attention method.")
self.hidden_size = hidden_size
if self.method == 'general':
self.attn = torch.nn.Linear(self.hidden_size, hidden_size)
elif self.method == 'concat':
self.attn = torch.nn.Linear(self.hidden_size * 2, hidden_size)
self.v = torch.nn.Parameter(torch.FloatTensor(hidden_size))
def dot_score(self, hidden, encoder_output):
return torch.sum(hidden * encoder_output, dim=2)
def general_score(self, hidden, encoder_output):
energy = self.attn(encoder_output)
return torch.sum(hidden * energy, dim=2)
def concat_score(self, hidden, encoder_output):
energy = self.attn(torch.cat((hidden.expand(encoder_output.size(0), -1, -1), encoder_output), 2)).tanh()
return torch.sum(self.v * energy, dim=2)
def forward(self, hidden, encoder_outputs):
# Calculate the attention weights (energies) based on the given method
if self.method == 'general':
attn_energies = self.general_score(hidden, encoder_outputs)
elif self.method == 'concat':
attn_energies = self.concat_score(hidden, encoder_outputs)
elif self.method == 'dot':
attn_energies = self.dot_score(hidden, encoder_outputs)
# Transpose max_length and batch_size dimensions
attn_energies = attn_energies.t()
# Return the softmax normalized probability scores (with added dimension)
return F.softmax(attn_energies, dim=1).unsqueeze(1)
参考资料:
https://blog.csdn.net/malefactor/article/details/78767781