知识表示学习(五):RotatE

本文提出了名为RotatE的知识图谱嵌入方法,该方法将关系表示为复向量空间中的旋转,能有效建模对称/反对称、反转和组合关系模式。RotatE结合了自我对抗负采样技术,提高了训练效率并在多个基准数据集上超越了现有最佳模型。
摘要由CSDN通过智能技术生成

一.摘要

我们研究了在知识图中学习实体和关系的表示以预测缺失链接的问题。 这种任务的成功很大程度上依赖于建模和推断关系模式(或关系模式)的能力。 在本文中,我们提出了一种新的知识图嵌入方法,称为 RotatE,它能够建模和推断各种关系模式,包括:对称/反对称、反转和组合。 具体来说,RotatE 模型将每个关系定义为在复向量空间中从源实体到目标实体的旋转。 此外,我们提出了一种新颖的自我对抗负采样技术,用于有效地训练 RotatE 模型。 在多个基准知识图谱上的实验结果表明,所提出的 RotatE 模型不仅具有可扩展性,而且能够推断和建模各种关系模式,并显着优于现有的最先进的链接预测模型。

二.背景介绍

知识图谱是事实三元组的集合,其中每个三元组 (h, r, t) 表示头实体 h 和尾实体 t 之间的关系 r。 现实世界知识图的示例包括 Freebase、Yago 和 WordNet。 知识图谱可能对各种应用有用,例如问答、信息检索、推荐系统和自然语言处理。 知识图谱的研究在学术界和工业界引起了越来越多的兴趣。
由于知识图谱通常是不完整的,知识图谱的一个基本问题是预测缺失的链接。 最近,已经对学习实体的低维表示和用于缺失链接预测的关系进行了广泛的研究。 这些方法已被证明是可扩展的和有效的。 这些方法的一般直觉是根据观察到的知识事实对知识图中的连接模式进行建模和推断。 例如,一些关系是对称的(例如,婚姻),而另一些是反对称的(例如,亲子关系); 一些关系是其他关系的逆(例如,上位词和下位词); 有些关系可能由其他人组成(例如,我母亲的丈夫是我的父亲)。 从观察到的事实中找到对这些模式进行建模和推断的方法(即对称/反对称、反转和组合)以预测缺失的链接至关重要。
实际上,许多现有方法一直在尝试隐式或显式地对上述关系模式中的一种或几种进行建模。例如,将关系表示为翻译的 TransE 模型旨在对倒置和合成模式进行建模。 DisMult 模型对头部实体、关系和尾部实体之间的三向交互进行建模,旨在对对称模式进行建模。 然而,现有模型中没有一个能够对上述所有模式进行建模和推断。 因此,我们正在寻找一种能够对所有三种类型的关系模式进行建模和推断的方法。
在本文中,我们提出了一种称为 RotatE 的知识图嵌入方法。 我们的动机来自欧拉恒等式 e^iθ = cosθ + i sinθ,这表明酉复数可以看作是在复平面上的旋转。 具体来说,RotatE 模型将实体和关系映射到复杂向量空间,并将每个关系定义为从源实体到目标实体的旋转。 给定一个三元组 (h, r, t),我们期望 t = h ◦ r,其中 h, r, t ∈ Ck 是嵌入,模 |ri| = 1 和 ◦ 表示 Hadamard(逐元素)乘积。 具体来说,对于复杂空间中的每个维度,我们期望:
在这里插入图片描述

事实证明,这样一个简单的操作可以有效地模拟所有三种关系模式:对称/反对称、反转和组合。此外,RotatE 模型可以扩展到大型知识图谱,因为它在时间和内存上都保持线性。
为了有效优化RotatE,我们进一步提出了一种新颖的自我对抗负采样技术,该技术根据当前实体和关系嵌入生成负样本。 所提出的技术非常通用,可以应用于许多现有的知识图嵌入模型。 我们在四个大型知识图谱基准数据集(包括 FB15k、WN18、FB15k-237 和 WN18RR)上评估 RotatE。 实验结果表明,RotatE 模型明显优于现有的最先进方法。 此外,RotatE 还优于 Country 的最先进模型,这是一个明确设计用于组合模式推断和建模的基准。 据我们所知,RotatE 是第一个在所有基准测试中均达到最先进性能的模型。

三.RotatE

我们首先介绍在知识图谱的链接预测文献中广泛研究的三种重要的关系模式。 随后,我们介绍了我们提出的 RotatE 模型,该模型将关系定义为复向量空间中的旋转。 我们还表明,RotatE 模型能够建模和推断所有三种关系模式。

3.1 建模和推断关系模式

知识图谱中链接预测的关键是通过观察到的事实来推断连接模式,例如关系模式。 根据现有文献,三种关系模式在知识图谱中非常重要并广泛传播:对称、反转和组合。 我们在这里给出它们的正式定义:
定义 1. 一个关系 r 是对称的(反对称的)如果 ∀x, y
在这里插入图片描述

