知识库问答KB-QA——深度学习(3)(记忆网络)

什么是记忆网络

记忆网络由Facebook AI Research的Jason Weston等人提出,其论文发表在2015年ICRL会议。对于很多问题(如自动问答、对话系统等),我们都希望模型能够像我们人一样具有记忆机制,能够记住一些信息(上下文、知识库等),为此发明了很多记忆模型。一个广为人知的记忆模型就是长短时记忆网络(Long Short-Term Memory, LSTM)。然而它的记忆实质上是一种内在(Internal)表达,只能记住在使用时所输入的一些历史信息。它就像计算机的内存一样,能够存储一些使用时的历史输入信息(把所有的历史输入信息都压缩到一个低维空间上,这样也会损失很多信息),一旦使用完毕,记忆就会被抹去,记忆量也非常有限。

我们想要找到一种外部(External)表达的记忆,就像计算机的硬盘一样,能够长期存取大量的记忆信息。在使用时再去记忆库中读取相关的记忆。对于KB-QA问题,我们也希望将知识库里的知识直接存储在我们的模型中。近年来,人们在这方面的研究作出了不懈努力,发明了一些能够提供外部记忆的模型,其中有两个最著名的模型,一个是由Google DeepMind团队提出的神经图灵机(Neural Tuning Machine),而另一个就是今天要讲的记忆网络。

记忆网络其实是一种框架结构,它里面的每一个模块(也称组件,Component)都可以根据应用套用不同的模型,也可以根据应用的需要增加其他的模块。总体来说它可以分为以下5个模块:

  • 输入模块I(Input)将外部输入转化为内部表达。我们可以把输入模块想象成人类的感知器官,接受外部的原始输入并将其转化为能够被大脑处理的生物信号。具体来说,输入模块用于将外部的输入(如自然语言句子、图片等) x x x 转化为内在的分布式表达 I ( x ) I(x) I(x)。输入模块可以根据应用的需要选用不同的模型,诸如CNN、LSTM、bag-of-words等等。
  • 记忆模块M(Memory)用于存储记忆。每一条记忆都是一个分布式表达向量 m i m_{i} mi,每一个记忆有一个索引地址号 i i i,所有记忆组成了我们的记忆模块。我们的记忆模块就像是计算机中的硬盘一样,存储着一条条的信息,每一个信息都有一个物理地址。我们可以记忆模块进行记忆的读取,修改,删除,也可以插入新的记忆信息。
  • 泛化模块G(Generalization)根据外部输入的内在表达 I ( x ) I(x) I(x) 去更新记忆 G ( m i , I ( x ) , m ) G\left(m_{i}, I(x), \mathbf{m}\right) G(mi,I(x),m)。我们可以根据新的输入对记忆模块中的每一个记忆都进行更新并增加新的记忆,也可以仅对部分相关记忆作针对性更新。最简单的方式是,直接将输入存储在记忆模块中而不对其他的记忆进行修改,即 m H ( x ) = I ( x ) m_{H(x)}=I(x) mH(x)=I(x)。这里 H ( x ) H(x) H(x) 是一个为输入选择记忆槽(为输入确定记忆的索引地址)的函数,在记忆存储满的时候,也可根据 H ( x ) H(x) H(x) 函数对记忆进行替换。更复杂一点,我们也可以引入一些遗忘机制等等。
  • 输出模块O(Output)根据外部输入的内在表达 I(x)去选择记忆模块中与之最相关的记忆。 该记忆也称为支撑记忆(Support Memory),即 o = O ( I ( x ) , m ) o=O(I(x), \mathbf{m}) o=O(I(x),m)。这个 选择 的方式有很多,最简单的方法就是将 I ( x ) I(x) I(x) 和记忆向量 m i m_{i} mi 投影到同一个向量空间中,通过比较 相似度得分(cosine,点乘等)来选择最相似度得分最高的记忆作为输出。当然我们也可以根据应用的需要,选择多个记忆作为输出。选择多个记忆的方式也有很多种,最简单的方法就是选择相似度得分最高的k个记忆作为输出,论文中作者提出了另一种方法,先选择得分最高的作为第一个输出 o 1 o_{1} o1,再选择与 I x I_{x} Ix 得分加上与 o 1 o_{1} o1 得分 最高的记忆作为第二个输出,以此类推(这种方法更像是在进行推理,先将输入作为推理的支点,选择与输入最相关的记忆作为第一条线索,再根据输入和第一条线索去确定下一条线索)。
  • 回答模块R(Response)根据输入的内在表达和输出模块提供的记忆,输出满足应用需要格式的结果。它就相当于encoder-decoder模型中的decoder部分,将 I x I_{x} Ix { m o 1 , … , m o k } \left\{m_{o_{1}}, \ldots, m_{o_{k}}\right\} {mo1,,mok} 作为输入,根据应用的需要使用不同的模型输出最终的结果(分类器、语言模型、RNN、CNN等)。

