Memory Networks02 记忆网络经典论文
1 Recurrent Entity Network
这篇论文是facebook AI在2017年的ICLR会议上发表的,文章提出了Recurrent Entity Network的模型用来对world state进行建模,根据模型的输入对记忆单元进行实时的更新,从而得到对world的一个即时的认识。该模型可以用于机器阅读理解、QA等领域。本文参考了Google团队的NTM和其他的神经计算单元,能够基于内容和位置对记忆单元进行读写操作。本文在babi-10k的数据集和Children’s Book Test(CBT)的数据集上实现了最优的结果。
Introduction
EntNet使用了动态长期记忆,因此可以用在语言理解任务,QA等。它跟NTM一样使用固定长度的memory,并且学习基于位置和内容的读写操作。不过它的更新可以多个memory并行处理。EntNet在bAbI数据集上取得了state-of-art的结果,并且是第一个解决了所有了bAbI-10k问题的模型,此外在大的数据集如Children’s Book Test上结果也很好。
简单来说,EntNet的每个memory cell由key和value组成,分别为\(w_i\) 和 \(h_i\)。 每个cell都有一个关联的processor,即一个gated RNN,负责根据当前输入和过去的状态来更新状态。各个memory cell是独立的,因此EntNet可以看做是一系列共享权值的gated RNN。
注意,在多层RNN中,每层的状态更新是通过前一时刻的状态和底层状态来决定的,所以层与层之间的状态是关联的,这与EntNet是不一样的。在另外一篇论文中给出了RelNet,在EntNet的基础上增加了参数\(r_{ij}\)给出每个两个memory \(h_i\)和\(h_j\)的的关联程度,也取得了很好的结果。
模型构建
和之前的模型一样,Entity Network模型共分为Input Encoder、Dynamic Memory和Output Model三个部分。如下图的架构图所示:
Input Encoder
Input Encoder部分将输入的句子序列编码为一个固定长度的向量,此时典型的对句子的处理方式有:
- 词袋子编码向量(对于词表vocab和句子s,对于句子中的所有词w1/s2/…/wn赋权值,但是如果vocab很大的话效率就特别低)
- 利用RNN或者LSTM等时序神经网络模型,使用最后一个时间步长的状态作为句子编码
- 本文中采用将w1/s2/…/wn分别通过embedding层,得到embedding向量,然后进行位置编码,得到句子的向量表示,具体的句子位置编码的介绍在end to end memory network。
\]
\(e_{1}, \ldots, e_{k}\) 为在时间步长t时输入的单词序列的embedding表示, \(f_{1}, \ldots, f_{k}\) 是每一个位置的权重,得到的\(s_t\)就是固定长度的句子的向量表示 \(_{0}\)
Dynamic Memory
Entity network中,在时间步长t得到了t时刻句子的向量表示\(s_t\)。在\(s_t\)之上,有类似于多层GRU的单元即w1,h1,w2,h2,…wm,hm。其中,{w}是key,负责记录实体;{h}是value,负责记录该实体的状态。在时间步长t,{h}由{w}和\(s_t\)两者进行更新,更新公式如下:
g_{j} \leftarrow \sigma\left(s_{t}^{T} h_{j}+s_{t}^{T} w_{j}\right) \\
\tilde{h}_{j} \leftarrow \phi\left(U h_{j}+V w_{j}+W s_{t}\right) \\
h_{j} \leftarrow h_{j}+g_{j} \odot \tilde{h}_{j} \\
h_{j} \leftarrow \frac{h_{j}}{\left\|h_{j}\right\|}
\end{array}
\]
- \(g_j\)是一个sigmoid的门函数,用来决定第j层的记忆有多少需要被更新,由{w}和{h}共同决定;
- \(\widetilde{h_{j}}\) 是记忆的候选值, 由 \(h_{j}, w_{j}\) 和 \(s_{t}\) 共同决定, 此处的 \(\phi\) 可以是任意一个激活函数, 本文中选定的是ReLU;
- \(h_{j}\) 就由门限函数\(g_j\)和候选记忆 \(\widetilde{h_{j}}\) 来决定;
- 然后将\(h_{j}\) 进行正则化, 至于为什么正则化, 我猜想应该是保证 \(\widetilde{h}_{j}\) 和 \(h_{j}\) 在同一个区间内, 这样进行更新才有意义。
论文中第三章给出了一个非常具体的例子:
Mary picked up the ball.
Mary went to the garden.
Where is the ball?
前两句是文本,最后一句是问题。由第一句得到在时间步长t的句子表达\(s_{t}\),由第二句得到时间步长t+1的句子表达\(s_{t+1}\)。以\(s_{t}\)和\(s_{t+1}\)来说明动态实体网络是如何捕捉输入从而对记忆单元进行实时的更新。
- 当\(s_{t}\)被读取,w1记录实体Mary,h1记录实体状态Mary拿了一个ball;
- w2记录实体ball,h2记录实体状态ball被Mary拿着;
- 然后\(s_{t+1}\)被读取,读取到Mary,因为w1是记录Mary的key,位置寻址项\(s_{t+1}^Tw_1\)变化,门函数被激活,更新h1实体状态Mary去了garden;
- 因为h2记录ball被mary拿着,因此内容寻址项\(s_{t+1}^Th_2\)变化,门函数被激活,更新h2的实体状态球被mary拿着,球在garden。
即使\(s_{t+1}\)中没有提到和球有关的内容,在时间步长t+1,h2依然会被更新,是因为内容寻址项起了作用。我们称\(s_{t }^Tw_j\)为位置寻址,\(s_{t }^Th_j\)为内容寻址。
Output Model
在原文中使用了一层的记忆网络, 因此得到最后一个时间步长的隐层向量 \(h_{j}\) 以后, 就可以直接输出了:
p_{j} &=\operatorname{Softmax}\left(q^{T} h_{j}\right) \\
u &=\sum_{j} p_{j} h_{j} \\
y &=R \phi(q+H u)
\end{aligned}
\]
H是一个[hidden_size, hidden_size]的待训练矩阵;
R是一个[hidden_size, vocab_size]的待训练矩阵。
最后得到的y是一个vocab大小的向量,代表输出单词的概率,模型的部分也就到此结束了。
总结
实体网络提供了一种根据模型的输入对记忆单元进行实时的更新的记忆模型,在BABI和CBT数据集上都实现了最佳的效果。在论文的表4中,提供了在CBT数据集上EntNet与其他几个问答系统的模型的对比结果:
论文提供了两种模型构造的思路:单轮阅读和多轮阅读。
- 单轮阅读必须按顺序读story和query然后立即产生输出
- 多轮阅读可以使用通过多轮的阅读,使用query来构造story的attention。
因此单轮阅读是更有挑战性的,因为模型事先并不知道query是什么,所以必须学习保留对各种潜在query有用的信息,因此单轮阅读可以看作通用的(即不知道query的情况下)对模型构建“current state of story”能力的测试。而多轮阅读因为知道了问题,所以可以根据问题来选择性的读取story。
从上表中可以看出,在CBT数据集上一向表现不好的NE和CN两个子数据集,通过EntNet表现可以有很大的提升,但还是无法和更复杂的多轮阅读相提并论。
2 hierarchical Memory Networks
这是Bengio团队在2017年发表在ICLR上面的论文“hierarchical Memory Networks”,这篇论文的主要思想是使用分层结构的Memory,目的是在维持准确度的基础上实现训练速度的提升。因为当需要的记忆量很大时,对所有的记忆进行Attention操作,必然会及其浪费时间,而通过本文提出的Hierarchical Memory结构,可以加速选择相关记忆的速度。总结一下本文贡献就是,提出一种新的memory数据结构(基于聚类),和一种新的搜索方法(MIPS)来适应该结构进行评分计算。但是这两个东西都是他们之前的论文“clustering is efficient approximate maximum inner product search”提出的,只不过是用到Memory Networks中来。所以可以理解为是在数据结构层面的改进,而不是模型架构,和前面的论文不太一样。下面我们来看一下: 首先说一下两种用于memory选择的Attention的概念和区别:
- soft Attention: 一般使用softmax对所有的memory计算得分,好处是可以方便的计算梯度并反向传播,缺点是当memory比较大时,计算量比较大。
- hard Attention:仅一个或者几个相关的记忆被计算,优点是计算量小,缺点是非凸,无法使用反向传播进行计算,所以一般结合强化学习进行优化,比较复杂。
上面两种都有各自的优缺点,所以本文在此基础上提出了基于MIPS的Hierarchical Memory Networks,可以理解为介于两者之间的方法,一方面使用分层结构进行存储和寻址,相比soft Attention速度更快,而且仍然可以进行端到端的反向传播进行训练,比hard Attention简单。
此外,本文主要是为了解决论文“large-scale simple Question Answering with Memory Networks”,该paper中使用关键词匹配的方法获得一个问题的相关记忆子集,这是一种启发式的方法,相对而言不是这么智能,所以本文提出的方法就是为了解决这个问题,想要一种自动、端到端、快速的方法来寻找query相关的记忆子集并求其相关性得分。 说了这么多,那么我们接下来结合“clustering is efficient approximate maximum inner product search”这篇文章来看一下分层的MIPS(maximum inner product search)的方法。为了加速计算过程,通常有三种结构被用于组织数据:
- Hashing-based:不依赖于具体数据。将memorys分成多个bins,然后只返回与query最相关的几个bins进行MIPS
- Tree-based:依赖于数据。将memory保存在叶子节点上。这里有很多方案,在github上面也可以找到相应的实现方案。
- ball tree:java实现//github.com/saulvargas/BallTreespython实现://github.com/gamboviol/miptree
- cone tree:python实现://github.com/ZexinYan/MIP-Search
- clustering-based:将memory分成多个相关的簇,并返回与query最相关的几个簇然后执行MIPS。C++实现://github.com/walkowiak/k-means-mips(也就是本文方法)
MIPS
K-MIPS问题的数学描述:给定一个查询q和一个数据集x,选择出最相关的K个数据即可。其复杂度与x的大小成线性相关。可以表述为:
为了解决上面的问题,我们可以使用最近邻或者最大相似度搜索方法,但是上式中内积既不满足三角不等式,也不满足相似度函数的概念,所以没办法直接使用,我们首先要将K-MIPS转化为K-MCSS(maximum cosine similarity search)问题。K-MCSS问题表述如下所示:
通过上面两个公式的定义我们可以看出,当x的模相等时,MIPS就等价于MCCS,所以我们要做的就是转化x的模。所以使用P和Q两个函数分别对x和q进行映射,映射之后MIPS就转化为了MCCS:
接下来就是将数据分簇,按照其方向的相关度进行分。而分层是为了进一步加快速度和缩小簇的大小。可以参考下图:
总结一下起流程就是,将memory使用分层聚类的方法进行存储和排列,然后输入一个query时,先返回与q最相关的一个或者几个聚类,然后在这个自己上进行MIPS搜索,得到最相关的K个memory及其得分。但是该方法仍然存在两个最大的缺点和局限:
- 但是在刚开始训练的时候,很可能返回的几个聚类中并不包含目标答案,为了避免这个问题,使用超监督的方法,以确保所有的正确答案均在返回的几个聚类中。
- 训练过程中memory向量需要保持不变==也就是静态记忆。因为如果memory实时变化的话,MIPS搜索的效果会大幅度下降,导致无法搜到正确的相关性得分。看到这里时,其实我是懵比的,如果memory不变的话,我们怎么进行初始化呢??随机吗,这效果怎么保证呢,然后看了作者的实验设置才发现,其使用别人模型跑出来的memory作为初始值。所以这应该也是一个很大的缺点。
所以整体来讲,本篇论文所提出的模型还需要一段时间的发展和完善才能取得比较好的效果,目前来讲可能只是一个简单的版本。效果上来讲的话,也只是起到速度上的提升,而准确度并没有办法改善。
3 Hierarchical Memory Networks for Answer Selection on Unknown Words
这篇论文是中科院自动化研究所(CASIA)在 9 月份发表的一篇论文,收录于 COLING2016。该论文基于 Memmory Network 做了一些改进,使得模型在特定的 QA 任务中能更好地从 memory 中选择答案,并且能一定程度上处理低频词甚至未登录词(unknown words)。论文的数据集以及模型实现已经在 Github 上开源,如果对论文细节没有太多兴趣,可以直接去 项目地址 了解项目详情。
论文使用的数据集如下表所示
数据集包含机票预订和酒店预订两个领域,而且包含中文的数据集哦,这点很赞,虽然数据量看起来并不是很多。截取中文的机票预订数据中的片段如下:
1 下午 好 , 我 是 机票 预订 服务 代理 , 需要 什么 服务 ?
2 我要 预订 一张 机票 。
3 请问 先生 您 从 哪里 起飞 ?
4 由 BGI 起飞 的 飞机 。
5 去 到 哪里 ?
6 到 印第安纳 去 。
7 电话 号 ?
8 13228762221 , 这 是 我 的 号码
9 时间 是 ?
10 2015年09月26日22点 之前 。
11 先生 , 乘客 的 身份证 是 ?
12 我 的 身份证号 是 110100195352319154 。
13 麻烦 说 下 您 的 名字 ? 谢谢 先生 。
14 好 的 , 名字 是 袁磊 。
15 先生 , 我们 已经 成功 为 您 预订 。
16 这么 快 , 非常 感谢您
17 订票 人 的 姓名 叫 什么 ? 袁磊 16
18 出发 城市 是 哪里 ? BGI 16
19 到达 城市 是 哪里 ? 印第安纳 16
20 出发 时间 是 什么 时候 ? 2015年09月26日22点 16
21 证件号码 是 多少 ? 110100195352319154 16
22 联系电话 是 多少 ? 13228762221 16
数据集的情况似乎有点像多轮对话,但并不完全是,如上 22 轮对话,其中前 16 轮是客服和客户之间的对话,这段内容被作为 history 输入到模型中储存为 memory,而 17-22 则是问题和对应的答案,每个问题的答案都是一个单独的词,是从 memory 中挑选出来的。所以从数据集上来看,本文的方法适用于一些像机票预订、酒店预订这种流程比较明确的业务。
像这种数据集,如果要我做我会怎么做呢?粗暴点的思路是将 history 和 question 各自 encode,然后将两者一起用于计算来去预测输出,事实上之前不少 QA 方面的工作都是这种思路。论文开头就批评这种做法
the memory of these methods, such as Long Short-Term Memory(LSTM) (Hochreiter and Schmidhuber, 1997) and Gated Recurrent Unit (GRU) (Cho et al., 2014) compressing all the external sentences into a fixed-length vector, is typically too small to accurately rememberfacts from the past, and may lose important details for response generation
这个也是当前在 sentence representation 讨论得比较多的话题吧,将句子直接 encode 成一个固定长度的向量,是会丢失一些细节的。不过我觉得还是看应用场景,如果是那种一问一答且目的性不是非常强的 QA 场景,encoder-decoder 的框架问题不大,语义漂移(如万能回复)的问题可以在前期进行意图识别、情感分析来得到额外的特征输入到模型里。但像本文的这种数据集就不是简单的一问一答,而是先有了一部分历史信息,然后给定问题从历史信息里寻找答案,有点类似英语的阅读理解题目 —— 因此 PaperWeekly 在 教机器学习阅读 中介绍了《End-to-End Memory Networks》这一篇作为本篇论文基础的论文。
对于类似本文的 QA 任务,早先的一些相关工作也是可以用上的,比如 Sukhbaatar 提出的端到端的 Memory Networks,文中记为「MemNN」。但是 MemNN 的问题在于它单纯在句子级别进行 “推理”,具体一点是只使用了 sentence level 的 attention 机制,见之前写的笔记: End-to-End Memory Networks。如果能进一步地在词级别进行分析,结果应该会更好一点。事实上也有人这么做了,2015 年俞扬等人的《Empirical study on deep learningmodels for question answering》论文中就提出了一种 “Search-Response” 结构的模型,先使用 MemNN 从 history 中挑选出相关的句子(supporting sentences),这一步称为 “Search”;然后用 NTM 或者 NMT(Neural Machine Translation) 来从这些 supporting sentences 中生成答案,这一步称为 “Response”。在 “Search-Response” 结构中,Search 和 Response 两个步骤是分别独立训练的,也就是说这其实是一个 pipeline 的方法。
所以本文的基本思想是: 结合 MemNN 和 “Search-Response” 的思想,得到一个端到端的系统。本文的模型结构如下图所示:
图中左侧是模型的整体结构,右边的两个小图是左图中两个模块的细节图示。整个模型大体上可以划分为四个部分,分别是:
-
sentence level memory and reasoning
这部分将 history 信息转换成内部的 memory,并在 此基础上计算结果,同 MemNN,上图中右下块是这部分的图示,要注意的是这里为了简化画成了类似 RNN 的结构图,但并不是说 \(X\) 中的句子依次输入这个模型,然后更新自连接的 \(u_{r}{(S)}\),这里的自连接只是表示多层结构(文中使用的层数为 3),而这种多层结构和 RNN 的结构有共同之处。
在这里,history 也就是 \(X\) 中的每个句子 \(x_i\) 和 question 也就是 q 都要表示成一个向量,使用的是《End-to-End Memory Networks》中的 position encoding 方法,即将句子中每个词的 embedding 加权求和,而这个权值和词在句子中的次序有关。
总之这部分跟《End-to-End Memory Networks》中的内容基本一样,不赘述,详见 MemNN 的笔记。
-
k-max pooling
这部分连接 1 和 3,利用 1 输出的 internel state 和 question 一起挑选出 history 中和 question 最相关的 k 个句子。
所谓的 internel state,就是图中的 \(\alpha^{(S)}\)
\[\alpha^{(S)}=softmax(M^{T}u_{1}^{(S)})
\]上式中 \(M\) 为 sentence level memory,\(u_{1}\)为问题 q 的 representation。
-
word level memory and attention: 使用 2 得到的 k 个句子,进行 word level 的 attention 来得到结果
这部分使用 BiGRU 来得到 attention
\[M^{(W)} = \{m_{t}\}_{t=(1,2,…)}
\\
m_{t}=\overrightarrow{h_{t}}+\overleftarrow{h_{t}}\\
\alpha^{(W)}=softmax(v^{T}\tanh(Wu_{R}^{(S)}+U\hat{m}_{t}))
\]这里的 \(\alpha^{(W)}\)就是 word level 得到的结果,但是这个结果是在 k 个句子中的词上的概率分布,没法直接用于第 4 步的计算,因此要做一次转换,将\(\alpha^{(W)}\)扩充为长度为 V 的向量,V 是词典的大小,方法是用 0 填充。
-
output: 综合 1 和 3 的输出来计算最后的结果
第一步得到的输出记为 \(p^{(S)}\) ,第三步得到的输出记为 \(p^{(W)}\),将这两者直接相加作为最后的输出
\[p = p^{(S)}+p^{(W)}
\]
如上所述,因为在 sentence level memory network 的基础上加上了 word level memory,作者将这个模型称为「Hierarchical Memmory Networks」,这是一个能够进行端到端训练、能在更细粒度的语言成分上进行”推理”的 QA 模型。
下图是 HMN 和其他模型在给定的数据集上的对比结果
以及 HMN 模型使用不同的 word level encoder 时的效果对比
下面的图显示了模型回答一个问题时的过程
- 表格第一列是 history,这些内容将会被 encode 后储存到 sentence level memory 中
- 需要回答的问题是: When does the client depart,正确答案是 history 中第 14 条中的日期
- 表格第二列是 sentense level reasoning 的过程,其中的值是每一个 reasoning 层的 internel state 也就是 u(S)rur(S),可以看到进行三次 reasoning 后正确的 supporting sentence 也就是第 14 条的权重已经非常的高了
- 第三列是 k-max pooling,这里的 k 取值为 4,得到的就是 8、10、13、14 这四个候选的句子
- 第四列是 word level 部分,使用 attention 来得到每个候选句子中的词作为答案的概率,这里概率最大的就是第 14 条句子中的日期
以上就是本篇论文的主要内容,至于开头作者提到的未登录词问题的处理,作者就是指着上面的图说:你看, 10/13/2018 这样的词也被找出来了!总之,作者没有提出一种对未登录词的解决办法,我猜他的意思是,在构建 vocabulary 的时候,不要根据词频去除低词频的词,而是照单全收喂给模型,而这个模型是能够将这种词频非常低的词正确地找出来作为答案的。
4 Gated End-to-End Memory Networks
今天要介绍的论文“gated end-to-end memory networks”时16年10月份发布的,他是在End-To-End Memory Networks这篇论文的基础上做了一些修改。因为End-To-End Memory Networks在multi-fact QA、 positional reasoning、 dialog等领域的效果还不是很好,所以本文参考CV领域中HighWay Networks和Residual Networks涉及到的shortcut connections,引入Gated机制,以实现对memory的正则化,从而让模型可以动态的修改memory。 因为End-To-End Memory Networks已经很熟悉了,所以我们先来介绍一下Highway Networks的想法,其主要是在网络输出下一层之前引入了一个transform gate \(T\)和一个carry Gated \(C\),以让网络学习什么、多少信息应该被传到下一层。我们假设本层网络的输出为:\(y=H(x)\),那么就加入下面的映射函数:
往往我们会选择C = 1-T,所以上面的公式可以转化为:
而残差网络则可以视为是Highway网络的一种特例,因为其直接把T和C都当做I,所以就相当于\(y=H(x) + x\)。但是这里背后的原理我还没来得及搞明白,为什么这样就可以让更深的网络很容易就训练成功,等有时间再看看相关的论文学习下。 然后我们来看一下如何将其融入到End-To-End Memory Networks中,由于其每个hop的功能都可以视为\(u’=H(u)\),所以对应到上面的公式,\(u\)就相当于输入\(x\),\(o\)就相当于输出y,所以代入上式得:
也就是修改一下原来模型中输出层的公式即可。然后参数W和b有全局和每个hop独立两种方式,后面实验结果证明,每个hop保持独立效果会比较好。论文的创新点倒不是很大,只不过是将两篇论文结合一下,但是看有实验效果好像还有挺大的提升。最终的模型架构图如下所示:
实验结果: 本文所提出的模型不仅仅在bAbI数据集上取得了很好的效果,而且在dialog bAbI对话数据集上也取得了很好的效果。这个数据集应该会在后面的文章中进行介绍,这里就不赘述了。这里也贴上两张实验结果的图:
第二张图揭示得是MemNN与本文提出模型各个hop对每个句子的权重计算,可以看出本文的模型更加集中在最重要的那个句子上面,而MemNN则比较分散,也说明了本文模型效果更好。
参考
TRACKING THE WORLD STATE WITH RECURRENT ENTITY NETWORKS
Hierarchical Memory Networks
Hierarchical Memory Networks for Answer Selection on Unknown Words
gated end-to-end memory networks