定义 2. 如果 ∀x, y,关系 r1 与关系 r2 成反比
在这里插入图片描述

定义 3. 关系 r1 由关系 r2 和关系 r3 组成,如果 ∀x, y, z
在这里插入图片描述

根据上述三类关系模式的定义,我们对现有模型在推断和建模这些模式方面的能力进行了分析。 结果总结在表2中,可以看到,没有现有的方法能够对所有三种关系模式进行建模。
在这里插入图片描述

3.2 将关系建模为复向量空间中的旋转

在这一部分中,我们介绍了我们提出的模型,该模型能够建模和推断所有三种类型的关系模式。 受欧拉恒等式的启发,我们将头部和尾部实体 h, t 映射到复杂的嵌入,即 h, t ∈ Ck ; 然后我们将每个关系 r 引起的函数映射定义为从头部实体 h 到尾部实体 t 的逐元素旋转。 换句话说,给定一个三元组 (h, r, t),我们期望:
在这里插入图片描述

◦ 是 Hadmard(或元素)乘积。 具体来说,对于嵌入中的每个元素,我们有 ti = hiri。 在这里,我们将 r ∈ Ck 的每个元素的模,即 ri ∈ C, 约束为 |ri| = 1。通过这样做,ri 的形式为 e iθr,i ,它对应于围绕复平面原点逆时针旋转 θr,i 弧度,并且仅影响复向量空间中实体嵌入的相位 . 由于其旋转性质,我们将提出的模型称为RotatE。 根据上面的定义,对于每个三元组(h, r, t),我们定义RotatE的距离函数为:
在这里插入图片描述

与TransE的联系。从表 2 中,我们可以看到 TransE 能够推断和建模除对称模式之外的所有其他关系模式。 原因是在 TransE 中,任何对称关系都将由 0 平移向量表示。 结果,这将推动具有对称关系的实体在嵌入空间中彼此靠近。 RotatE 解决了这个问题,并且能够建模和推断对称模式。 在RotatE中可以使用满足ri=±1的任意向量r来表示对称关系,从而可以区分具有对称关系的实体。 不同的对称关系也可以用不同的嵌入向量来表示。 图 1 提供了仅具有一维嵌入的 TransE 和 RotatE 的图示,并显示了 RotatE 如何对对称关系进行建模。
在这里插入图片描述

3.3 优化

负采样已被证明对于学习知识图嵌入和词嵌入都非常有效。 在这里,我们使用类似于负采样损失 的损失函数来有效优化基于距离的模型:
在这里插入图片描述

我们还提出了一种构造负样本的新方法。 负采样损失以统一的方式对负三元组进行采样。 这种统一的负样本存在效率低下的问题,因为随着训练的进行,许多样本显然是错误的,这并不能提供任何有意义的信息。 因此,我们提出了一种称为自对抗负采样的方法,该方法根据当前的嵌入模型对负三元组进行采样。 具体来说,我们从以下分布中采样负三元组:
在这里插入图片描述

其中 α 是采样温度。 此外,由于采样过程可能代价高昂,我们将上述概率视为负样本的权重。 因此,自我对抗训练的最终负采样损失采用以下形式:
在这里插入图片描述

四.总结

我们提出了一种新的知识图嵌入方法,称为 RotatE,它将实体表示为复向量,将关系表示为复向量空间中的旋转。 此外,我们提出了一种新颖的自我对抗负采样技术,用于有效地训练 RotatE 模型。 我们的实验结果表明,RotatE 模型在四个大型基准上优于所有现有的状态模型。 此外,RotatE 还在一个专门为组合模式推断和建模而设计的基准上取得了最先进的结果。 对 RotatE 关系嵌入的深入研究表明,这三种关系模式隐含在关系嵌入中。 未来,我们计划在更多数据集上评估 RotatE 模型,并利用概率框架对实体和关系的不确定性进行建模。

五.附录

论文:https://arxiv.org/pdf/1902.10197.pdf
代码:https://github.com/DeepGraphLearning/KnowledgeGraphEmbedding

  • 7
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在使用torch对知识表示学习模型RotatE进行修改,使之输出自对抗负采样损失而不保留实体关系嵌入向量时,可以遵循以下步骤: 1. 定义模型结构 首先,我们需要定义一个新的模型结构来实现这个任务。可以参考RotatE模型的代码来定义新的模型结构,需要将实体和关系嵌入向量的权重从模型中移除,并添加自对抗负采样损失函数。这里以在RotatE的基础上对模型进行修改为例: ```python import torch import torch.nn as nn from torch.autograd import Variable class RotatE_AutoNeg(nn.Module): def __init__(self, nentity, nrelation, hidden_dim, gamma): super(RotatE_AutoNeg, self).__init__() self.nentity = nentity self.nrelation = nrelation self.hidden_dim = hidden_dim self.gamma = gamma self.embedding_range = nn.Parameter( torch.Tensor([(self.gamma + 2.0) / (self.hidden_dim * 2)]), requires_grad=False) self.entity_emb = nn.Embedding(self.nentity, self.hidden_dim) self.relation_emb = nn.Parameter(torch.Tensor(self.nrelation, self.hidden_dim)) nn.init.uniform_( tensor=self.entity_emb.weight.data, a=-self.embedding_range.item(), b=self.embedding_range.item() ) nn.init.uniform_( tensor=self.relation_emb.data, a=-self.embedding_range.item(), b=self.embedding_range.item() ) def _calc(self, h, t, r): # Calculate rotated complex embeddings re_head, im_head = torch.chunk(h, 2, dim=-1) re_tail, im_tail = torch.chunk(t, 2, dim=-1) re_relation, im_relation = torch.chunk(r, 2, dim=-1) re_head = torch.unsqueeze(re_head, dim=-1) im_head = torch.unsqueeze(im_head, dim=-1) re_tail = torch.unsqueeze(re_tail, dim=-1) im_tail = torch.unsqueeze(im_tail, dim=-1) # Perform rotation re_h = re_head * re_relation - im_head * im_relation im_h = re_head * im_relation + im_head * re_relation re_t = re_tail * re_relation + im_tail * im_relation im_t = -re_tail * im_relation + im_tail * re_relation # Concatenate real and imaginary part of embeddings h = torch.cat([re_h, im_h], dim=-1) t = torch.cat([re_t, im_t], dim=-1) return h, t def forward(self, pos_h, pos_t, pos_r, neg_h, neg_t, neg_r): # Positive triple score pos_h_emb = self.entity_emb(pos_h) pos_t_emb = self.entity_emb(pos_t) pos_r_emb = self.relation_emb(pos_r) pos_h_emb, pos_t_emb = self._calc(pos_h_emb, pos_t_emb, pos_r_emb) pos_score = torch.norm(pos_h_emb + pos_r_emb - pos_t_emb, p=2, dim=-1) # Negative triple score neg_h_emb = self.entity_emb(neg_h) neg_t_emb = self.entity_emb(neg_t) neg_r_emb = self.relation_emb(neg_r) neg_h_emb, neg_t_emb = self._calc(neg_h_emb, neg_t_emb, neg_r_emb) neg_score = torch.norm(neg_h_emb + neg_r_emb - neg_t_emb, p=2, dim=-1) # Self-adversarial negative sampling loss auto_neg_score = torch.norm(neg_h_emb + pos_r_emb - pos_t_emb, p=2, dim=-1) return pos_score, neg_score, auto_neg_score ``` 2. 定义损失函数 接下来,我们需要定义损失函数。这里使用自对抗负采样损失函数,需要计算正样本和自动生成的负样本之间的相似度,并将其作为损失函数的一部分。具体实现可以参考以下代码: ```python criterion = nn.MarginRankingLoss(margin=1.0) pos_score, neg_score, auto_neg_score = model(pos_h, pos_t, pos_r, neg_h, neg_t, neg_r) auto_neg_target = Variable(torch.Tensor([-1])).cuda() loss = criterion(pos_score - neg_score, auto_neg_score, auto_neg_target) ``` 这里使用了MarginRankingLoss作为损失函数,其中pos_score-neg_score表示正样本和负样本之间的相似度,auto_neg_score是自动生成的负样本和正样本之间的相似度,auto_neg_target是一个固定值-1,表示自动生成的负样本要与正样本距离更远。 3. 训练模型 最后,我们需要训练模型,更新模型参数。可以使用Adam等优化器来更新模型参数,具体实现可以参考以下代码: ```python optimizer = torch.optim.Adam(model.parameters(), lr=0.001) for epoch in range(100): for pos_h, pos_t, pos_r, neg_h, neg_t, neg_r in dataloader: pos_h = pos_h.cuda() pos_t = pos_t.cuda() pos_r = pos_r.cuda() neg_h = neg_h.cuda() neg_t = neg_t.cuda() neg_r = neg_r.cuda() optimizer.zero_grad() pos_score, neg_score, auto_neg_score = model(pos_h, pos_t, pos_r, neg_h, neg_t, neg_r) auto_neg_target = Variable(torch.Tensor([-1])).cuda() loss = criterion(pos_score - neg_score, auto_neg_score, auto_neg_target) loss.backward() optimizer.step() print('Epoch %d, loss %.4f' % (epoch, loss.item())) ``` 这里使用了Adam优化器来更新模型参数,每个epoch遍历一次数据集,计算损失函数并进行反向传播和优化。 这样就完成了使用torch对知识表示学习模型RotatE进行修改,使之输出自对抗负采样损失而不保留实体关系嵌入向量的过程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值