Reasoning Through Memorization: Nearest Neighbor Knowledge Graph Embeddings论文阅读
研究问题
将基于记忆的方法与预训练语言模型相结合,以完成知识图谱补全任务
背景动机
- 传统模型在面对未曾识别的实体时表现出明显的局限性
- 相关研究重点转向探索与记忆增强神经网络相关的最新研究动态,并提出了一种创新性的解决方案:在现有的计算架构中引入专门的内存单元以提升数据存储能力
模型方法
通过预训练的语言模型建立实体知识库,并利用嵌入向量间的相似度来识别最接近的概念;随后将记忆搜索结果与语言模型的预测输出进行加权融合

Masked Entity Modeling

在每一个三元组查询\left(e_i, r_j, ?\right)及其对应的实体信息d的情况下,生成相应的查询语句。

接下来计算mask位置对应不同实体的词的概率:

最终的损失函数即为分类器损失函数:

Entity Vocabulary Expansion

这一步实际上是上一步的一个预处理步骤。由于预训练语言模型在编码阶段会对单个词进行分词处理,并将其分解为多个sub token单位。然而,在这种情况下其输出的token概率与实体之间无法实现完全对应关系。因此我们需要通过扩展语料库来实现这一目标。具体而言,在这种情况下我们需要引入一些特殊的tokens,并确保这些特殊tokens能够具有明确且一致的意义基础之上还需要完成以下相关的预训练任务
对于每个实体及其描述,获得以下查询语句:

预训练目标损失:

词表扩展相关代码
def get_entities(self, data_dir):
"""Gets all entities in the knowledge graph."""
with open(self.entity_path, 'r') as f:
lines = f.readlines()
entities = []
for line in lines:
entities.append(line.strip().split("\t")[0])
ent2token = {ent : f"[ENTITY_{i}]" for i, ent in enumerate(entities)}
return list(ent2token.values())
entity_list = self.processor.get_entities(args.data_dir)
num_added_tokens = self.tokenizer.add_special_tokens({'additional_special_tokens': entity_list})
代码解读
Knowledge Store

基于涵盖语义信息的实体描述内容以及涵盖结构信息的实体三元组两方面的分析来构建知识库
在实体描述部分采用的是Entity Vocabulary Expansion部分所学得的向量表达。

三元组部分就是把所有包含目标实体的三元组对应的嵌入加入库中

知识库中采用(k,v)对的形式组织实体与嵌入的关系结构,其中k由描述或三元组生成的嵌入表示,v则包含对应实体名称信息。该论文采用了开源库FAISS来进行高维空间检索任务。
记忆推理
基于三元组查询框架,在利用该方法推导出缺失实体对应的向量表示h_{[mask]}的情况下, 计算过程如下:

knn算法通过计算候选实体与目标实体之间的向量空间距离来评估其概率。值得注意的是,每个候选实体会产生多个多样化的向量表达.因此,在选择时仅考虑最邻近的那个

最终结果为二者的加权和

实验结果
链路预测

KS即KNN部分

低资源场景
论文研究了不同训练样本比例的变化,并对加入KS部分对模型性能的影响进行了对比分析;同时评估该方法在何种情况下能够超越现有最优(SOTA)的效果。

长尾实体上的效果比较


KNN中K的数目设置
通过这里我大致掌握了整个KNN算法的基本概念。当设定一个最近邻居数量为k时,在知识库中提取出与给定嵌入表示最接近的前k个实体。这些实体的距离被用来计算它们的概率值,并与另一种方法得出的概率结果进行加权平均。基于假设,在这k个候选实体中包含目标实体。然而,在现有公式推导中并未明确体现这一点。

插值参数的取值

可视化
2D t-SNE实现了将距离最近的k个邻居以及其他实体进行可视化展示,并通过观察可以看出,在空间布局上,那些语义相近的实体同样会显得更加靠近。

模型比较

规模越大越好,RoBERTa上限最高
案例

