Cluster-GCN阅读笔记

Abstract

大规模GCN的训练:目前基于SGD的gcn算法,1)面临随着gcn层数增长,计算复杂度呈指数增长;2)需要保存整个Graph和每个node的embedding,存储量巨大。

本文提出了一种基于Graph聚类结构结构,且基于SGD训练的GCN算法:Cluster-GCN。在每一个步骤中,Cluster-GCN通过graph聚类算法来筛选联系紧密的sub-graph,从而在sub-graph中的一组node进行采样,并且限制该sub-graph中的邻居搜索,可以显著提高搜索效率。

在Amazon2M数据集:200万个node,6100万个边,比Reddit大五倍,实验了三层四层gcn。

Introduction

**对于Graph,GCN网络通过Graph Convolutional Neural逐层地获取节点的embedding:在每一层的每一个节点的embedding,需要采集下一层相邻节点的embedding进行激活。最后一层的embedding将用于一些最终任务。**例如在Graph Classification中,最后一层embedding被输入到分类器(如softmax)来预测各个节点的标签。

需要注意地是,由于GCN运算需要利用graph中节点之间地交互来学习更新embedding,这使得GCN的训练非常有挑战性。与cnn等网络不同,训练loss可以完美地分解为每个样本单独影响(decomposed into individual terms),GCN的损失函数必须依赖大量的其他节点。特别是GCN变深时,由于这种节点依赖,GCN的训练变得非常慢–反向传播时需要计算Graph上的所有embedding。

Previous GCN Training Algorithm

1、 GCN开山之作:Semi-Supervised Classification with Graph Convolutional Networks,应用全批次梯度下降法(Full-batch Gradient Descent),需要计算整个梯度,存储所有节点的embeddings,导致 O ( N F L ) O(NFL) O(NFL)内存需求。由于每个epoch只更新一次参数,梯度下降的收敛速度非常慢。

2、Graph-SAGE:Inductive Representation Learning on Large Graphs,提出了mini-batch SGD。由于每次更新参数仅仅基于一个batch的梯度,大大降低了内存需求,并且可以在每个epoch执行多次更新,从而加快了收敛速度。Graph-SAGE存在节点邻居扩展问题,需要计算节点的邻居节点在L-1层的embeddings,而这些邻居节点又需要求在L-2层的embeddings,周而复始,这导致大量的计算复杂度。Graph-SAGE同过在各层的反向传播过程中固定大小的邻居节点,降低了复杂度。

3、VR-GCN采用减小Variance方法来减小邻域采样节点的大小。尽管成功地减小了采样大小,但仍然需要将所有节点的中间embedding,导致 O ( N F L ) O(NFL) O(NFL)的内存需求。如果节点数量增加到数百万个,那么对于内存要求过高。

本文利用Graph的聚类结构,目的是划分节点的分区,使同一分区中的节点之间sub-Graph的链接,比不同分区更多。一个mini-batch算法的效率,由embedding utilization(嵌入利用率)来描述:与一个batch或者within-batch的节点之间的链接数量成正比。

  • Cluster-GCN在大型Graph上实现了最好的内存使用,特别是在deep GCN上;
  • 对于浅层网络(2层),Cluster-GCN可以达到与VR-GCN类似的训练速度。但当网络加深时(4层),可以比VR-GCN更快。这是因为Cluster-GCN的复杂度与网络层数L成线性关系,而VR-GCN时指数关系。
  • Cluster-GCN能够训练一个非常深且极大规模的网络。

Bachground

Graph Convolutional Neural

GCN中的每一层通过考虑相邻节点的embedding,来更新Graph中的每个节点的特征向量表示。具体来说,GCN的逐层正向传播可以总结为:
X ( l + 1 ) = f ( X l , A ) = δ ( D ^ − 1 2 A ^ D ^ − 1 2 X ( l ) W ( l ) ) X^{(l+1)}=f(X^l,A)=\delta(\hat D^{-\frac{1}{2}}\hat A\hat D^{-\frac{1}{2}}X^{(l)}W^{(l)}) X(l+1)=f(Xl,A)=δ(D^21A^D^21X(l)W(l))

  • X X X是所有节点的特征向量构成的特征矩阵(每一行表示一个节点的特征);
  • X ( l ) X^{(l)} X(l) X ( l + 1 ) X^{(l+1)} X(l+1)分别是 l l l层的输入和输出矩阵, X ( l ) X^{(l)} X(l)代表第 l l l层对应节点的embedding;
  • A A A是Graph的邻接矩阵;
  • A ^ = A + I N \hat A=A+I_N A^=A+IN是带有自环的无向图的邻接矩阵;
  • D ^ i i = ∑ j A ^ i j \hat D_{ii}=\sum_{j}\hat A_{ij} D^ii=jA^ij是度量矩阵;
  • W ( l ) W^{(l)} W(l)是一个可训练权重矩阵或参数矩阵;
  • δ ( ⋅ ) \delta(\cdot) δ()是激活函数,如ReLU等。

