小样本场景下的多跳推理及其可解释性(MetaKGR、DacKGR、BIMR)
这几篇论文是 TransC 的作者 Lv Xin 近几年在知识推理方面的研究工作,因为找 TransC 的代码,顺腾摸瓜找到了这几篇,正好知识推理是我刚回所就想做的方向,因为种种原因没有选择,现在有机会了解一下了。作者似乎对 EMNLP 情有独钟,TransC 发表在 EMNLP 2018,MetaKGR 发表在 EMNLP 2019,DacKGR 发表在 EMNLP 2020,BIMR 还没有公开发表,不过大概率也是投今年的 EMNLP 吧。
MetaKGR
paper: Adapting Meta Knowledge Graph Information for Multi-Hop Reasoning over Few-Shot Relations
论文
本文作者是清华大学刘知远老师团队的 Lv Xin 发表于 EMNLP 2019 上的文章,提出了 MetaKGR 模型,在小样本场景下进行多跳推理,使用强化学习的 MAML 方法,在常规数量关系上初始化得到参数,然后在具体的 few-shot 关系上进行快速适应,并进行多跳推理。
问题提出
可以进行多跳推理的模型有两类,一类是通用的 KGE 模型,另一类是多跳推理模型,前者虽然可以计算出推理的结果,但无法给出合理的可解释性(如推理路径),后者在小样本场景下表现差。本文提出的模型 MetaKGR,将带有同一关系的三元组查询视为一个任务,采用强化学习训练 agent 搜索目标实体和推理路径。
MAML 元学习方法: 从高频关系任务中捕捉不同的任务中包含的共同的元信息(meta information),在 MetaKGR 中,就是在 normal relation 上初始化参数,然后在具体的低频关系上进行快速适应(微调训练出新的模型)。
few-shot 关系的定义: 如果包含某个关系的三元组的数量小于定义的阈值 K,则该关系被视为小样本关系(few-shot relaiton),否则是 normal relation。
特定关系学习
对于关系集中的每一个关系(包括 normal 关系和 few-shot 关系),学习一个多跳推理的 agent,用于推理路径、搜索目标实体。(对强化学习没什么了解,暂时认为 agent 可以视为一个虚拟的主题,可以在 KG 的图上随机游走)
- 马尔可夫决策过程(Markov Decision Process,MDP)
MDP: 将知识谱图视为有向图,关系和实体视为节点和边,给定查询和答案 \((e_s,r_q,e_o)\),期望 agent 从源实体 \(e_s\) 出发,经过几条边,到达目标实体 \(e_o\)。
MDP 的其他定义概念:
State: 第 t 个时间步的状态定义为 \(s_t=(r_q,e_s,\hat{e}_t)\),括号正分别为查询关系、源实体、当前到达的实体。
Actions: 一个动作是即将到达的边(关系)和实体,t 时刻的动作空间定义为当前实体的所有出边和下一实体:\(A_t=\{(r_{t+1},\hat{e}_{t+1})|(\hat{e}_t,r_{t+1},\hat{e}_{t+1}) \in G \}\)
Transition: 如果 agent 选择了一个动作,状态将会发生改变,状态转移的函数定义为 \(\delta(s_t,A_t)=(r_q,e_s,\hat{e}_{t+1})\),转移函数的输出为 t+1 时刻的状态。给定固定的时间步 T,最终到达的状态为 \(s_T=(r_q,e_s,\hat{e}_T)\)
Rewards: 如果 agent 最终到达了正确的实体,即 \(\hat{e}_T=e_o\),则得到奖赏 \(R(s_T|r_q,e_s)=1\),否则得到的奖赏是由基于 embedding 的函数值—— \(f(e_s,r_q,\hat{e}_T)\),\(f\) 度量三元组 \((e_s,r_q,\hat{e}_t)\) 的概率。其实 \(f\) 就是三元组打分函数,在这里用于计算奖赏值。
- 策略网(Policy Network)
应用策略网解决马尔可夫决策过程,即决定每个状态选择哪个 action。\(A_t\) 中的每个动作具体表示为 \(a_t=[r_{t+1};\hat{e}_{t+1}]\)。
使用 LSTM 编码搜索路径:\(h_t=LSTM(h_{t-1},a_{t-1})\)。\(h_t\) 是历史路径的表示,LSTM 实现了一跳路径的编码。
动作空间 \(A_t\) 中所有动作的概率分布为:\(\pi_{\theta}(a_t|s_t)=softmax(A_t(W_2ReLU(W_1[\hat{e}_t;h_t;r_q])))\)
- 损失函数
给定关系 r 和带有该关系的三元组集合 D,特定关系的策略网上的整体 loss 为:
元学习(Meta-Learning)
元学习的目的是学习到在 common task 上初始化好的参数 \(\theta^*\)(Figure 2中)。当适应到新任务 \(T_r\) 时,模型的参数变为 \(\theta_r^{'}\)。
对单个 r 的梯度下降步骤:
\(D_r\) 是从属于 \(T_r\) 的三元组中随机采样得到的训练集,同样采样得到 \(D_Q\) 用于评价参数 \(\theta^{'}_r\)。
一个 batch 中多个任务共同做梯度下降:
实验
进行了链接预测和鲁棒性分析实验。
- 链接预测
用了两个数据集 FB15K-237 和 NELL-995 进行链接预测,分别设定 K 为 137 和 114 来决定两个数据集中的关系是否是 few-shot relation。四个多跳推理模型作为 baseline 进行对比。个人认为 baseline 应该再加上一个同样用多跳路径作推理的 PTransE。
- 鲁棒性分析
在 FB15K-237 上调整了 K 观察实验结果的变化。
与 MultiHop 的对比结果表明,Meta-KGR 对决定关系是否是小样本的阈值 K 不敏感,因此模型更鲁棒。
这篇文章的实验做得比较少,而且不够直观,会令读者有一些疑问,比如多跳关系训练出来有几跳?即如何证明做的是多跳推理?如果能用 case study 直观地展示推理效果就好了。
代码
该作者的每一篇研究都给出了代码,该模型的 https://github.com/THU-KEG/MetaKGR 。尝试在服务器上运行,但是因为环境、路径、包等一些小问题也很多 bug,没能一次跑通(尽管我知道那是小概率事件)。因为忙着记录下面的两个模型,代码就先不看了,我是很想并且打算要做推理方向的,等把 KGE 的基础模型梳理完之后再来看这几个模型,想 idea。
后记:五一回来尝试运行了一下,即使是在 2080ti 上,也太慢了,预训练 KGE 还好,一个白天能跑完,第二步 --few-shot 的时候,一晚上才训了 10 个 epoch,太慢了,大概率要放弃这个方向了。
小结: 强化学习思想用于 KG 知识推理,是我第一次接触这方面的内容。看文章综述,真正结合 KGE 做多跳推理的工作应该不是很多,后面学习完了神经网络 KGE 模型,再看有没有可以结合可做的点。
DacKGR
paper: Dynamic Anticipation and Completion for Multi-Hop Reasoning over Sparse Knowledge Graph
论文
这篇文章是作者发表在 EMNLP 2020 上的工作,主要思想还是用强化学习做稀疏 KG (这里没有强调是小样本关系)的多跳推理,包括动态预测和动态补全两步。
问题提出及形式化定义
该文针对稀疏知识图谱做多跳推理。可以做多跳推理的模型主要有两类:KGE 模型和专门的多跳推理模型。但 KGE 做补全是计算出来的结果,不能给出推理路径之类的解释。而专门的多跳推理模型作用于稀疏知识图谱时面临两个问题:稀疏 KG 包含的信息少,路径选择困难;路径的缺乏使得预测目标实体变得困难。
因此,文章提出了 DacKGR,包括动态预测(Dynamic Anticipation)和动态补全(Dynamic Completion)两部分,前一部分应用 KGE 模型预测尾实体信息用于 agent 选择正确的 action;后一部分负责在推理过程中动态地向 KG 中添加额外的边(关系),缓解 KG 的稀疏性问题。
模型
强化学习框架及策略网
这两部分的介绍和前面一篇论文中的介绍是相同的,简单贴一下:
- 强化学习相关概念
- State:某时刻的状态
- Action:状态转移的动作,给出一个关系和一个实体;状态 \(s_t\) 的所有动作组成其动作空间
- Transition:从当前状态转移到下一状态
- Reward:若到达正确实体,奖励为1,否则为三元组打分函数给出的值
- 策略网
策略网用于指导 agent 选择正确的动作。
第 t 步的某个动作表示为某个关系和实体的向量拼接:\(a_t=[r;e]\)
LSTM 对路径信息进行编码,生成和存储历史路径信息:\(h_t=LSTM(h_{t-1},a_{t-1})\)
第 t 个状态表示为 查询关系、当前实体、历史信息 三者的拼接:\(s_t=[r_q;e_t;h_t]\)
策略网定义为动作空间 \(A_t\) 中的所有动作的概率分布:\(\pi_\theta(a_t|s_t)=\sigma(A_t(W_1ReLU(W_2s_t)))\)
动态预测(Dynamic Anticipation)
这部分说白了就是用 KGE 模型进行普通的链接预测。先用 KGE 模型计算出所有实体作为尾实体的概率得分,然后添加到 \(s_t\) 中:\(s_t=[e_p;r_q;e_t;h_t]\)。这部分给出的 \(e_p\) 信息只为 agent 提供一个路径方向选择的参考,并不是必须的。
\(e_p\) 为 KGE 模型给出的预测信息,有三种获取方式:
- Sample 方式:基于所有实体的三元组打分的概率分布采样一个实体
- Top-one 方式:选 P 中概率得分最高的实体表示
- Average 方式:所有实体表示的加权平均作为 \(e_p\)
实验表明,sample 方式最好。
动态补全(Dynamic Completion)
这部分是模型的重点,用于拓展动作空间。从添加动作的候选集合 \(C_t\) 中选出高概率的动作添加到 KG。
给定状态 \(S_t\) 条件下的某个动作的概率定义为:\(p((r,e)|s_t)=p(r|s_t)p(e|r,s_t)\)
这里用近似剪枝的方法计算 \(p((r,e)|s_t)\):先选定给定状态下概率最高的关系,然后选给定状态和关系下概率最高的实体。
使用关系的 attention 值作为 \(p(r|s_t)\):\(w=Softmax(MLP(s_t)\cdot[r_1,...,r_{|R|}])\)
然后根据 attention 的值选出前 x 个关系,组成集合 \(R_{add}=\{r^1,r^2,...,r^x\}\)
对于选出的这些关系,用 KGE 模型计算所有实体作为尾实体的概率得分 \(p(e|r^i,s_t)\),并选择前 k 个得分最高的。
因为额外添加的动作数量为:\(N_{add}=min(\lceil \alpha N \rceil,M)\),
所以关系选择的个数 x 为 \(x=\lcel N_{add}/k rcel\)。
每个状态下得到的 additional 动作空间会被添加到原有动作空间:\(A_t=A_t+A_t^{add}\)
策略优化(目标函数)
模型使用 REINFORCE 算法训练代理、优化策略网的参数。我简单将这种训练方法理解为和梯度下降相反的训练方法。梯度下降是最小化 loss,这里是最大化奖赏:
目标函数没有像前一篇论文那样加负号,因此参数优化时是梯度上升:
实验
- 链接预测
在 FB15K-237 的三个子数据集和 NELL23K、WD-singer 上进行了链接预测实验。
(1)DacKGR 在越稀疏的数据集上,效果提升越明显。
(2)多跳推理的模型和本文提出的 DacKGR 很多都比不过 KGE 模型,但论文中说只把 KGE 模型作为参考,它们属于不同的类型,不具可解释性。
(3)DA模块中 \(e_p\) 的三种获得方式中,sample strategy 的效果最好。
- 消融实验
分别去掉 DA 和 DC 模块观察实验效果,两个模块都可以起到一定的效果,DC 的效果比 DA 的效果好一丢丢,文章的解释是 DA 用于 agent 做出正确的选择,基本不改善 KG 的稀疏性。
DA 和 DC 的关系:DA 只是为 agent 提供动作选择的方向,DC 用 DA 的结果做多跳推理、补全图谱。
- 验证分析
这部分用于探究额外添加的动作是否被 agent 选择。图中的曲线代表各数据集上的动态补全(DC)的正确率,上面一行是关于训练 epoch,下面一行是关于添加动作的数量占比 \(\alpha\)。
对于第一行,在 10% 的子数据集上,正确率先降后升,其他数据集上只下降,下降是因为 additional actions 引入了噪声,在 10% 子数据集上先降后升是因为 agent 识别出了噪声部分,并减少了对 additional actions 的选择比率。证明了模型在稀疏 KG 上表现好。
对于第二行,DC 正确率随着 \(\alpha\) 的增大而增长(FB15K-237-50%),符合直观预期。而因为 50% 的子数据集不太稀疏,添加额外动作对其正确率影响不大。
- case study
对于三元组查询给出了三条推理路径,加粗的 London 是添加的 additional action,该 action 形成的路径对于推理有帮助。第三条是 KG 中已有的路径。
代码
模型代码: https://github.com/THU-KEG/DacKGR
后面做的时候再看代码吧=.=。
小结: 这篇文章比前一篇感觉详实了很多,给出了 case study 便于直观理解。模型效果虽然没有 KGE 的效果好,并且在探究 DC 的正确率时,正确率反而随着 epoch 的增加而下降,引出一个问题:既然添加 additional actions 引入的是噪声,那么添加额外动作的意义是什么?尽管如此,论文对实验结果都给出了合理的解释,令我感受到,实验结果好坏并不重要,只要能够给出合理的解释即可。
BIMR
paper: Is Multi-Hop Reasoning Really Explainable? Towards Benchmarking Reasoning Interpretability
论文
这篇论文是今年新出的,还未公开发表,但根据作者历年的习惯,八成是要投今年的 EMNLP。文章的主要工作是提出了一个 benchmark —— BIMR (Benchmark to detect the Interpretability of Multi-hop Reasoning),用于对多跳推理的效果进行评估,并用该 benchmark 对 9 个 baseline 模型进行了测试。
问题提出
很多多跳推理模型给出的路径并不合理,如上图下面的例子,尽管模型预测出了正确的尾实体,但是给出的推理路径完全不合理,目前对多跳推理效果评价的方法只有 case study,因此文章提出了量化的评价指标 BIMR,用于评价多跳路径的可解释性。
评价框架
BIMR 包括三个指标:
- Path Recall (PR)
PR 代表在测试集中,可通过一条或多条路径连接的三元组所占的比例。\(Cnt(h,r,t)\) 是一个指示函数,用于指示模型是否可以找到一条从 \(h\) 到达 \(t\) 的路径,有的话函数值为 1,否则为 0。
- Local Interpretability
局部可解释性用于评价模型发现的路径的合理性。p 代表模型发现的从 h 到 t 的最佳路径(最高得分的路径),\(S(p)\) 是该路径的可解释性得分。
- Global Interpretability
全局可解释性是前两者的乘积,代表模型整体的可解释性程度。PR 指示模型发现的路径的数量,GI 代表模型发现路径的可解释性程度,二者的乘积代表模型整体的效果。
路径可解释性得分 \(S(p)\) 的计算
BIMR 使用基于 wikipedia 构建的 WD15K 数据集(包含 15817 个实体、182个关系,共 176524 个三元组),采用广度优先(BFS)进行路径搜索,设置最大跳数为 3,去重后,大约可得到 1600 万条路径组成路径集合 \(P\),对这些路径手动标注得分工作量巨大,因此文章提出了一种估计优化的方法来计算这些路径的可解释性得分。
具体为:对于路径 \(p \in P\),用该路劲对应的规则 \(f\) 的可解释性得分作为该路径的可解释性得分:\(S(p) \approx S(f)\)
对于一条路径:
将其转化到它对应的规则:
由于规则是“entity-independent”的,因此规则集 \(F\) 的规模(96019)远远小于路径集 \(P\)(1600 万),因此标注工作量会大大减少。此外,还使用了一些剪枝优化规则来降低标注成本。(后面人工标注和挖掘规则的两小节没看太懂,也不是很重要,先过了=.=)
实验
在 WD15K 数据集上对 9 个模型进行了链接预测和可解释性评估的实验:
从实验结果看出,基于规则的推理模型普遍优于多跳推理模型,其中 AnyBURL 效果最好。
此外,还对 9 个模型在人工标注和挖掘规则的不同 benchmarks 上进行了对比实验。
代码
代码给出了传送门,但还没有放内容:https://github.com/THU-KEG/BIMR
小结: 针对多跳推理没有量化的评价指标的问题,提出了衡量多跳路径可解释性得分的 BIMR,包括三个指标:PR、LI 和 GI,弥补了多跳推理效果没有量化评价指标的空白,算是一个从 0 到 1 的开创性工作,个人认为比前两篇贡献更大,中今年的 EMNLP 应该是没有问题的。
整体小结: 过了一个五一,前两篇看的全忘了=.=,只还记得是用强化学习做小样本关系场景和稀疏 KG 场景的多跳知识推理,最后一篇提出衡量多跳路径可靠性的评价指标 BIMR,over~
最近的两点感受(写于五一前):
- 最近本打算这几篇论文一起看完一起写笔记的,但是前两篇论文涉及的强化学习的知识我之前没有接触过,所以看得比较慢,又有些事情没有把全部心思放在学习上,因此没有看得很明白透彻,期望全部看完一起理解是不现实的。吸取到了一点教训就是:看论文必须要全神贯注、一气呵成,走马观花的话就会陷入“理解不透彻、重看浪费时间、不看等于没看”的尴尬境地,因此做事情一定要安排好固定的时间块,在该时间块内把该做的事情做完。看论文时,记住,“快就是慢,慢就是快”。
- 第二点就是代码,正好前两篇论文的代码是用 pytorch 实现的,因此想尝试运行,但是会遇到很多小的类似文件路径、环境设置这样的问题,解决这些无关痛痒的 bug 可能大半天就下去了,单纯看代码又没有太深的感觉,所以这一直是令我比较头疼的一个问题,花了很多时间配环境、debug,这还不算学习代码的时间,如果不是真的决定要做这个点的话,时间成本有点大,我的代码能力又比较差,确实应该多看代码、多实践,所以,这样吧,对于一篇有代码的论文,可以不尝试运行,看一下代码,在论文笔记中把它的代码思路写出来吧,学习下有什么可以借鉴的实现方式,如果确定要做这个点,再去配环境运行和看代码实现细节吧。