本文描述如何扩展图神经网络(GNNs)的最简单公式,以编码知识图谱(KGs)等多关系数据的结构。
这篇文章包括4个主要部分:
- 介绍了描述KGs特性的多关系数据的核心思想;
- GNN体系结构中包含的标准组件摘要;
- gnn最简单公式的描述,称为图卷积网络(GCNs);
- 讨论如何以关系图卷积网络(R-GCN)的形式扩展GCN层,对多关系数据进行编码。
知识图作为多关系数据
基本图结构包括用于连接节点的无向,无类型和唯一边。例如,在哲学领域,我们可以定义两个由“苏格拉底”和“柏拉图”实体表示的节点之间的链接。在这种特定情况下,我们不提供关于这些哲学家之间关系的任何信息。。
另一方面,KG包括定向的,类型化的和用于连接节点的多个边。考虑我们正在运行的示例,从“苏格拉底”到“柏拉图”的连接可以用“影响”来标记。在相反的方向上,可以建立从“柏拉图”到“苏格拉底”的另一种连接,可以用“影响者”来标记。
换句话说,KG是基于图的结构,其节点表示真实世界的实体,而边沿则定义了这些实体之间的多个关系。
图神经网络
GNN的主要组件包括(I)输入层,(ii) GNN层,(iii)多层感知器(MLP)预测层。
在该体系结构中,GNN层是编码局部图结构的关键组件,用于更新节点表示。不同的GNN层使用不同类型的局部图结构聚合。为了说明使用GNN行为,我们使用NumPy进行编码,完成以下3个主要成分:
- 表示节点的独热向量(无特征)矩阵
- 描述节点隐藏特征的权值矩阵
- 定义节点间无向边的邻接矩阵
###One-hotvectorrepresentationofnodes (5,5): X=np.eye(5, 5) n=X.shape[0] np.random.shuffle(X) print(X) -----[[0.0.1.0.0.] #Node1 [0.1.0.0.0.] #Node2 [0.0.0.0.1.] ... [1.0.0.0.0.] [0.0.0.1.0.]] #Node5###Weightmatrix (5,3) #Dimensionofthehiddenfeaturesh=3#RandominitializationwithGlorotandBengioW=np.random.uniform(-np.sqrt(1./h), np.sqrt(1./h),(n,h)) print(W) -----[[-0.42940490.57624235-0.3047382 ] [-0.11941829-0.129429530.19600584] [ 0.50291720.3998854-0.21561317] [ 0.02834577-0.06529497-0.31225734] [ 0.039737760.47800217-0.04941563]] ###AdjacencymatrixofanundirectGraph (5,5) A=np.random.randint(2, size=(n, n)) #Includetheselfloopnp.fill_diagonal(A, 1) #Symmetricadjacencymatrix (undirectedgraph) A_und= (A+A.T) A_und[A_und>1] =1print(A_und) -----[[11101] #ConnectionstoNode1 [11111] [11110] [01111] [11011]]
考虑到这些因素,通过更新过程的所谓“消息传递框架”(message passing framework ,Gilmer ,2017)执行了“递归邻域扩散”( recursive neighborhood diffusion ,Dwivedi,2020)。邻居的特征通过边缘作为消息传递给目标节点。具体地说,所需的操作如下(请参阅NumPy代码了解更多细节):
- 涉及节点和权重矩阵(包括其隐藏特征)的初始表示的线性变换(或投影)。
- 邻域扩散以更新节点的表示形式,汇总其邻居的隐藏特征。针对每个节点并行计算此操作。
###LineartransformationL_0=X.dot(W) print(L_0) -----[[ 0.50291720.3998854-0.21561317] #Node1 (3rdrowofW) [-0.11941829-0.129429530.19600584] #Node2 (2ndrowofW) [ 0.039737760.47800217-0.04941563] #Node3 (5throwofW) [-0.42940490.57624235-0.3047382 ] [ 0.02834577-0.06529497-0.31225734]] #Node5 (4throwofW) ###GNN-NeighborhooddiffusionND_GNN=A_und.dot(L_0) print(ND_GNN) -----[[ 0.451582440.68316307-0.3812803 ] #UpdatedNode1 [ 0.022177541.25940542-0.6860185 ] [-0.006168231.3247004-0.37376116] [-0.480739660.85952002-0.47040533] [-0.017560220.78140325-0.63660287]] ###Testontheaggregationassert(ND_GNN[0,0] ==L_0[0,0] +L_0[1,0] +L_0[2,0] +L_0[4,0])
观察邻域扩散的结果,您可以注意到节点1的更新表示
[0.50291720.3998854-0.21561317] #Node1
为表示节点1 (self-loop)、节点2、节点3、节点4的向量之和。这些节点根据前面定义的邻接矩阵连接到节点1。
[ 0.50291720.3998854-0.21561317] #Node1[-0.11941829-0.129429530.19600584] #Node2[ 0.039737760.47800217-0.04941563] #Node3[ 0.02834577-0.06529497-0.31225734] #Node5
本节中描述的代码可以在数学上形式化如下:
通用更新功能(h_i ^(l + 1)),用于将邻居(h_j ^ l)的隐藏特征聚合到中心节点(h_i ^ l)的隐藏特征
图卷积网络(GCNs)
在被称为普通图卷积网络(GCNs)的GNNs的公式中,节点更新是通过“对邻域特征进行各向同性平均运算”来执行的(isotropic averaging operation over the neighborhood features ,Dwivedi,2020)。换句话说,相邻节点同样有助于更新中心节点的表示。更准确地说,在普通GCNs(Vanilla GCNs)的具体情况下,执行了各向同性平均计算。这个计算需要一个由每个节点的度表示的新元素,该度由其连接边的数量组成。
###Degreevector (degreeforeachnode) D=A_und.sum(axis=1) print(D) -----[45444] #DegreeofNode1###Reciprocalofthedegree (diagonalmatrix) D_rec=np.diag(np.reciprocal(D.astype(np.float32))) print(D_rec) -----[[0.250.0.0.0. ] #ReciprocalvalueofNode1degree [0.0.20.0.0. ] [0.0.0.250.0. ] [0.0.0.0.250. ] [0.0.0.0.0.25]] ###GCN-IsotropicaveragecomputationND_GCN=D_rec.dot(ND_GNN) print(ND_GCN) -----[[ 0.112895610.17079077-0.09532007] #UpdatedNode1 (withdeg) [ 0.004435510.25188109-0.1372037 ] [-0.001542060.3311751-0.09344029] [-0.120184910.21488001-0.11760133] [-0.004390050.19535081-0.15915072]] ###Testontheisotropicaveragecomputation: assert(ND_GCN[0,0] ==ND_GNN[0,0] *D_rec[0,0])
度向量的每个元素代表i节点的度值。实际上,向量的第一个元素等于4,因为邻接矩阵显示4个节点连接到节点1。然后计算度数的倒数,以实现连接到节点的边的平均贡献。最后,根据GCN公式进行各向同性平均计算。使用节点1度执行平均计算的节点1的更新表示等于:
[ 0.112895610.17079077-0.09532007]
通过将以下向量(表示节点1的聚合表示)乘以其度数的倒数(0.25),可以得到此向量:
[ 0.451582440.68316307-0.3812803 ]
本节中描述的代码可以通过数学形式化如下:
描述GCN层执行的各向同性平均聚合的函数。U是投影步长的结果,deg是中心节点的度数。N是其邻居数