在上一次讨论中,我们重点讲述了RNN的长时记忆问题,作为RNN最显著的缺点,围绕其展开的研究也众多。而运用外部记忆是其中非常重要的一种思路。 简而言之,既然RNN难以记住很久以前的信息,我们便在RNN之外添加一个记忆模块。比起改造RNN本身,这种方法更偏工程,但很实际,我们所处的NLP领域中也是以应用研究为主,所以解决问题比方法优美更加重要。
大部分使用外部记忆的模型都可以抽象为三部分,控制器(通常是一个RNN),读取内存,写入内存。
首先,内存(Memory)是一个固定大小的矩阵(N
我们发现读写最重要的部分就是分布$w$,我们也可以用Attention的思想理解它,它就是对每个位置Attention的系数。而求这个Attention的方法和我们现在常用的有一定区别。
大致可以分为两种思路,很多模型都同时使用了这两种思路,一是内容索引,二是位置索引,顾名思义,内容索引指只根据内容决定读写的位置,不考虑所在位置。即同一个向量放在内存中不同位置是等效的,而位置索引相反,只考虑所在位置,不考虑内容,比如存放在第一个位置的向量就应该如何如何而不考虑它的具体内容。
具体方法比较繁琐,但不难,原paper写的比较清楚 https://arxiv.org/pdf/1410.5401.pdf
Attention最早出现并不是我们现在常用的self-attention,当时通常是把attention作为一种信息选取的工具,类似于NTM的读取机制。 除了在encoder-decoder模型中大量使用外,attention还有很多其他用法,比如在RNN的每一步都对历史信息进行attention。
当然我们在这里更为关注的是attention的形式问题, \begin{align} \alpha_i &= V^T \mathrm{tanh}(WQ+UK_i) \ \alpha_i &= MLP([Q;K_i]) \end{align} 早期的Attention大部分使用加法,或者拼接(实际是一种)的方式。其实和我们的现在常用的点积形式并没有太多性能差别。但如果拓展到self-attention,效率就比较底了。 从这里也可以看出,Attention系列的研究动机比RNN时代要简略,很多工作更倾向于通过实验从多种设计中选择一种,而不是探讨不同设计的特性。
如我们以上所示,attention的含义开始是从多个候选项中选择一个,而之后一些工作提出,这种选择是否也应该考虑特征的维度,即不同维度是否可以套用不同的attention。而其代表工作就是多维attention,每个维度都有不同的attention。这种方法确实显著提高了attention的表达能力,但物理含义和效率都不佳,人们又慢慢转向了多头机制(multi-head)。其实多头机制很早就有了,在NTM中就有应用,但过了几年,才最终形成我们现在常用的 multi-head dot-product self-attention。其实现在的做法未必最优,只是一个权衡了多方面因素的暂时解决方案。
图太长就不贴上来了,这篇工作对self-attention的探索很有意义
Attention的具体含义其实并不清晰,有人解释为多选一,有人解释为动态卷积,有人解释为GNN。 但有一些基本的概念,即Attention和CNN和RNN不同,在关系建模上与输入内容相关,换言之是对不同输入是动态处理的。这里的“动态”和“静态”指的是直接影响,因为从参数角度,所有网络都是“静态”的。另外需要注意的是attention并不一定是bilinear形式的。
\begin{align} \alpha = x^T W y \end{align}