Z ( l + 1 ) = A ′ X ( l ) W ( l ) , X ( l + 1 ) = δ ( Z ( l + 1 ) ) . Z^{(l+1)}=A^{'}X^{(l)}W^{(l)},\\ X^{(l+1)}=\delta(Z^{(l+1)}). Z(l+1)=AX(l)W(l),X(l+1)=δ(Z(l+1)).

损失函数
L = 1 ∣ Y L ∣ ∑ i ∈ Y L Loss ( y i , z i L ) , \mathcal{L}=\frac{1}{|\mathcal{Y}_\mathcal L|\sum_{i\in \mathcal{Y}_\mathcal L}}\text{Loss}(y_i,z^L_i), L=YLiYL1Loss(yi,ziL),

  • Y L \mathcal{Y}_\mathcal L YL是部分有标签的节点的标签;
  • z i L z^L_i ziL是ground-truth标签为 y i y_i yi Z L Z^L ZL的第 i i i行,表示节点 i i i的最终预测;
  • Cross-Entropy Loss。

Cluster-GCN

batch_size= ∣ B ∣ |\mathcal{B}| B表示一个batch的节点,使用基于mini-batch的SGD:
1 ∣ B ∣ ∑ i ∈ B ∇ Loss ( y i , z i L ) , \frac{1}{|\mathcal{B}|}\sum_{i\in \mathcal B}\nabla\text{Loss}(y_i,z^L_i), B1iBLoss(yi,ziL),
需要注意的是,尽管基于mini-batch的SGD在每个epoch收敛得更快,但由于引入了另一个计算开销,所以比Full Gradient Descent要慢。

Why does vanilla mini-batch SGD have slow per-epoch time?

考虑计算一个节点 i i i相关的梯度: ∇ Loss ( y i , z i L ) \nabla\text{Loss}(y_i,z^L_i) Loss(yi,ziL)。显然,需要存储节点 i i i的embedding,而节点 i i i的embedding的计算依赖于, L − 1 L-1 L1层的邻居节点的embeddings。**假设一个 L L L层的GCN网络,每个节点的平均度数为 d d d,为了获得节点 i i i的相关梯度,需要对Graph中的一个节点聚合 O ( d L ) O(d^L) O(dL)个节点的特征。**换句话说,需要获取Graph中节点的 h o p − k ( k = 1 , … , L ) hop-k(k=1,\dots,L) hopk(k=1,,L)邻居节点的信息来执行一次更新。

Embedding utilization can reflect computational efficiency

嵌入利用率用来反应计算效率。

如果节点 i i i在第 l l l层得embedding: z i ( l ) z^{(l)}_i zi(l),在计算第 l + 1 l+1 l+1层得embeddings时被重复使用了 u u u次,那么 z i ( l ) z^{(l)}_i zi(l)的嵌入利用率就是 u u u

为了使mini-batch SGD工作,以前的方法试图限制邻域扩展的数量,但是这并没有提高嵌入使用率。

  • GraphSAGE使用一个固定大小的均匀采样来确定邻居节点集,而不是使用一个完整的邻域集合;
  • FastGCN提出了一种改进梯度估计的重要采样策略;
  • VR-GCN提出了一种策略来存储所有 N N N个节点和 L L L层在先前计算的embedding,并对未采样的邻居节点重复利用。

Vanilla Cluster-GCN

在mini-batch SGD更新中,尝试设计一个batch和相应的计算sub-graph来最大限度地提高embedding utilization。Cluste-GCN通过将embedding utilization连接到一个聚类目标上来实现。

对于一个Graph: G \mathcal G G,把节点分成 c c c个组: V = [ V 1 , … , V c ] V=[V_1,\dots,V_c] V=[V1,,Vc],这样就会得到 c c c个sub-graph:
G ‾ = [ G 1 , … , G c ] = [ { V 1 , E 1 } , … , { V c , E c } ] \overline G=[G_1,\dots,G_c ]=[\{V_1,E_1\},\dots,\{V_c,E_c\}] G=[G1,,Gc]=[{V1,E1},,{Vc,Ec}]

  • 每个 E t E_t Et只包含在 V t V_t Vt中的节点之间的边;

    对节点进行重组后,邻接矩阵被划分为 c 2 c^2 c2个子矩阵:
    KaTeX parse error: Undefined control sequence: \label at position 142: …x} \right] \̲l̲a̲b̲e̲l̲{eq:a}
    其中
    A ˉ = [ A 11 … 0 ⋮ ⋱ ⋮ 0 … A c c ] , Δ = [ 0 … A 1 c ⋮ ⋱ ⋮ A c 1 … 0 ] \bar A=\left[ \begin{matrix} A_{11}&\dots&0\\ \vdots&\ddots&\vdots\\ 0&\dots&A_{cc} \end{matrix} \right], \Delta=\left[ \begin{matrix} 0&\dots&A_{1c}\\ \vdots&\ddots&\vdots\\ A_{c1}&\dots&0 \end{matrix} \right] Aˉ=A1100AccΔ=0Ac1A1c0

  • 对角块 A t t A_{tt} Att是一个包含的边在sub-graph G t G_t Gt ∣ V t ∣ × ∣ V t ∣ |V_t|\times|V_t| Vt×Vt维的邻接矩阵;

  • A ˉ \bar A Aˉ G ˉ \bar G Gˉ的邻接矩阵;

  • A s t A_{st} Ast包含了两个部分 V s V_s Vs V t V_t Vt之间的边;

  • Δ \Delta Δ是由 A A A的所有非对角块组成的矩阵。