给定训练数据 输入输出对 ( x , r ) (x,r) (x,r) ,可以通过梯度下降算法优化margin-based ranking损失函数,去训练记忆网络中的所有参数。假设输出模块每次输出两条支撑记忆,损失函数如下:

∑ f ˉ ≠ m o 1 max ⁡ ( 0 , γ − s O ( x , m o 1 ) + s O ( x , f ˉ ) ) + ∑ f ˉ ′ ≠ m o 2 max ⁡ ( 0 , γ − s O ( [ x , m o 1 ] , m o 2 ] ) + s O ( [ x , m o 1 ] , f ˉ ′ ] ) ) + ∑ r ˉ ≠ r max ⁡ ( 0 , γ − s R ( [ x , m o 1 , m o 2 ] , r ) + s R ( [ x , m o 1 , m o 2 ] , r ˉ ] ) ) \begin{array}{c} \sum_{\bar{f} \neq \mathbf{m}_{o_{1}}} \max \left(0, \gamma-s_{O}\left(x, \mathbf{m}_{o_{1}}\right)+s_{O}(x, \bar{f})\right)+ \\ \left.\left.\sum_{\bar{f}^{\prime} \neq \mathbf{m}_{o_{2}}} \max \left(0, \gamma-s_{O}\left(\left[x, \mathbf{m}_{o_{1}}\right], \mathbf{m}_{o_{2}}\right]\right)+s_{O}\left(\left[x, \mathbf{m}_{o_{1}}\right], \bar{f}^{\prime}\right]\right)\right)+ \\ \left.\sum_{\bar{r} \neq r} \max \left(0, \gamma-s_{R}\left(\left[x, \mathbf{m}_{o_{1}}, \mathbf{m}_{o_{2}}\right], r\right)+s_{R}\left(\left[x, \mathbf{m}_{o_{1}}, \mathbf{m}_{o_{2}}\right], \bar{r}\right]\right)\right) \end{array} fˉ=mo1max(0,γsO(x,mo1)+sO(x,fˉ))+fˉ=mo2max(0,γsO([x,mo1],mo2])+sO([x,mo1],fˉ]))+rˉ=rmax(0,γsR([x,mo1,mo2],r)+sR([x,mo1,mo2],rˉ]))

其中 f ˉ , f ˉ ′ , r ˉ \bar{f}, \bar{f}^{\prime}, \bar{r} fˉ,fˉ,rˉ 是随机采样的一些负样本。需要注意的是,这里在构造损失函数的时候,需要提供输出模块输出正确记忆的标签(即上式的 m o 1 , m o 2 \mathbf{m}_{o_{1}}, \mathbf{m}_{o_{2}} mo1,mo2),即记忆的正样本。但是在一般情况下,我们的训练数据都只有 输入输出对 ,难以提供关于记忆的标签。针对这一问题,纽约大学和Facebook AI Research的Sukhbaatar等人提出了端到端学习(End-to-End)的记忆网络。
关于记忆网络还有很多的技巧(trick),我们可以通过哈希聚类的方法提高查找记忆的效率,通过单词的上下文来处理未见过的单词等。可以看出相比LSTM的内部记忆,记忆网络可以存储大量的外部记忆,并且它具有很强的扩展性

