使用解析器
由于PyKEEN是一个高度模块化和可扩展的库,我们使用了class_resolver库来允许简单的组件配置。在本教程的这一部分中,我们将解释如何使用这些配置选项,以及如何确定可以在此处传递的值。
我们使用基础模型类的初始化方法 pykeen.models.base.Model() 及其对损失函数的处理作为示例。其签名如下:
def __init__(
self,
*,
...,
loss: HintOrType[Loss] = None,
loss_kwargs: OptionalKwargs = None,
...,
) -> None:
注意两个相关的参数 loss: HintOrType[Loss] = None 和 loss_kwargs: OptionalKwargs = None。 loss_kwargs 因此接受类型为 OptionalKwargs 的值作为输入,这是 Union[None, Mapping[str, Any]] 的缩写。因此,我们可以传递一个字符串键到某些值的映射,或者传递 None。 在后一种情况下,传递 None 被解释为一个空字典。
loss 参数接受类型为 HintOrType[Loss] 的输入。HintOrType[Loss] 是 Union[None, str, Type[Loss], Loss] 的缩写。因此,我们可以传递
一个 实例 的
pykeen.losses.Loss,例如pykeen.losses.MarginRankingLoss(margin=2.0)。 如果传递了pykeen.losses.Loss的实例,它将直接使用而不进行修改。在这种情况下, loss_kwargs 将被忽略。一个
pykeen.losses.Loss的子类,例如pykeen.losses.MarginRankingLoss在这种情况下,该类使用给定的loss_kwargs作为(基于关键字的)参数进行实例化。例如,loss = MarginRankingLoss loss_kwargs = None # equivalent to {}
翻译为 MarginRankingLoss()。我们还可以通过选择不同的实例化参数来实现
loss = MarginRankingLoss loss_kwargs = dict(margin=2) # or {"margin": 2}
这转化为 MarginRankingLoss(margin=2)
一个字符串。此字符串用于通过类解析器的lookup函数搜索匹配的类。 lookup函数执行一些字符串规范化,并将结果键与它关联的类的规范化名称进行比较。然后使用找到的类来实例化对象,就像我们传递了这个类而不是字符串一样。 例如,我们可以通过传递“MarginRankingLoss”、“marginrankingloss”、“marginranking”、“margin-ranking”或“MRL”来获取MarginRankingLoss的实例。
None。在这种情况下,我们使用在类解析器中设置的default类,这恰好是
MarginRankingLoss用于loss_resolver。如果没有设置default,将会抛出异常。
确定允许的输入
为了使PyKEEN易于扩展和维护,我们经常使用None作为选择,例如loss,以及基于关键字的参数。这有时会使阅读默认值、可用有效选择以及这些不同选择允许的参数变得困难。在下文中,我们描述了几种查找此信息的方法。
首先,你应该看一下类型注解。HintOrType[X] = None 告诉你,你可以传递任何 X 的子类。此外,你还可以传递类名的字符串,这通常更容易为你的结果跟踪、命令行参数或超参数搜索进行设置。PyKEEN 中使用的所有类的解析器都是使用 ClassResolver.from_subclasses 工厂函数实例化的,该函数会自动注册给定基类的所有子类作为有效选择。此外,它允许你传递不带基类名称后缀的类名,例如,loss_resolver 接受 MarginRanking 而不是 MarginRankingLoss,因为在规范化过程中基类名称 Loss 被移除为后缀。为了利用这一功能,我们尝试为所有可配置部分遵循适当的命名方案,例如,pykeen.nn.representation.Representation,或 pykeen.nn.modules.Interaction。
…_kwargs: OptionalKwargs 允许的参数较难确定,因为它们随组件的选择而变化!例如,MarginRankingLoss 有一个 margin 参数,而 pykeen.losses.BCEWithLogitsLoss 则不提供此类参数。因此,您应查阅各个类的文档,以了解可用的参数和允许的值。