Source code for pykeen.models.unimodal.conv_kb

# -*- coding: utf-8 -*-

"""Implementation of the ConvKB model."""

import logging
from typing import Any, ClassVar, Mapping, Optional, Type

from torch.nn.init import uniform_

from ..nbase import ERModel
from ...nn.modules import ConvKBInteraction
from ...regularizers import LpRegularizer, Regularizer
from ...typing import Hint, Initializer

__all__ = [

logger = logging.getLogger(__name__)

[docs]class ConvKB(ERModel): r"""An implementation of ConvKB from [nguyen2018]_. ConvKB uses a convolutional neural network (CNN) whose feature maps capture global interactions of the input. Each triple $(h,r,t) \in \mathbb{K}$ is represented as a input matrix $\mathbf{A} = [\mathbf{h}; \mathbf{r}; \mathbf{t}] \in \mathbb{R}^{d \times 3}$ in which the columns represent the embeddings for $h$, $r$, and $t$. In the convolution layer, a set of convolutional filters $\omega_i \in \mathbb{R}^{1 \times 3}, i=1, \dots, \tau,$ are applied on the input in order to compute for each dimension global interactions of the embedded triple. Each $\omega_i $ is applied on every row of $\mathbf{A}$ creating a feature map $\mathbf{v}_i = [v_{i,1},...,v_{i,d}] \in \mathbb{R}^d$: .. math:: \mathbf{v}_i = g(\omega_j \mathbf{A} + \mathbf{b}) where $\mathbf{b} \in \mathbb{R}$ denotes a bias term and $g$ an activation function which is employed element-wise. Based on the resulting feature maps $\mathbf{v}_1, \dots, \mathbf{v}_{\tau}$, the plausibility score of a triple is given by: .. math:: f(h,r,t) = [\mathbf{v}_i; \ldots ;\mathbf{v}_\tau] \cdot \mathbf{w} where $[\mathbf{v}_i; \ldots ;\mathbf{v}_\tau] \in \mathbb{R}^{\tau d \times 1}$ and $\mathbf{w} \in \mathbb{R}^{\tau d \times 1} $ is a shared weight vector. ConvKB may be seen as a restriction of :class:`pykeen.models.ERMLP` with a certain weight sharing pattern in the first layer. .. seealso:: - Authors' `implementation of ConvKB <>`_ --- citation: author: Nguyen year: 2018 link: github: daiquocnguyen/ConvKB """ #: The default strategy for optimizing the model's hyper-parameters hpo_default: ClassVar[Mapping[str, Any]] = dict( embedding_dim=DEFAULT_EMBEDDING_HPO_EMBEDDING_DIM_RANGE, hidden_dropout_rate=DEFAULT_DROPOUT_HPO_RANGE, num_filters=dict(type=int, low=7, high=9, scale="power_two"), ) #: The regularizer used by [nguyen2018]_ for ConvKB. regularizer_default: ClassVar[Type[Regularizer]] = LpRegularizer #: The LP settings used by [nguyen2018]_ for ConvKB. regularizer_default_kwargs: ClassVar[Mapping[str, Any]] = dict( weight=0.001 / 2, p=2.0, normalize=True, apply_only_once=True, ) def __init__( self, *, embedding_dim: int = 200, hidden_dropout_rate: float = 0.0, num_filters: int = 400, regularizer: Optional[Regularizer] = None, entity_initializer: Hint[Initializer] = uniform_, relation_initializer: Hint[Initializer] = uniform_, **kwargs, ) -> None: """Initialize the model. :param embedding_dim: The entity embedding dimension $d$. :param hidden_dropout_rate: The hidden dropout rate :param num_filters: The number of convolutional filters to use :param regularizer: The regularizer to use. Defaults to $L_p$ :param entity_initializer: Entity initializer function. Defaults to :func:`torch.nn.init.uniform_` :param relation_initializer: Relation initializer function. Defaults to :func:`torch.nn.init.uniform_` :param kwargs: Remaining keyword arguments passed through to :class:`pykeen.models.EntityRelationEmbeddingModel`. To be consistent with the paper, pass entity and relation embeddings pre-trained from TransE. """ super().__init__( interaction=ConvKBInteraction, interaction_kwargs=dict( hidden_dropout_rate=hidden_dropout_rate, embedding_dim=embedding_dim, num_filters=num_filters, ), entity_representations_kwargs=dict( shape=embedding_dim, initializer=entity_initializer, ), relation_representations_kwargs=dict( shape=embedding_dim, initializer=relation_initializer, ), **kwargs, ) regularizer = self._instantiate_regularizer(regularizer=regularizer) # In the code base only the weights of the output layer are used for regularization # c.f. if regularizer is not None: self.append_weight_regularizer( parameter=self.interaction.linear.parameters(), regularizer=regularizer, ) logger.warning("To be consistent with the paper, initialize entity and relation embeddings from TransE.")