输入和输出都是sequence的任务都是一种Sequence-to-sequence Learning,简称Seq2Seq。
Attention其实是一种Dynamic Conditional Generation。在前文描述的Conditional Generation中,我们在每个时间点都将Encoder输出的vector输入到Decoder中,其实我们可以进一步使得Decoder在每个时间点接收到的vector都是不一样的,这就是Attention。Attention有两个好处,第一是应对Encoder输出的vector无法充分有效地表示整个setence的情况,第二是使Decoder在不同时间点关注setence的不同部分(假如要把“机器学习”翻译为“machine learning”,那么在翻译“机器”时就不需要关注“学习”这个暂时无关的word)。
Machine Translation
如上图所示,$h^1,h^2,h^3,h^4$是作为Encoder的RNN中隐藏层的输出,一种方法是$z$为Decoder的输出,$z^0$即时间点为0时的一个初始值。
使用
match
函数计算$h^i$和$z^0$的匹配程度$\alpha_0^1,\alpha_0^2,\alpha_0^3,\alpha_0^4$,举例来讲$\alpha_0^1$中上标$1$表示$h^1$、下标$0$表示时间点为0。match
函数是自定义的,它可以只是一个cosine similarity也可以是一个神经网络等等,如果match
函数中包括参数,那这些参数也是可以通过学习得到的。将$\alpha_0^1,\alpha_0^2,\alpha_0^3,\alpha_0^4$输入到softmax得到$\hat\alpha_0^1,\hat\alpha_0^2,\hat\alpha_0^3,\hat\alpha_0^4$
softmax使得这4个值之和为1,有人说这一步也可以不做
计算Encoder的输出$c^0=\sum\limits_i\hat\alpha_0^ih^i$
若$\hat\alpha_0^1=\hat\alpha_0^2=0.5,\ \hat\alpha_0^3=\hat\alpha_0^4=0$,则代表Encoder只考虑了“机器”二字而没有考虑“学习”二字,由此实现Attention
将$c^0$输入到Decoder得到
得到$z^1$后也就得到了“machine”
按照上述步骤,使用$h^i$和$z^1$计算出$\alpha_1^1,\alpha_1^2,\alpha_1^3,\alpha_1^4$,再用softmax计算出$\hat\alpha_1^1,\hat\alpha_1^2,\hat\alpha_1^3,\hat\alpha_1^4$,再计算出$c^1=\sum\limits_i\hat\alpha_1^ih^i$,再将$c^1$输入到Decoder得到$z^2$,也就得到了“learning”。
重复上述过程直到生成句子的结束(句号)。
Speech Recognition
Attention也可以应用于语音识别。在语音识别中, 输入是声音信号(可以用vector sequence表示),输出是word sequence。
Attention在Speech Recognition中的应用类似于其在Machine Translation中的应用,算法步骤差不多,谷歌有一篇相关论文:《Listen, Attend and Spell》
Image Caption
Attention在Image Caption中的应用类似于其在Machine Translation中的应用,可以将图片的每个region视为Machine Translation任务中的一个character,有一篇相关文章是《Show, Attend and Tell: Neural Image Caption Generation with Visual Attention》。
Attention不只可以做单张Image的Caption,还可以做多张图片/视频的Caption,相关论文如《Describing Videos by Exploiting Temporal Structure》。
Memory Network
Memory Network是在Memory上做Attention。Memory Network最开始是被用在Reading Comprehension上, 也就是给机器看一个document,然后问机器一个question并让它给出answer。
将document表示为多个vector
document由很多个sentence组成,可以用一个vector表示一个sentence,因此一个document可以表示为$x^1,x^2,\dots,x^N$
这一步可以和后面的DNN一起训练
将question表示为一个vector $q$
计算$q$和每个$x^n$之间match的分数$\alpha_1,\alpha_2,\dots,\alpha_N$
计算$e=\sum\limits_{n=1}\limits^N\alpha_nx^n$得到extracted information
这一步的作用是提取出和question相关的setence,由此实现Attention
将extracted information输入到DNN,输出对应的answer
Memory Network还有一个更加复杂的版本。可以将document表示为不同的两组vector,即使用两个vector $h^n$和$x^n$表示document中的每个sentence,然后计算$q$和每个$x^n$之间match的分数$a_n$,此时extracted information为$e=\sum\limits_{n=1}\limits^N\alpha_nh^n$。将extracted information输入到DNN得到对应的answer,同时还可以将extracted information和问题$q$加起来更新$q$(这叫做Hopping)。Hopping可以重复很多次,这就像机器在反复思考。
相关论文:《End-To-End Memory Networks》
Neural Turing Machine
Neural Turing Machine不只是在Memory上做Attention、不只是可以读取memory,它还可以根据match
函数的结果修改存储在memory中的内容。
在Neural Turing Machine中,memory是一个vector sequence
在初始时,memory表示为$m_0^1,m_0^2,\dots,m_0^N$,然后有一组初始的attention weight:$\hat\alpha_0^1,\hat\alpha_0^2,\dots,\hat\alpha_0^N$,计算$r^0=\sum\hat\alpha_0^im_0^i$
将$r^0$和第一个时间点的输入$x^1$输入到一个网络$f$,得到输出$k^1,e^1,a^1$
这个网络$f$其实就是一个controller,它可以是一个DNN、LSTM、GRU等等都可以。
$k^1$的作用就是产生attention:$\alpha^i_1=cos(m_0^i,k^1)$,然后用softmax处理$\alpha^i_1$即可得到$\hat\alpha_1^i$,这里讲的生成attention的方法$\alpha^i_1=cos(m_0^i,k^1)$是简化过的版本,真正的通过$k^1$计算得到$\alpha^i_1$的方法更为复杂。
根据attention weight $\hat\alpha_1^i$和$e^1,a^1$就可以修改memory,$e^1$的作用是把memory中的值清空(erase),$a^1$的作用是把新的值写到memory里。$m_1^i=m_0^i-\hat\alpha_1^ie^1\odot m_0^i+\hat\alpha_1^ia^1$,通常attention weight $\hat\alpha$的分布会比较sharp,即其中某一维接近1而其它维都接近0,因此可以控制$e^1,a^1$清空或写入memory中的哪个值。
Pointer Network
Pointer Network用来求解凸包(Convex Hull)。
求解凸包问题中,输入和输出都是一个point sequence。
假如使用Seq2Seq求解凸包问题,每个point用其x和y坐标表示,那输入就是多个point,输出则是point的索引,这样不可行。如果Encoder是RNN则可以处理point数量不确定的输入,但假如在训练时输入中最多只有50个point,而如果测试时需要输出100个point,那Decoder就无法输出51-100,因此这种方法是不可行的。
我们可以使用Attention Model,假设有一个key $z^0$,使用$z^0$为输入中的每个point计算attention weight,选择attention weight最大的那个point,模型输出即该point的索引,这样不管输入了多少个point,都能正确输出point的索引。使用输出的point的x和y坐标计算得到$z^1$,然后用$z^1$计算输入中每个point的attention weight,并选择attention weight最大的那个point,输出该point的索引。重复以上过程直到输出END
。
Summarization
可以将summarization理解为求解凸包一样的问题:从一个document中选择几个word,详见《Get To The Point: Summarization with Pointer-Generator Networks》。
Machine Translation
比如在将英语翻译为法语时,一些word并不用进行翻译,通过Pointer Network提取出来直接用就好了。
Chat-bot
比如用户说“我叫臭咸鱼”,就可以通过Pointer Network将“臭咸鱼”这个word直接提取出来。
Recursive Network
Recursive Network是Recurrent Neural Network的泛化版本,Recurrent Neural Network其实是Recursive Network的subset。
如下图所示,以Sentiment Analysis为例,输入为一个word sequence,输出为sentiment(假设是5级),输入的word sequence(假设有4个word)经过word embedding可以表示为vector sequence $x^1, x^2, x^3, x^4$,输出是一个5维的vector。
如上图所示,如果用Recurrent Neural Network实现Sentiment Analysis,初始有一个值$h^0$,我们的RNN是$f$,将$h^0,x^1$输入到$f$得到$h^1$,再将$h^1,x^2$输入到$f$得到$h^2$,再将$h^2,x^3$输入到$f$得到$h^3$,再将$h^3,x^4$输入到$f$中得到$h^4$,将$h^4$输入到模型$g$(可以是几个层)中得到最终的sentiment。
如上图所示,如果用Recursive Structure实现Sentiment Analysis,需要先确定word和模型输出之间的关系,比如$x^1$和$x^2$、$x^3$和$x^4$分别是两组,我们的模型是$f$,将$x^1,x^2$输入到$f$中得到$h^1$,将$x^3,x^4$输入到$f$中得到$h^2$,将$h^1,h^2$输入到$f$中得到$h^3$,再把$h^3$输入输入到模型$g$(可以是几个层)中得到最终的sentiment。因为模型$f$的输入可以是$x^i$或$h^i$,所以需要使得$x^i$和$h^i$的维度相同。
与Recursive Network相关的模型有:Recursive Nerual Tensor Network、Matrix-Vector Recursive Network、Tree LSTM。
除了Sentiment Analysis,Recursive Network还可以用来处理其它与sentence相关的任务。
Github(github.com):@chouxianyu
Github Pages(github.io):@臭咸鱼
知乎(zhihu.com):@臭咸鱼
博客园(cnblogs.com):@臭咸鱼
B站(bilibili.com):@绝版臭咸鱼
微信公众号:@臭咸鱼
转载请注明出处,欢迎讨论和交流!