类似的,将特征矩阵 X X X和训练矩阵 Y Y Y根据区分 [ V 1 , … , V c ] [V_1,\dots,V_c] [V1,,Vc]分组为 [ X 1 , … , X c ] [X_1,\dots,X_c] [X1,,Xc] [ Y 1 , … , Y c ] [Y_1,\dots,Y_c] [Y1,,Yc]

块对角近似的好处是GCN的目标函数可以分解成不同的batches(clusters)。设 A ′ ˉ \bar{A^{'}} Aˉ A ˉ \bar A Aˉ的归一化版本,则最终embedding矩阵由 A ˉ \bar A Aˉ的块对角形式变成( A t t ′ ˉ \bar{A^{'}_{tt}} Attˉ A ′ ˉ \bar{A^{'}} Aˉ的块对角):
KaTeX parse error: No such environment: equation at position 8: \begin{̲e̲q̲u̲a̲t̲i̲o̲n̲}̲ \begin{aligned…
损失函数也被分解成:
KaTeX parse error: Undefined control sequence: \label at position 163: …ss}(y_i,x^L_i) \̲l̲a̲b̲e̲l̲{eq:step2}
然后Cluster-GCN基于公式KaTeX parse error: Undefined control sequence: \eqref at position 1: \̲e̲q̲r̲e̲f̲{eq:step1}KaTeX parse error: Undefined control sequence: \eqref at position 1: \̲e̲q̲r̲e̲f̲{eq:step2}中的分解形式。**在每一步中,对一个聚类 V t V_t Vt进行采样,然后根据 L A ′ ˉ \mathcal L_{\bar{A^{'}}} LAˉ的梯度进行SGD更新,**这只需要当前batch上的sub-graph A t t , X t , Y t A_{tt},X_t,Y_t AttXt,Yt和模型 { W ( l ) } l L \{W^{(l)}\}^L_l {W(l)}lL

Cluster-GCN使用了Graph聚类算法来划分Graph。Graph聚类的方法,如metis和graclus等,旨在在Graph中的顶点上构建分区,使得簇内连接远大于簇间连接,从而更好的捕捉聚类和区分结构。

  • embedding utilization相当于每个batch的簇内的连接。每个节点及其相邻节点通常位于同一个簇中,因此经过几次跳跃后,高概率的邻域节点仍然位于同一个簇中;
  • 由于使用 A A A的对角近似 A ˉ \bar A Aˉ取代 A A A,并且误差和簇间的连接成正比,所以要找到一种分区方法最小化簇间连接的数量。
    在这里插入图片描述
    在上图中,全图 G G G和聚类分区图 G ˉ \bar G Gˉ来进行邻域展开,如右边所示,Cluster-GCN可以避免大量的邻域搜索,而集中在每个簇中的邻居上。
Time and Space complexity

由于在分区 V t V_t Vt中的节点,只连接 V t V_t Vt中的节点,所以每个节点不需要再 A t t A_{tt} Att外部执行邻居搜索。对每个batch的计算将很纯粹的只是 A t t ′ ˉ X ( l ) W ( l ) \bar{A_{tt}^{'}}X^{(l)}W^{(l)} AttˉX(l)W(l)的矩阵乘积和一些element-wise的操作,时间复杂度低。并且每个batch只需要计算 O ( b L ) O(bL) O(bL)的embeddings,是线性的,存储要求也低。

在这里插入图片描述

Stochastic Multiple Partitions

Cluster-GCN实现了良好的计算和内存复杂性,却存在两个问题:

  • Graph被分割后,一些链接(等式KaTeX parse error: Undefined control sequence: \eqref at position 1: \̲e̲q̲r̲e̲f̲{eq:a}中的 Δ \Delta Δ部分)被删除。因此,性能可能会受影响。
  • 图聚类算法往往将相似的节点聚集在一起,因此聚类的分布可能不同于原始数据集,从而导致在执行SGD更新时对full gradient的估计有偏差。

随即多聚类方法,在簇与簇之间进行合并,减少batch间的差异(variance)。首先用一个较大的p值把图分割为 V 1 , … , V p V_1,\dots,V_p V1,,Vp,然后对于SGD更新重新构建一个batch B B B,而不是只考虑一个簇。随机的选择q个簇: t 1 , … , t q t_1,\dots,t_q t1,,tq,并把它们的节点 V t 1 ∪ ⋯ ∪ V t q V_{t_1}\cup\dots\cup V_{t_q} Vt1Vtq包含在这个batch B B B中。此外,在选择的簇之间的连接:
A i j ∣ i , j ∈ t 1 , … , t q A_{ij}|i,j\in t_1,\dots,t_q Aiji,jt1,,tq
被添加回去。这样,簇间的连接会被重新合并,使得batch之间的差异更小。

Issues of training deeper GCN

类似与Resnet的跳接:
Z ( l + 1 ) = A ′ X ( l ) W ( l ) , X ( l + 1 ) = δ ( Z ( l + 1 ) ) + X ( l ) Z^{(l+1)}=A'X^{(l)}W^{(l)},\\ X^{(l+1)}=\delta(Z^(l+1))+X^{(l)} Z(l+1)=AX(l)W(l),X(l+1)=δ(Z(l+1))+X(l)
本文通过放大每个GCN层中使用的邻接矩阵 A A A的对角部分,实现在每个GCN层的聚合中对上一层的表示施加更多的权重,如将单位矩阵添加到 A ˉ \bar A Aˉ中:
Z ( l + 1 ) = ( A ′ + I ) X ( l ) W ( l ) , X ( l + 1 ) = δ ( Z ( l + 1 ) ) , X ( l + 1 ) = δ ( ( A ′ + I ) X ( l ) W ( l ) ) Z^{(l+1)}=(A'+I)X^{(l)}W^{(l)},\\ X^{(l+1)}=\delta(Z^{(l+1)}),\\ X^{(l+1)}=\delta((A'+I)X^{(l)}W^{(l)}) Z(l+1)=(A+I)X(l)W(l),X(l+1)=δ(Z(l+1)),X(l+1)=δ((A+I)X(l)W(l))
进而提出对角增强(diagonal enhancement)

  1. 首先向原始 A A A添加一个单位矩阵,然后标准化:
    A ~ = ( D + I ) − 1 ( A + I ) \tilde A=(D+I)^{-1}(A+I) A~=(D+I)1(A+I)

  2. X ( l + 1 ) = δ ( ( A ~ + λ diag ( A ~ ) ) X ( l ) W ( l ) ) X^{(l+1)}=\delta((\tilde A+\lambda\text{diag}(\tilde A))X^{(l)}W^{(l)}) X(l+1)=δ((A~+λdiag(A~))X(l)W(l))

Experiment

Training Deeper GCN

多层GCNs,在下表中对比了Cluster-GCN和VRGCN:
在这里插入图片描述
对比发现,VRGCN由于其邻域查找的代价呈指数增长,而Cluster-GCN线性增长。

通过对Cluster-GCN的归一化方法,可以进行更深的训练,对于PPI数据集,Cluster-GCN可以通过训练一个包含2048个隐藏单元的5层GCN来达到最先进的效果。对于Reddit数据集,使用了一个包含128个隐藏单元的4层GCN。
在这里插入图片描述

Conclusion

此文提出了一种新的训练算法Cluster-GCN。实验结果表明,该方法可以在大型图上训练非常深的GCN,例如在一个超过200万个节点的图上,使用2G左右的内存训练时间不到1小时,精度达到90.41 (F1 score)。使用该方法,能够成功地训练更深入的GCNs,它可以在PPI数据集和Reddit数据集上获得最先进的测试F1 score。

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值