Advertisement

ConvE:Convolutional 2D Knowledge Graph Embeddings

阅读量:

这篇论文提出了一种基于二维卷积的模型ConvE,用于知识图谱补全任务。该模型通过卷积操作高效提取实体和关系的特征交互,解决了传统浅层模型的参数过多和过拟合问题。ConvE在训练多层卷积网络时引入了鲁棒的正则化方法,如Dropout和BatchNorm,进一步提升模型性能。实验表明,ConvE在逆关系测试集上表现优异,能够有效处理知识图谱中的复杂关系。该模型不仅参数效率高,还能处理有向图和内存受限的情况,为知识图谱补全提供了新的解决方案。

论文:Convolutional 2D Knowledge Graph Embeddings

1 介绍

1.1 提出原因

基于以往研究的模型,如disMult和Trans系列,可被视为较浅层的模型。这些模型虽然参数相对较少,且训练速度较快,但相较于较深的模型,在捕捉复杂信息方面的能力较为有限。为了提升复杂性,提出ConvE模型,该模型通过卷积方式对知识图谱进行补全,从而适用于更为复杂的图结构。

在浅层模型中,仅在增加嵌入维度时才能实现特征数量的提升。然而,这使得扩展到更为庞大的知识图谱变得受限,因为嵌入参数的总数与图中实体和关系的数量呈正相关。此外,传统的多层知识图嵌入体系结构采用全连接设计,容易导致模型出现过拟合现象。

1.2ConvE优势

ConvE基于卷积机制,经过高度优化的硬件支持使其在参数效率和计算速度上均表现出色。在实际应用中,为了应对复杂场景,提出了系统性的方法来控制过拟合。本文提出了一种基于二维卷积的嵌入模型,该模型通过在嵌入空间中应用卷积操作,有效识别知识图谱中的潜在关系。该模型作为最简单的多层卷积架构,仅由单个卷积层、经过优化的嵌入维数投影层和内积层构成。与传统的GCN框架相比,知识图谱具有明确的方向性,并受到计算资源限制,这使得ConvE在处理大规模知识图谱时展现出独特优势。

1.3 贡献

提出了一个简单的、具有竞争力的2D卷积链路预测模型,ConvE。 构建了一个1-N评分系统,该系统不仅加速了训练速度,还提升了评估效率。 系统研究了逆关系测试集的泄露问题,并开发了鲁棒版本的数据集,以防止简单的基于规则的模型能够有效预测。

2 模型

2.1 1D vs 2D Convolutions

1D Convolutions
([a a a] ; [b b b]) = [a a a b b b]
若采用filter, 其 size k = 3, 结果为维度1\times4

2D卷积运算
\begin{pmatrix} \begin{bmatrix} a & a & a \\ a& a & a\\ \end{bmatrix}; \begin{bmatrix} b&b&b\\ b&b&b\\ \end{bmatrix} \end{pmatrix}= \begin{bmatrix} a&a&a\\ a&a&a\\ b&b&b\\ b&b&b\\ \end{bmatrix}
当采用滤波器时,其尺寸k为3×3,输出结果的维度为2×1。
二维卷积操作能够模拟a和b之间的更多交互作用,其规模与m、n、k呈正比。相比之下,二维卷积能够提取两个嵌入之间的更多特征交互作用。

2.2 模型图

在这里插入图片描述

模型讲解:

通过one-hot编码表示头实体和关系,并通过嵌入层将头实体和关系进行嵌入表示,维度为k。经过 reshape 处理后进行拼接,随后通过卷积层进行特征提取。接着,通过全连接层将嵌入后的特征映射到 k 维空间。最后,将全连接层的输出与所有嵌入结果进行点积,从而实现对每个实体的打分,即为每个实体赋予权重评分。

2.3 评分函数

在这里插入图片描述

其中,\mathbf{r}_{r}属于\mathbb{R}_{k}\overline{\mathit{e}}_{s}\overline{\mathit{r}}_{r}分别代表经过2D reshape后的e_{s}r_{r}e_{s}r_{r}属于\mathbb{R}_{k},经过2D reshape后的\overline{\mathit{e}}_{s}\overline{\mathit{r}}_{r}属于\mathbb{R}^{k_{w}\times k_{h}},且k等于k_{w}\times k_{h}

2.4 损失函数

在这里插入图片描述

2.5 正则化

我们通过在多个阶段应用Dropout技术来规范模型,以防止过拟合现象。具体而言,我们对嵌入层、卷积操作后的feature map以及全连接层后的hidden units进行了Dropout处理。此外,我们采用BatchNorm进行归一化处理,分别在卷积操作前和卷积操作后实施归一化处理。

3 代码

论文原作的代码基于一个复杂的框架,使得代码难以理解,因此需要寻找一个更易理解的替代方案。模型代码的实现部分可以参考以下链接:点我

复制代码
    import torch
    import torch.nn as nn
    import torch.nn.functional as F
    from torch.nn import  Parameter
    class ConvE(nn.Module):
    def __init__(self, config):
        super(ConvE, self).__init__()
        self.config = config
        self.ent_embs = nn.Embedding(self.config.ent_num, self.config.dim)
        self.rel_embs = nn.Embedding(self.config.rel_num, self.config.dim)
        self.input_drop = nn.Dropout(config.inputDrop)
        self.hide_drop = nn.Dropout(config.hideDrop)
        self.feature_drop = nn.Dropout2d(config.featureDrop)
        self.conv = nn.Conv2d(1, 32, (3, 3), bias=True)
        self.bn0 = nn.BatchNorm2d(1)
        self.bn1 = nn.BatchNorm2d(32)
        self.bn2 = nn.BatchNorm1d(config.dim)
        self.fc = nn.Linear(config.hide_size, config.dim)
        self.dim = config.dim #dim = 200
        self.dim1 = config.dim1  #dim1 = 20
        self.dim2 = self.dim // self.dim1 # dim2 = 10
        self.loss = nn.BCELoss()
        self.register_parameter('b',Parameter(torch.zeros(config.ent_num)))
        self.init()
        
    def init(self):
        nn.init.xavier_normal_(self.ent_embs.weight.data)
        nn.init.xavier_normal_(self.rel_embs.weight.data)
    def forward(self, e1, rel):
        e1_emb = self.ent_embs(e1).view(-1, 1, self.dim1, self.dim2)#el_emb; batch*1*20*10
        rel_emb = self.rel_embs(rel).view(-1, 1 ,self.dim1, self.dim2)
        
        conv_input = torch.cat([e1_emb, rel_emb], dim = 2)#con_input: bath*1*40*10
        conv_input = self.bn0(conv_input)
        x = self.input_drop(conv_input)
        x = self.conv(conv_input)
        x = self.bn1(x)
        x = F.relu(x)
        x = self.feature_drop(x)
        x = x.view(x.shape[0], -1)#bacth*hide_size(38*8*32 = 9728)
        x = self.fc(x)
        x = self.hide_drop(x)
        x = self.bn2(x)
        x = F.relu(x)#batch*dim          ent_ems.weight   dim*ent_num
        #print(x.shape, self.ent_embs.weight.shape)
        x = torch.mm(x, self.ent_embs.weight.transpose(1, 0))
        x += self.b.expand_as(x)
        pred = torch.sigmoid(x)
        return pred

全部评论 (0)

还没有任何评论哟~