作为深度学习与图数据结合的代表性方法,GCN的出现带动了将神经网络技术运用于图数据的学习任务中去的一大类方法,为了给出一个涵盖更广范围的定义,一般我们统称这类方法为图神经网络,即Graph Neural Networks(GNN)[0] 。
在之前的章节我们提到从空域视角看GCN,本质上就是一个迭代式的聚合邻居的过程,这启发了一大类模型对于这种聚合操作的重新设计,这些设计在某方面大大加强了GNN对于图数据的适应性。基于对这些设计的结构,一些GNN的通用表达框架也相继被提出,这些框架从更加统一的层面抽象出了GNN的一般表达方式,为GNN的模型设计工作提供了统一范式。
在本章中,我们就上述两个方面的内容进行讲解来加强对GNN的认识。本章的前三节分别介绍了3中GNN的典型变体模型。在3.4节,我们同时介绍了3中GNN的通用表达框架。3.5节针对GraphSAGE模型,准备了相应的实战内容。
本节介绍的GraphSAGE[1]从两个方面对GCN做了改动,一方面是通过采样邻居的策略将GCN由全图(full batch)的训练方式改造已节点为中心的小批量(mini batch)训练方式,这使得大规模图数据的分布式训练成为可能; 另一方面是该算法对聚合邻居的操作进行了拓展,提出了替换GCN操作的集中新的方式。
在之前的GCN模型中,训练方式是一种全图形式,也就是一轮迭代,所有节点样本的损失只会贡献一次梯度数据,无法做到DNN中通常用到的小批量式更新,这从梯度更新的次数而言,效率是很低的。另外,对于很多实际的业务场景数据而言,图的规模往往是十分巨大的,单张显卡的显存容量很难达到一整张图训练时所需的空间,为此采用小批量的训练方法对大规模图数据的训练进行分布式拓展是十分必要的。GraphSAGE从聚合邻居的操作出发,对邻居进行随机采样来控制实际运算时节点k节子图的数据规模,在此基础上对采样的子图进行随机组合来完成小批量式的训练。
在GCN模型中,我们知道节点在第 ( k + 1 ) (k+1) (k+1) 层的特征只与其邻居在k层的特征有关,这种局部性质使得节点在第k层的特征只与自己的 k k k 阶子图有关。对于图3-1中的中心节点(橙色节点),假设GCN模型的层数为 2 2 2 ,若想得到其第2层特征,图中所有的节点都需要参与计算。
虽然根据上述阐述,我们只需要考虑节点的 k k k 阶子图就可以完成对节点高层特征的计算,但是对于一个大规模的图数据来说,我们直接将此思路迁移过来仍然存在以下两个问题:
(1)子图的节点数存在呈指数级增长的问题。假设图中节点度的均值为 d ˉ \bar{d} dˉ ,执行 k k k 层GCN,则 k k k 阶子图平均出现 1 + d ˉ + d ˉ 2 + ⋯ + d ˉ k 1+\bar{d}+\bar{d}^2+⋯+\bar{d}^k 1+dˉ+dˉ2+⋯+dˉk 个节点,如果 d ˉ = 10 \bar{d}=10 dˉ=10 , k = 4 k=4 k=4 ,那么就有 11111 11111 11111 个节点要参与计算,这会导致很高的计算复杂度。
(2)真实世界中图数据节点的度往往呈现幂律分布,一些节点的度会非常大,我们称这样的节点为超级节点,在很多图计算的问题中,超级节点都是比较难处理的对象。在这里,由于超级节点本身邻居的树木就很大,再加上子图节点数呈指数级增长的问题,这种类型节点高层特征计算的代价会变得更加高昂。
对于上述两种情况的出现,遍历子图的时间代价、模型训练的计算代价与存储代价都会变得十分不可控。为此,GraphSAGE使用了非常自然地采样邻居的操作来控制子图发散时的增长率。具体做法如下:设每个节点在第 k k k 层的邻居采样倍率为 S k S_k Sk(该参数为GraphSAGE算法的超参数,由用户自行设计与调节),即每个节点采样的一阶邻居总数不超过 S k S_k Sk,那么对于任意一个中心节点的表达计算,所涉及的总结点数将在 O ( ∏ k = 1 K S k ) O(∏_{k=1}^KS_k ) O(∏k=1KSk) 这个级别。对于任意一个两层的模型来说,如果设 S 1 = 3 S_1=3 S1=3, S 2 = 2 S_2=2 S2=2,则总的节点数不会超过 1 + 3 + 3 × 2 = 10 1+3+3×2=10 1+3+3×2=10 个。这里对节点采样,GraphSAGE选择了均匀分布,事实上根据工程效率或者数据的业务背景,我们可以采用其他形式的分布来替代均匀分布 [2] [3] [4] 。
GraphSAGE通过采样邻居的策略,使得子图节点的规模始终维持在阶乘级别以下,同时也从工程上给模型层数的增加节省出了相应空间。
3.1.1 参考文献:
[1] Hamilton W , Ying Z , Leskovec J.Inductive representation learning on large graphs[C]//Advances in Neural Information Processing Systems.2017:1024-1034.
[2] Chen J,Ma T,Xiao C.Fastgcn:fast learning with graph convolutional networks via importance sampling[J].arXiv preprint arXiv:1801.10247,2018.
[3] Huang W,Zhang T,Rong Y,et al.Adaptive sampling towards fast graph representation learning[C]//Advances in Neural Information Processing Systems.2018:4558-4567.
[4] Chen J,Zhu J,Song L.Stochastic training of graph convolutional networks with variance reduction[J].arXiv preprint arXiv:1710.10568,2017.
GraphSAGE研究了聚合邻居操作所需的性质,并且提出了几种新的的聚合操作(aggregator),需满足如下条件:
(1)聚合操作必须要对聚合节点的数量做到自适应。不管节点的邻居数量怎么变化,进行局和操作后输出的维度必须是一致的,一般是一个统一的长度的向量。
(2)聚合操作对聚合节点具有排列不变性。对于我们熟知的2D图像数据与1D序列数据,前者包含着空间顺序,后者包含着时序顺序,但图数据本身是一种无序的数据结构,对于聚合操作而言,这就要求不管邻居节点的排列顺序如何,输出的结果总是一样的。比如 Agg ( v 1 , v 2 ) = Agg ( v 2 , v 1 ) \text{Agg}(v_1,v_2 )=\text{Agg}(v_2,v_1 ) Agg(v1,v2)=Agg(v2,v1) 。
当然,从模型优化的层面来看,该种聚合操作还必须是可导的。有了上述性质的保证,聚合操作就能对任意输入的节点集合做到自适应。比较简单的符合这些性质的操作算子有:
(1)平均/加和(mean/sum)聚合算子。逐元素的求和与取均值是最直接的一种聚合算子,这类操作是GCN中图卷积操作的线性近似,下面给出了求和的聚合公式,W和b是聚合操作的学习参数:
Agg^sum=σ(SUM{Wh_j+b,∀v_j∈N(v_i)})
(2)池化(pooling)聚合算子。该算子借鉴了CNN里的池化操作来做聚合,常见的如最大池化操作,即逐元素取最大值:
Agg^pool=MAX{σ(Wh_j+b,∀v_j∈N(v_i)}
原则上我们可以套用任意一种DNN模型对邻居进行最大池化操作之前的特征变换,在上面的例子中,选用了最简单的单层全连接网络对节点的特征进行加工学习。
在了解了上述两个机制之后,我们来看看GraphSAGE实现小批量训练形式的具体过程。
输入:图 G = ( V , E ) G=(V,E) G=(V,E);输入特征 { x v , ∀ v ∈ B } \{x_v,∀v∈B\} {xv,∀v∈B};层数 K K K;权重矩阵 W ( k ) W^{(k)} W(k), ∀ k ∈ { 1 , … , K } ∀k∈\{1,…,K\} ∀k∈{1,…,K};非线性函数 σ σ σ;聚合操作 Agg ( k ) \text{Agg}^{(k)} Agg(k), ∀ k ∈ { 1 , … , K } ∀k∈\{1,…,K\} ∀k∈{1,…,K};邻居采样函数 N ( k ) N^{(k)} N(k) : : : v → 2 v v→2^v v→2v , ∀ k ∈ { 1 , … , K } ∀k∈\{1,…,K\} ∀k∈{1,…,K} 。
输出:所有节点的向量表示 z v z_v zv , v ∈ B v∈B v∈B 。
上述代码清单所示的算法的基本思路是先将小批集合 B B B 内的中心节点聚合操作所要涉及的 k k k 阶子图一次性全部遍历出来,然后在这些节点上进行 K K K 次聚合操作的迭代式计算。算法的第 1 ∼ 7 1\sim7 1∼7 行就是描述遍历操作的。我们可以这样来理解这个过程:要想得到某个中心节点第 k k k 层的特征,就需要采样其在第 ( k − 1 ) (k-1) (k−1) 层的邻居,然后对第 ( k − 1 ) (k-1) (k−1) 层的每个节点采样其第 ( k − 2 ) (k-2) (k−2) 层的邻居,以此类推,直到采样完第 1 1 1 层的所有邻居位置。需要注意的是,每层的采样函数可以单独设置,具体可以参考本节采样邻居部分的内容。
代码清淡的第 9 ∼ 15 9\sim15 9∼15 行是第二步——聚合操作,其核心体现在第 11 ∼ 13 11\sim13 11∼13 行的3个公式上面。第11行的式子是调用聚合操作完成对每个节点邻居特征的整合输出,第 12 12 12 行是将聚合后的邻居特征与中心节点上一层的特征进行拼接,然后送到一个单层网络里面得到中心节点新的特征向量,第 13 13 13 行对节点的特征向量进行归一化处理,将所有节点的向量都统一到单位尺度上。对这 3 行操作迭代 K K K 次就完成了对B内所有中心节点特征向量的提取。
值得一提的是,GraphSAGE算法的计算过程完全没有拉普拉斯矩阵的参与,每个节点的特征学习过程仅仅只与其k阶邻居相关,而不需要考虑全图的结构信息,这样的方法适合做归纳学习(Inductive Learning)。归纳学习是指可以对在训练阶段见不到的数据(在图数据中,可以指新的节点,也可以指新的图)直接进行预测而不需要重新训练的学习方法,与之相对的是转导学习(Transductive Learning),指所有的数据在训练阶段都可以拿到,学习过程是作用在这个固定的数据上的,一旦数据发生改变,需要重新进行学习训练,典型的比如图上的随机游走算法,一旦图数据发生变动,所有节点的表示学习都需要重新进行。对于GraphSAGE算法而言,对于新出现的节点数据,只需要遍历得到 k k k 阶子图,就可以带入模型进行相关预测。这种特性使得该算法具有十分巨大的应用价值。
总结一下,GraphSAGE对空域视角下的GCN作了一次解构,提出了集中邻居的聚合操作算子,同时通过采样邻居,大大提升了算法的工程价值。在引文 [5] 中,通过该方法完成了对工业级大规模推荐系统的应用,且效果十分显著。
3.1.3参考文献:
[5] Ying R,He R,Chen K,et al.Graph convolutional neural networks for web-scale recommender systems[C]//Proceedings of the 24th ACM SIGKDD International Conference on Knowledge Discovery&Data Mining.ACM,2018:974- 983.
[0] 刘忠雨, 李彦霖, 周洋.《深入浅出图神经网络: GNN原理解析》.机械工业出版社.