之前承诺要写一个关于graph network的介绍,因为随着deep learning的发展达到一个很高的水平,reasoning(推理)能力的具备变得异常迫切。而knowledge graph则是实现reasoning的重要途径之一,如何从复杂的graph中学习到潜在的知识是一项非常challenging的任务,图作为knowledge的存储媒介,deep learning作为信息抽取的重要工具,二者的结合可谓是必然趋势。下面我将结合之前看过的一篇国外的博客,为大家入门graph neural network抛一块砖。
在开始之前,多说几句,关于graph和deep learning结合的工作,想必大家都能猜到名字该怎么取,无非是这几个关键词的组合:Graph,Neural,Network,Convolution…所以,许多工作从paper名字来看并没有多大的区分性。
现实世界许多数据都是以graph的形式存储的,比如social networks(社交网络), knowledge graphs(知识图谱), protein-interaction networks(蛋白质相互作用网络), the World Wide Web(万维网),最近有一些研究者把目光投向建立一种通用的神经网络模型来处理graph数据。在此之前,该领域的主流方法是一些基于kernel的方法或基于graph的正则化技术,不过从deep learning的角度来讲,这些已经属于“传统方法”了,不是我们要讨论的主题,不了解也没有关系。
由于大家的思想普遍是如何将CNN等神经网络的思想迁移到graph上,所以往往设计出来的结构都有一定的共性,使用类似convolution权重共享的思想,我们可以把这类网络暂且都称作Graph Convolutional Networks(GCNs)。这类网络从数学上来看,是想学习 G = ( V , E ) G=(V, E) G=(V,E)上的一个函数,该函数的输入是:
该函数产生一个node-level的输出 Z Z Z(是一个 N × F N×F N×F的矩阵, N N N代表节点数量,每一行代表一个节点, F F F代表节点特征向量的维度)。如果想要得到graph-level的特征表达,只需要将每一个node的表达综合起来再经过一个映射操作即可。
和卷积神经网络一样,对于graph的特征提取我们同样可以使用多层神经网络结构,对于每一层,我们可以使用如下的映射函数来计算:
f ( H ( l ) , A ) = f ( H ( l ) , A ) f(H^{(l)},A)=f(H^{(l)},A) f(H(l),A)=f(H(l),A)
其中 H ( l ) ∈ R N × d ( l ) H^{(l)}{\in}R^{N×d^{(l)}} H(l)∈RN×d(l)表示第 l l l层graph的node-level表达,是一个 N × d ( l ) N×d^{(l)} N×d(l)维的矩阵, N N N代表node数量, d ( l ) d^{(l)} d(l)代表第 l l l层节点表达的维度(节点表达的维度可以在每一层都不一样,由 f f f决定,可以灵活设置,详见下节例子); H ( 0 ) = X H^{(0)}=X H(0)=X表示第0层的初始化节点表达矩阵;假设一共有 L L L层网络,则 H ( L ) = Z H^{(L)}=Z H(L)=Z表示最后一层输出的节点表达矩阵(上一段已经说了 H ∈ R N × F H{\in}R^{N×F} H∈RN×F, F F F表示最后一层节点的特征向量维度)。
针对上一节提到的层间的映射函数 f f f,我们可以采用如下式的方式实现:
f ( H ( l ) , A ) = σ ( A H ( l ) W ( l ) ) f(H^{(l)},A)=\sigma(AH^{(l)}W^{(l)}) f(H(l),A)=σ(AH(l)W(l))
这里 A ∈ R N × N A{\in}R^{N×N} A∈RN×N, H ( l ) ∈ R N × d ( l ) H^{(l)}{\in}R^{N×d^{(l)}} H(l)∈RN×d(l), W ( l ) ∈ R d ( l ) × d ( l + 1 ) W{(l){\in}R^{d^{(l)}×d^{(l+1)}}} W(l)∈Rd(l)×d(l+1), σ \sigma σ是非线性激活函数。这里简单解释一下这么做的物理意义,首先,邻接矩阵 A A A与 H ( l ) H^{(l)} H(l)相乘的作用是使节点的邻接节点值求和聚集到该节点上,为了不丢失该节点本来的信息,我们往往会强制每一个节点到自己也有一个连接,即一个self-loop,相当于让邻接矩阵 A A A加上一个单位矩阵 I I I,则上式变成如下形式。
f ( H ( l ) , A ) = σ [ ( A + I ) H ( l ) W ( l ) ] f(H^{(l)},A)=\sigma[(A+I)H^{(l)}W^{(l)}] f(H(l),A)=σ[(A+I)H(l)W(l)]
尽管该模型看着很简单,但实际上已经非常powerful了,不过我们还是可以力所能及的对模型做一些改进,使模型发挥更大的效能。首先,邻接矩阵 A + I A+I A+I并没有归一化,这样会导致每经过一次相乘节点特征的尺度就会变大,这样我们可以进一步将公式变为如下形式:
f ( H ( l ) , A ) = σ [ D − 1 / 2 ( A + I ) D − 1 / 2 H ( l ) W ( l ) ] f(H^{(l)},A)=\sigma[D^{-1/2}(A+I)D^{-1/2}H^{(l)}W^{(l)}] f(H(l),A)=σ[D−1/2(A+I)D−1/2H(l)W(l)]
这样,本质上我们就实现了Kipf & Welling (ICLR 2017)中设计的传播模型。
本节我们利用上面介绍的模型实现一个分类问题。首先大家可以先看一下Zachary’s karate club network数据集以及它的背景,该数据集可以以下图的形式呈现,简单介绍的话就是说一个空手道俱乐部内部出现矛盾要被拆分为两波人,我们需要依据队员们平时的交往关系来判断他们会站哪一支队伍,图中每个节点表示一个队员,若两个节点之间存在边,则表示对应两个队员之间关系密切。下图使用clustering做个一个简单的划分,仅做参考,颜色相同的表示最后分在一组(这里作者貌似没有分为2类,而是4类)。
这里使用上述介绍的模型对每个node做embedding(这里网络设置为3层,使用了半监督,具体可以看原文Kipf & Welling ,不过大可以当做有监督来看),embedding后的效果就是同一组特征在空间上距离相近,下面的video展示了embedding的过程,效果还是相当明显的:
width="560" height="315" src="https://youtu.be/EuK4L61JmcQ" allowfullscreen="">显示不了的话可移步https://youtu.be/EuK4L61JmcQ观看
我们发现一个很有意思的现象,就是当我们还没有开始训练,仅仅是随机初始化上述模型的参数之后,也产生了一定的embedding效果,如下图所示:
近期一个叫DeepWalk (Perozzi et al., KDD 2014)的工作表明他们可以使用无监督的方式产生一个相似的embedding效果,这听起来挺不可思议的,我们试图从Weisfeiler-Lehman算法的角度来解释,并把GCNs看做该算法的通用、可微版。
其实下面的部分可看可不看,因为我并没与觉得作者的解释有多少说服力,感兴趣的可以看一下原文。
之前做过一个PPT,也简单的介绍了一下三种graph neural network,需要的可以点击这里浏览一下。
由于水平所限,可能文中很多地方解释的不好,欢迎大家批评指正,相互进步,谢谢~
http://tkipf.github.io/graph-convolutional-networks/