#学习笔记#(图在上,对应讲解在下)
首先seq2seq模型可以用来处理许多NLP相关任务,这里介绍加入attention机制的意义以及算法
对于普通Seq2Seq模型,Encoder本身是一个RNN模型,下面的x1,x2,x3,...,xm是embedding过的词向量,对应的h1,h2,3,...,hm是每个时间段对应的输出状态由于RNN的运作机制,每个词的信息都会一路保留至hm,也就是说hm内含有所有词向量的相关信息,这部分作为Encoder的输出s0(这里的s0=hm),同时作为DecoderRNN网络第一步的状态输入(Encoder也有初始的状态输入,可以是默认值0等等),之后s0与Decoder的新输入得到新状态s1并重复此工作至结束。
(本文主要介绍attention机制的应用,对seq2seq模型不做过多介绍)
这里可以看到在Decoder中除了第一次的输入状态有Encoder传入的状态信息,后续的输入并没有继续传入原始的Encoder信息,这就导致若句子过长,模型很容易遗漏许多关键信息,当单词数超过20个,模型输出质量明显下降。
下面开始讲解加入attention的seq2seq,首先Encoder的工作没有改变,输入词向量,编码后输出状态hm=s0。后面的工作发生了变化,对于Encoder中每一个输出hi,s0都与之进行一次align()函数运算(函数内容之后会讲),得到的阿尔法i(用a代指),每个h都对应有自己的a,最后再将hi与ai做加权平均得到c0。
讲一下上面提到的align()函数,首先concatenatehi与s0,在乘一个w矩阵(我个人将其理解为一个改变维度帮助理解词向量的全连接层),对结果进行tanh激活,再乘上一个v向量(同样理解为一个全连接),对结果进行softmax处理使得a1+a2+a3+...+am=1。
这里的w和v全都是需要通过训练得到的参数。
以上所有参数相乘,通过激励函数tanh,再通过softmax统一构成了align()函数。
再介绍另外一种align()函数的内容,可能更好理解一些,而且是与transformer中的attention机制相同的,也是大部分NLP任务的SOTA。
这里加入两个参数Wk和Wq,用每个h去乘Wk得到ki,用s0去乘Wq得到q0,两者内积得到的值再通过softmax得到最终的结果。
同理Wk和Wq都是需要训练得到的参数。
讲完了align()函数接着讲下面的内容,一起来看看加权平均后得到的c0怎么用在Decoder中,普通的seq2seq模型Decoder运作方式如上图左上角的所示,而加入了attention的模型运作方式如右上角所示,在传入数据方面添加了c0,并得到第二个状态s1,这个c0就是相当于对hi的一个整合,并且由于是加权平均,c0的值会更加接近相关性比较大的那个hi*ai,假如输出的状态与x2的输出结果h2关联性最强,那么h2*a2的值在c0中的占比就更大,也就可以理解为注意力更集中于h2。
在得到第二个状态s1后,再次进行相同的运算,用s1与每个hi通过align()函数再加权平均得到c1,由此可见,Decoder的每个输入由于添加了ci,相当于每次输入都提到了Encoder的输出内容,也就避免了信息遗漏或丢失的情况。
依此类推至结束,这就是完整的Seq2Seq(Attention),以上均为自己浅薄的理解,大体介绍了工作原理,有些小的细节我自己也还有一些疑惑,
比如在 hi*s0,求相关性那一步,既然hm与s0完全相等且hm包含所有Encoder的输出内容,那相关性不是应该最大吗?
还需要进行更深层的学习。
最后总结一下:
1、加入了Attention的Seq2Seq可有效避免信息遗忘的情况发生,可以大幅提高模型输出准确率。
2、同时Decoder也知道需要注意那些关联性更强的部分。
3、由于每步都要重新计算ci,运算量过大,可能导致模型训练速度较慢。
附一张Seq2Seq(Attention)的模型使用结果
#图片资料是截自王树森老师的ppt#