一个使用平移距离模型的玩具示例

以下教程基于Heiko Paulheim在PyKEEN问题跟踪器上提出的一个问题 #97

给定以下包含三个实体组成的三角形的玩具示例,像pykeen.models.TransE这样的平移距离模型应该能够准确地学习几何结构。

头部

关系

尾部

布鲁塞尔

位于

比利时

比利时

部分

欧盟

欧盟

hasCapital

布鲁塞尔

from pykeen.pipeline import pipeline
tf = ...
results = pipeline(
    training=tf,
    testing=...,
    model = 'TransE',
    model_kwargs=dict(embedding_dim=2),
    random_seed=1,
    device='cpu',
)
results.plot()
Troubleshooting Image 1

首先,使用results.plot_losses检查模型是否收敛。 从定性上讲,这意味着损失正在平稳下降并最终趋于平稳。如果模型没有下降,你可能需要通过optimizer_kwargstraining_kwargs调整一些参数到pipeline()函数中。

例如,您可以降低优化器的学习率,使损失曲线不那么波动。其次,您可以增加训练期间的epoch数量。

results = pipeline(
    training=tf,
    testing=...,
    model = 'TransE',
    model_kwargs=dict(embedding_dim=2),
    optimizer_kwargs=dict(lr=1.0e-1),
    training_kwargs=dict(num_epochs=128, use_tqdm_batch=False),
    evaluation_kwargs=dict(use_tqdm=False),
    random_seed=1,
    device='cpu',
)
results.plot()
Troubleshooting Image 2

请注意,训练中存在一定的随机性,因为我们为正样本采样负样本。因此,损失可能会自然波动。为了更好地观察趋势,您可以通过对多个epoch的窗口进行平均来平滑损失。

我们默认使用基于边界的损失与TransE。因此,如果模型预测的分数使得正三元组和负三元组的分数至少相差一个边界,就足够了。一旦模型达到这种状态,如果嵌入已经“足够好”,模型就不会在这些示例上进一步改进。因此,使用基于边界的损失的最优解可能看起来不像精确的几何解。如果你想改变这一点,你可以切换到不使用边界的损失函数,例如softplus损失。你可以通过将loss="softplus"传递给管道来实现这一点。

toy_results = pipeline(
    training=tf,
    testing=...,
    model='TransE',
    loss='softplus',
    model_kwargs=dict(embedding_dim=2),
    optimizer_kwargs=dict(lr=1.0e-1),
    training_kwargs=dict(num_epochs=128, use_tqdm_batch=False),
    evaluation_kwargs=dict(use_tqdm=False),
    random_seed=1,
    device='cpu',
)
results.plot()
Troubleshooting Image 3

!99上有许多有趣的后续讨论,期间这段代码被实现以便重用。其中一个有趣的观点是,关系图仅适用于像TransE这样的平移距离模型。此外,当模型的嵌入维度高于2时,必须使用降维方法。为此,可以从scikit-learn中的许多工具中选择一个。然而,为了确保实体和关系投影在同一轴上,降维模型首先在实体嵌入上进行训练,然后应用于实体嵌入和关系嵌入。此外,在绘制关系时不应使用像KPCA这样的非线性模型,因为这些模型在嵌入空间中应该对应于线性变换。