基于记忆网络的KB-QA

以Facebook AI Research的Bordes等人在2015年发表的论文Large-scale Simple Question Answering with Memory Networks为例,介绍如何将记忆网络应用于KB-QA。

此文初步尝试了将记忆网络应用于KB-QA中。作者认为现在的KB-QA对于解决只依赖一个知识三元组的简单问题(称为 Simple Question Answering)仍然有困难,为此作者构建了一个更大的简单问题数据集,称作SimpleQuestions。该数据集的每个问题都依据一个知识三元组知识,进行人工构建问题,数据集最终一共包含了108,442个问题-答案对,相比之前只含8000多个问题-答案对的benchmark数据集WebQuestion,其数据量大了很多。该数据集的部分数据如下图所示(下划线表示答案):

在这里插入图片描述
作者使用记忆网络,其整体思想是将知识库里的知识存储到记忆模块M中,问题经过输入模块I转化为分布式表达,输出模块O选择与问题最相关的支撑记忆(由于SimpleQustions的问题只依赖一个知识,所以只需要选择一条记忆),回答模块R将该记忆对应三元组的宾语作为最终答案输出。 最后,为了测试记忆网络的泛化能力,在模型训练完毕后,将Reverb中提取的三元组(Reverb的知识三元组是自然语言形式,如(“Obama”, “was also born in”, “August 1961”),知识三元组抽取自ClueWeb)作为新的知识,用泛化模块G将新知识存储到记忆模块中,在不经过re-training的情况下使用该记忆回答问题,测试模型的泛化性能。
具体来说,整体流程可以分为以下三步:

  1. 存储知识

首先我们要将知识库里的知识,存储到记忆网络中。作者使用Freebase的两个子集FB2M(含2M实体和5K实体关系)和FB5M(含5M实体和7K实体关系)分别作为知识库。使用输入模块I来处理数据。

由于一个问句可能有多个答案,并且对于一个问题输出模块O只选择一个支撑记忆,我们先对知识做两种预处理:

a. 将具有相同主语和实体关系的三元组进行合并(Group),这样每一条知识将包含k个不同的宾语,即 y = ( s , r , { o 1 , … , o k } ) y=\left(s, r,\left\{o_{1}, \ldots, o_{k}\right\}\right) y=(s,r,{o1,,ok})。合并的原因在于我们想用一条记忆回答具有多个答案的问题 (我们将合并前的知识三元组称为Atomic Facts,合并后的三元组称为Facts),合并后和合并前的知识库大小如下:

在这里插入图片描述
b.去除中间节点。有些知识中日期会链接两个实体以区分某一事实的时间范围,我们可以将中间节点(mediator node)去除转化成一个二阶关系,这样我们就把长度为2的路径压缩成了长度为1的路径,即压缩为一个三元组。这个操作使得WebQuestion里的能被单一关系回答的问题数量从65%上升到86%。
预处理完知识后,输入模块I对知识进行预处理并存储到记忆中。这里使用词袋模型bag-of-symbol的方法,用一个 N S N_{S} NS 维的multi-hot向量 f ( y ) f(y) f(y) 来表示每一条知识并作为记忆。 N S N_{S} NS 的大小为知识库实体和实体关系的大小之和,主语实体 s s s 和实体关系 r r r 对应向量维的值为1,宾语实体 o i o_{i} oi 对应维的值设为 1/k。

  1. 训练记忆网络

我们用问题-答案对来训练记忆网络。

首先用输入模块I来处理输入的自然语言问句 q q q ,使用n-gram词袋模型(bag-of-ngrams)方法,用一个 N V N_{V} NV 维的multi-hot向量 g q g_{q} gq 来表示每一个问句。 N V N_{V} NV的大小是字典大小,字典包含所有问题中出现的单词和所有知识库实体的自然语言别称(这个别称可能由多个单词构成,我们用1个n-gram来表示)。

