你需要知道Attention
起这个标题的原因是,春招时期写了一篇关于word2vec的文章,按照文章的思路跟面试官讲word2vec或者里面的细节,基本上没有扑街的,有些面试官也表示讲的很好。
益达:Embedding之word2vec但是有面试官这么问我:「可以看出这基础很好,但Attention、Bert等前沿模型近期很热门啊,有机会你再了解一下吧」。我当场鼠躯一震,觉得自己需要继续了解一下NLP的前沿模型了!
虽然自己开的专栏叫益达的Embedding空间,本著实用和全面的原则,近期我会写一点自己对Attention的理解。这篇文章只讲传统Attention,self-Attention留到下一篇吧。
Attention起源于图像领域的注意力机制(此处略去好多字...),发展史我这里就不多说了。直接开始切入正题吧!
1、seq2seq的翻译模型
在介绍Attention之前,有必要说一下seq2seq的翻译模型,这个模型很有利于理解Attention。可以将seq2seq看成一种通用的框架,它的输入是一个序列,输出是一个序列,好比翻译任务,输入「今天是晴天」,输出「Today is sunny」。我们使用RNN来seq2seq,RNN的结构如下:
对于每一个时间步(序列中的一个元素)将涉及2个输入, 和
(类比LSTM,我们可以将
看做网路的记忆,只不过RNN没有「长短期记忆」,只有「长时记忆」),同时具有2个输出(两个输出都是
)。于是一个最朴素的seq2seq可以画作下图:
对于上图,我们可作如下解释。Encoder部分具有初始记忆H0,和句子的第一个单词一同输入第一个神经元,然后得到输出 ,直至句子的最后一个单词输入完毕。输入Decoder的只有 中间记忆
,它承载了前面所有输入的记忆特征,并将被用于翻译。
开始翻译时,先输入句子的开始符号<BOS>,此时Decoder里第一个RNN单元接受输入<BOS>和长时记忆 ,得到输出Y1,我们希望这个Y1越接近Today这个单词越好(这里可以近似这么理解)。第二个RNN单元接受长时记忆
和Today,我们希望它能够输出is这个单词,后面同理。这里使用了Teacher Forcing技术,即使用真实的翻译结果来强制模型学到正确的信息,防止错误积累,参见链接。
在这种设计下,Decoder模型将具备2个部分(训练、预测),因为预测的时候没有正确的标签告诉RNN单元,只能使用上一轮的翻译结果作为下一个位置的输入。
- Encoder端 encoder_layer
- Decoder端
- Decoder训练 decoder_layer_train
- Decoder预测/推断 decoder_layer_inference
2、多次利用Encoder记忆
这里我们发现,长时记忆 承载了大量信息,但是在翻译过程中仅被直接利用在Decoder里第一个RNN Cell上。很自然的一个想法是让Decoder中所有单元都得到长时记忆的「福泽」,如下图。
3、Attention的思想
将这个思想进一步扩展:我们既然已经能在翻译过程中每一个单元都使用「长时记忆」,那么我们为什么不把所有的「记忆」都拿过来(而不是丢弃掉中间记忆),供我们挑选呢?OK我认为这个可以看做Attention的另一种出发点,如何利用这些信息呢?
如上图,我们可以充分使用每一个序列的「记忆」,并对不同的「记忆」使用不同的权重。比如翻译「Today」的时候,我们希望「今天」这个词在最终翻译的「贡献」更大(图中以粗线表示更高的权重)。令 表示Encoder中第1个输出对Decoder翻译第t个单词时所产生的贡献,图中
表示在翻译第3个单词「Sunny」时,「晴天」对翻译的贡献程度。
OK先不管 是怎么计算的,考虑一下我们有这个权重了,要怎么计算Decoder的输入呢?在那之前我们先将这些权重归一化吧,使用softmax将权重归一化。这个结果就叫做AttentionScore,注意力评分。
然后再将归一化过后的结果与每个隐层状态相乘。
其中 表示输入序列的长度,相应地有
个Cell输出。根据上式,就能获得一个和原始「长期记忆」C大小相同的向量
(图中粉色虚线双箭头表示Attention和C结合得到
)。将
与Teacher Forcing相结合(就是将Y标签后移一个时间步,用于「监督」Decoder的训练),即完成Decoder的训练部分。推断部分,没有现成的标签,就使用
时刻已经预测得到的单词
作为下一个时间步的输入,并计算
时刻的Attention结果
,输入
时刻的Cell用于翻译。
现在我们可以讨论一下 要怎么计算了,常见的计算方式有3种,点乘、映射、加性:
注意有时候加性计算方式也被写成两个向量concat的形式: ,形式不同但是没有本质区别。
注意力评分是个 大小的矩阵,如果将矩阵绘制出来,就是常说的Attention评分矩阵,可以看到模型学习到的Attention信息。
4、后记和参考文献
发现自己之前使用的分类模型用了Attention实现多分类(当时直接从github拉取的Keras代码),分别实现了在LSTM之前和之后施加Attention。当时还有点纳闷,现在一想,其实Attention就是一种对前一层网路节点评分后输出经softmax加权表示的一个结果。那份代码的网路结构应该如下图(画的有可能有点问题,欢迎大佬指正):
至此程度应该足够应付面试里让简单讲讲Attention的需求了,如果有遗漏欢迎评论区讨论。下一篇准备讲讲self-attention和Transformer。
下面是本文的参考文献。
Understanding LSTM Networks推荐阅读: