pykeen Logo

入门指南

  • 安装
  • First Steps
  • 知识图谱嵌入模型
  • 训练期间的跟踪结果
  • 训练期间保存检查点
  • 使用平移距离模型的玩具示例
  • 理解评估
  • 优化模型的超参数
  • 运行消融研究
  • 性能技巧
  • Representations
  • NodePiece入门指南
  • 归纳链接预测
    • 组织数据集
    • Featurizing Unseen Entities
      • NodePiece
      • 基于标签的Transformer表示
    • 训练与评估
    • 完整归纳逻辑编程示例
  • Splitting
  • PyTorch Lightning 集成
  • 使用解析器
  • 故障排除

自带

  • Bring Your Own Data
  • Bring Your Own Interaction

扩展 PyKEEN

  • 扩展数据集
  • 扩展模型

参考

  • Pipeline
  • Models
  • Datasets
  • 归纳数据集
  • 实体对齐
  • Triples
  • Triples Workflows
  • 培训
  • Stoppers
  • 损失函数
  • Regularizers
  • 结果追踪器
  • 负采样
  • 过滤
  • Optimizers
  • 评估
  • Metrics
  • 超参数优化
  • Ablation
  • Prediction
  • 不确定性
  • Sealant
  • 常量
  • 灵活的权重检查点
  • pykeen.nn
  • Utilities

附录

  • 分析
  • 参考文献
pykeen
  • Inductive Link Prediction
  • View page source

归纳链接预测

Transductive vs Inductive setup

多年来,PyKEEN和其他KGE库中的标准训练设置意味着训练图包括我们将进行推理(验证、测试或自定义预测)的所有实体。也就是说,要预测的缺失链接连接了训练图中已经见过的实体。这种链接预测设置被称为转导设置。

如果在推理时我们有新的、未见过的实体,并且想要预测这些未见实体之间的链接,该怎么办? 这种情况在归纳框架下得到了统一。 在上图中展示的差异,归纳设置的主要区别在于,在推理时我们有一个新的图(称为归纳推理图),并且链接预测是针对这个新的未见实体的推理图执行的。

事实上,根据[ali2021]的分类,存在几种归纳设置的变体:

  • 推理图与训练图完全断开(不相交),也称为完全归纳设置。 因此,实体之间的链接预测模式是未见过的到未见过的。

  • 推理图扩展了训练图,将新节点连接到已见图,即半归纳设置。 当我们预测新添加节点之间的链接时,链接预测模式可以是未见-到-未见, 或者当我们预测已知节点与新到达节点之间的链接时,可以是未见-到-已见 / 已见-到-未见。

PyKEEN 支持归纳链接预测,提供接口来组织数据集,构建未见实体的表示,并在其上应用任何现有的交互函数。最重要的是,关系集必须在训练时被看到。也就是说,推理时看到的关系必须是训练时关系的一个子集,因为我们将学习这些关系的表示以转移到未见图中。

组织数据集

构建归纳数据集的基本类是 pykeen.datasets.inductive.InductiveDataset。 它应该包含超过3个三元组工厂,即在完全归纳设置中,预计至少有4个三元组工厂(transductive_training、inductive_inference、inductive_validation、inductive_test)。 transductive_training 是具有实体索引 (0..N) 的图,我们将在此图上训练模型, inductive_inference 是在推理时出现的新图,包含新实体(索引 (0..K))。 请注意,transductive_training 和 inductive_inference 中的实体数量不同。 inductive_validation 和 inductive_test 与 inductive_inference 共享实体, 但不与 transductive_training 共享。这样,我们告知模型我们是在针对归纳推理图而不是训练图进行链接预测。

PyKEEN 支持由 [teru2020] 引入的 12 个完全归纳的数据集,其中训练和归纳推理图是分离的。每个知识图谱家族,InductiveFB15k237、InductiveWN18RR 和 InductiveNELL,都有 4 个版本,这些版本根据训练和推理图的大小以及实体和关系的总数而变化。确保所有推理图的关系集是其训练图的子集。

特征化未见实体

在训练图上训练实体嵌入是没有意义的,因为这些嵌入在推理时无法使用。 相反,我们需要一些通用的特征化机制,能够构建已见和未见实体的表示。 在PyKEEN中,根据节点描述的可用性,至少存在两种这样的机制。

NodePiece

在最基本的情况下,未见的实体到达时没有任何特征或描述。 我们使用pykeen.nn.representation.NodePieceRepresentation来应对这种情况 - 由于训练和推理时的关系集是相同的,NodePiece表示将通过一组相关关系类型对每个实体进行标记。 出于计算原因,inductive_inference实体的NodePiece表示(在推理时可见)也可以预先计算。

目前,PyKEEN 提供了两种归纳式 NodePiece 实现: * pykeen.models.inductive.InductiveNodePiece - 基础版本; * pykeen.models.inductive.InductiveNodePieceGNN - 除了标记化和可学习的哈希编码器外,此版本还在从词汇表构建节点表示后,在 inductive_inference 图上执行消息传递。默认情况下,消息传递是通过 2 层 CompGCN 执行的。

NodePiece的归纳版本在关系tokens的词汇表上训练一个编码器,这些词汇表在推理时可以轻松重复使用。这样,我们可以获得未见实体的表示。InductiveNodePiece和InductiveNodePieceGNN可以与PyKEEN中的任何交互函数配对,其中关系向量的维度与最终节点向量的维度相同。可以通过自定义关系表示模块的初始化来集成替代的交互。

让我们使用InductiveFB15k237数据集之一创建一个基本的InductiveNodePiece:

from pykeen.datasets.inductive.ilp_teru import InductiveFB15k237
from pykeen.models.inductive import InductiveNodePiece
from pykeen.losses import NSSALoss

dataset = InductiveFB15k237(version="v1", create_inverse_triples=True)

model = InductiveNodePiece(
    triples_factory=dataset.transductive_training,  # training factory, used to tokenize training nodes
    inference_factory=dataset.inductive_inference,  # inference factory, used to tokenize inference nodes
    num_tokens=12,  # length of a node hash - how many unique relations per node will be used
    aggregation="mlp",  # aggregation function, defaults to an MLP, can be any PyTorch function
    loss=NSSALoss(margin=15),  # dummy loss
    random_seed=42,
)

创建消息传递版本的NodePiece几乎是一样的:

from pykeen.datasets.inductive.ilp_teru import InductiveFB15k237
from pykeen.models.inductive import InductiveNodePieceGNN
from pykeen.losses import NSSALoss

dataset = InductiveFB15k237(version="v1", create_inverse_triples=True)

model = InductiveNodePieceGNN(
    triples_factory=dataset.transductive_training,  # training factory, will be also used for a GNN
    inference_factory=dataset.inductive_inference,  # inference factory, will be used for a GNN
    num_tokens=12,  # length of a node hash - how many unique relations per node will be used
    aggregation="mlp",  # aggregation function, defaults to an MLP, can be any PyTorch function
    loss=NSSALoss(margin=15),  # dummy loss
    random_seed=42,
    gnn_encoder=None,  # defaults to a 2-layer CompGCN with DistMult composition function
)

请注意,此版本具有gnn_encoder参数 - 将其保持为None将调用默认的2层CompGCN。 您可以在此处传递任何返回更新后的实体和关系矩阵的关系GNN,因为评分函数将使用它们来对三元组进行排名。有关更多详细信息,请参见pykeen.models.inductive.InductiveNodePieceGNN。

基于标签的Transformer表示

如果实体描述可用,通用特征化机制可以是通过pykeen.nn.representation.LabelBasedTransformerRepresentation访问的语言模型。在训练和推理时,通过将它们的文本描述传递到预训练的语言模型后,可以获得固定大小的实体向量。

这是正在进行的工作,目前尚不可用。

训练与评估

通常,归纳模型的训练和评估使用相似的接口: sLCWA 和 LCWA 训练循环,以及 RankBasedEvaluator。 归纳接口的重要新增内容是 mode 参数。当设置为 mode=”training” 时, 归纳模型必须调用训练图的表示,当设置为 mode=validation 或 mode=testing 时,模型必须调用推理图的表示。 在来自 [teru2020] 的完全归纳(不相交)数据集的情况下,验证和测试时的推理图是相同的。

默认情况下,您可以使用标准的PyKEEN训练循环pykeen.training.SLCWATrainingLoop和 pykeen.training.LCWATrainingLoop与新的mode参数。同样,您可以使用 标准评估器pykeen.evaluation.rank_based_evaluator.RankBasedEvaluator与mode 参数来评估整个推理图上的验证/测试三元组。

此外,[teru2020] 的原始工作使用了一种受限的评估协议,每个验证/测试三元组仅针对50个随机负样本进行排名。PyKEEN 使用 pykeen.evaluation.rank_based_evaluator.SampledRankBasedEvaluator 实现了这一协议。

让我们创建一个训练循环和验证/测试评估器:

from pykeen.datasets.inductive.ilp_teru import InductiveFB15k237
from pykeen.training import SLCWATrainingLoop
from pykeen.evaluation.rank_based_evaluator import SampledRankBasedEvaluator
from pykeen.losses import NSSALoss

dataset = InductiveFB15k237(version="v1", create_inverse_triples=True)

model = ...  # model init here, one of InductiveNodePiece
optimizer = ...  # some optimizer

training_loop = SLCWATrainingLoop(
    triples_factory=dataset.transductive_training,  # training triples
    model=model,
    optimizer=optimizer,
    mode="training",   # necessary to specify for the inductive mode - training has its own set of nodes
)

valid_evaluator = SampledRankBasedEvaluator(
    mode="validation",   # necessary to specify for the inductive mode - this will use inference nodes
    evaluation_factory=dataset.inductive_validation,  # validation triples to predict
    additional_filter_triples=dataset.inductive_inference.mapped_triples,   # filter out true inference triples
)

test_evaluator = SampledRankBasedEvaluator(
    mode="testing",   # necessary to specify for the inductive mode - this will use inference nodes
    evaluation_factory=dataset.inductive_testing,  # test triples to predict
    additional_filter_triples=dataset.inductive_inference.mapped_triples,   # filter out true inference triples
)

完全归纳LP示例

一个在InductiveFB15k237 (v1)上训练InductiveNodePieceGNN的最小工作示例,使用sLCWA模式,每个正样本有32个负样本,使用NSSALoss和SampledEvaluator,看起来像这样:

from pykeen.datasets.inductive.ilp_teru import InductiveFB15k237
from pykeen.models.inductive import InductiveNodePieceGNN
from pykeen.training import SLCWATrainingLoop
from pykeen.evaluation.rank_based_evaluator import SampledRankBasedEvaluator
from pykeen.stoppers import EarlyStopper
from pykeen.losses import NSSALoss
from torch.optim import Adam

dataset = InductiveFB15k237(version="v1", create_inverse_triples=True)

model = InductiveNodePieceGNN(
    triples_factory=dataset.transductive_training,  # training factory, will be also used for a GNN
    inference_factory=dataset.inductive_inference,  # inference factory, will be used for a GNN
    num_tokens=12,  # length of a node hash - how many unique relations per node will be used
    aggregation="mlp",  # aggregation function, defaults to an MLP, can be any PyTorch function
    loss=NSSALoss(margin=15),  # dummy loss
    random_seed=42,
    gnn_encoder=None,  # defaults to a 2-layer CompGCN with DistMult composition function
)

optimizer = Adam(params=model.parameters(), lr=0.0005)

training_loop = SLCWATrainingLoop(
    triples_factory=dataset.transductive_training,  # training triples
    model=model,
    optimizer=optimizer,
    negative_sampler_kwargs=dict(num_negs_per_pos=32),
    mode="training",   # necessary to specify for the inductive mode - training has its own set of nodes
)

# Validation and Test evaluators use a restricted protocol ranking against 50 random negatives
valid_evaluator = SampledRankBasedEvaluator(
    mode="validation",   # necessary to specify for the inductive mode - this will use inference nodes
    evaluation_factory=dataset.inductive_validation,  # validation triples to predict
    additional_filter_triples=dataset.inductive_inference.mapped_triples,   # filter out true inference triples
)

# According to the original code
# https://github.com/kkteru/grail/blob/2a3dffa719518e7e6250e355a2fb37cd932de91e/test_ranking.py#L526-L529
# test filtering uses only the inductive_inference split and does not include inductive_validation triples
# If you use the full RankBasedEvaluator, both inductive_inference and inductive_validation triples
# must be added to the additional_filter_triples
test_evaluator = SampledRankBasedEvaluator(
    mode="testing",   # necessary to specify for the inductive mode - this will use inference nodes
    evaluation_factory=dataset.inductive_testing,  # test triples to predict
    additional_filter_triples=dataset.inductive_inference.mapped_triples,   # filter out true inference triples
)

early_stopper = EarlyStopper(
    model=model,
    training_triples_factory=dataset.inductive_inference,
    evaluation_triples_factory=dataset.inductive_validation,
    frequency=1,
    patience=100000,  # for test reasons, turn it off
    result_tracker=None,
    evaluation_batch_size=256,
    evaluator=valid_evaluator,
)

# Training starts here
training_loop.train(
    triples_factory=dataset.transductive_training,
    stopper=early_stopper,
    num_epochs=100,
)

# Test evaluation
result = test_evaluator.evaluate(
    model=model,
    mapped_triples=dataset.inductive_testing.mapped_triples,
    additional_filter_triples=dataset.inductive_inference.mapped_triples,
    batch_size=256,
)

# print final results
print(result.to_flat_dict())
Previous Next

© 版权所有 2019-2024, PyKEEN 项目团队。

Built with Sphinx using a theme provided by Read the Docs.