对于输入 g q g_{q} gq输出模块O要在记忆中寻找一个与之最相关的支撑记忆。为了避免遍历整个记忆模块里的每一条知识,应先确定一个候选范围。确定方式如下,将问句中的所有n-gram与知识库实体别称进行匹配,以确定候选实体,将含有候选实体作为主语的知识作为我们的候选支撑记忆。将记忆和问题投影到一个低维分布式空间,通过cosine相似度作为得分函数,来寻找最相关的支撑记忆,即: S Q A ( q , y ) = cos ⁡ ( W V g ( q ) , W S f ( y ) ) S_{Q A}(q, y)=\cos \left(\mathbf{W}_{V} g(q), \mathbf{W}_{S} f(y)\right) SQA(q,y)=cos(WVg(q),WSf(y))。这里我们需要学习的参数就是两个权值矩阵 W V , W S W_{V},W_{S} WV,WS

和在 知识库问答KB-QA——向量建模 一文中提到的训练方法一样,我们构建margin-based ranking损失函数,也进行多任务的训练,通过多任务训练让语义相同的问题的分布式表达 W V ( q ) {W}_{V} (q) WV(q)相似。这里不再赘述。

需要注意的是,我们知道构建margin-based ranking损失函数需要提供支撑记忆的正样本和负样本,由于SimpleQuestions数据集的每个问题都有对应的知识标签,因此我们已经有支撑记忆的正确标签。但是对于WebQuestion数据集,我们没有正确的支撑记忆标签,作者通过类似之前寻找候选支撑记忆的方式去得到标签。

训练完毕后,作者在WebQuestion和SimpleQuestions上做了测试,在WebQuestion上取得了42.2的F1-Score,在SimpleQuestion上正确率63.9%。作者发现如果仅用WebQuestion来训练模型,那么在SimpleQuestion测试集上正确率只有46.6%,说明了WebQuestion数据集的数据量还是具有一定的局限性。

  1. 测试网络泛化能力。

使用泛化模块G来连接新的知识库Reverb到我们的记忆中,通过实体链接和实体别名匹配等方式,来匹配已有记忆中的实体和新知识库里的实体(这种方式只能匹配到新知识库中17%的实体)。新知识库中剩下的实体和所有的关系都用词袋模型表示,因此我们可以用一个 N V + N S N_{V}+N_{S} NV+NS 维的向量 h ( y ) h(y) h(y) 来表示新知识并将其存储到记忆中。同样的,输出模块在寻找支撑记忆时的相似度得分函数为 S R V B ( q , y ) = cos ⁡ ( W V g ( q ) , W V S h ( y ) ) S_{R V B}(q, y)=\cos \left(\mathbf{W}_{V} g(q), \mathbf{W}_{V S} h(y)\right) SRVB(q,y)=cos(WVg(q),WVSh(y)),其中矩阵 W V S {W}_{V S} WVS 直接由之前训练好的 W V , W S W_{V},W_{S} WV,WS 拼接(concatenate)而成。

将该新的知识库存储到记忆中,在不经过re-training的情况下用Reverb的一个测试集(含691个问题)进行测试,达到了67%的正确率,接近当时state-of-the-art的方法。

可以看出该方法使用了一个很基础版本的记忆网络来解决简单问题的KB-QA。本文使用的方法很简单,本质上和传统向量建模方法很接近。但是我们也可以看出,记忆网络这种结构具有的很强大的扩展性,它的每个模块都有很多改进的空间。总的来说,记忆网络是一种很适合进行KB-QA的深度学习框架,相信今后会有很多使用记忆网络进行KB-QA的优秀文章。

此外,个人认为使用更加复杂的记忆网络是未来深度学习解决KB-QA的一个很有前景的途径。记忆网络的框架给了我们很多的提升空间:引入更多的技巧,使用更合理的模型作为记忆网络的组件,在记忆选择中引入推理机制,注意力机制和遗忘机制,将多源的知识库存入记忆等等。

参考文献

揭开知识库问答KB-QA的面纱7·深度学习下篇(一)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值