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(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(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(Xl,A)=δ(D^12A^D^12X(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)})

  • XX是所有節點的特徵向量構成的特徵矩陣(每一行表示一個節點的特徵);
  • X(l)X^{(l)}X(l+1)X^{(l+1)}分別是ll層的輸入和輸出矩陣,X(l)X^{(l)}代表第ll層對應節點的embedding;
  • AA是Graph的鄰接矩陣;
  • A^=A+IN\hat A=A+I_N是帶有自環的無向圖的鄰接矩陣;
  • D^ii=jA^ij\hat D_{ii}=\sum_{j}\hat A_{ij}是度量矩陣;
  • W(l)W^{(l)}是一個可訓練權重矩陣或參數矩陣;
  • δ()\delta(\cdot)是激活函數,如ReLU等。

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

損失函數
L=1YLiYLLoss(yi,ziL), \mathcal{L}=\frac{1}{|\mathcal{Y}_\mathcal L|\sum_{i\in \mathcal{Y}_\mathcal L}}\text{Loss}(y_i,z^L_i),

  • YL\mathcal{Y}_\mathcal L是部分有標籤的節點的標籤;
  • ziLz^L_i是ground-truth標籤爲yiy_iZLZ^L的第ii行,表示節點ii的最終預測;
  • Cross-Entropy Loss。

Cluster-GCN

batch_size=B|\mathcal{B}|表示一個batch的節點,使用基於mini-batch的SGD:
1BiBLoss(yi,ziL), \frac{1}{|\mathcal{B}|}\sum_{i\in \mathcal B}\nabla\text{Loss}(y_i,z^L_i),
需要注意的是,儘管基於mini-batch的SGD在每個epoch收斂得更快,但由於引入了另一個計算開銷,所以比Full Gradient Descent要慢。

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

考慮計算一個節點ii相關的梯度:Loss(yi,ziL)\nabla\text{Loss}(y_i,z^L_i)。顯然,需要存儲節點ii的embedding,而節點ii的embedding的計算依賴於,L1L-1層的鄰居節點的embeddings。**假設一個LL層的GCN網絡,每個節點的平均度數爲dd,爲了獲得節點ii的相關梯度,需要對Graph中的一個節點聚合O(dL)O(d^L)個節點的特徵。**換句話說,需要獲取Graph中節點的hopk(k=1,,L)hop-k(k=1,\dots,L)鄰居節點的信息來執行一次更新。

Embedding utilization can reflect computational efficiency

嵌入利用率用來反應計算效率。

如果節點ii在第ll層得embedding:zi(l)z^{(l)}_i,在計算第l+1l+1層得embeddings時被重複使用了uu次,那麼zi(l)z^{(l)}_i的嵌入利用率就是uu

爲了使mini-batch SGD工作,以前的方法試圖限制鄰域擴展的數量,但是這並沒有提高嵌入使用率。

  • GraphSAGE使用一個固定大小的均勻採樣來確定鄰居節點集,而不是使用一個完整的鄰域集合;
  • FastGCN提出了一種改進梯度估計的重要採樣策略;
  • VR-GCN提出了一種策略來存儲所有NN個節點和LL層在先前計算的embedding,並對未採樣的鄰居節點重複利用。

Vanilla Cluster-GCN

在mini-batch SGD更新中,嘗試設計一個batch和相應的計算sub-graph來最大限度地提高embedding utilization。Cluste-GCN通過將embedding utilization連接到一個聚類目標上來實現。

對於一個Graph:G\mathcal G,把節點分成cc個組:V=[V1,,Vc]V=[V_1,\dots,V_c],這樣就會得到cc個sub-graph:
G=[G1,,Gc]=[{V1,E1},,{Vc,Ec}] \overline G=[G_1,\dots,G_c ]=[\{V_1,E_1\},\dots,\{V_c,E_c\}]

  • 每個EtE_t只包含在VtV_t中的節點之間的邊;

    對節點進行重組後,鄰接矩陣被劃分爲c2c^2個子矩陣:
    KaTeX parse error: Undefined control sequence: \label at position 142: …x} \right] \̲l̲a̲b̲e̲l̲{eq:a}
    其中
    Aˉ=[A1100Acc]Δ=[0A1cAc10] \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]

  • 對角塊AttA_{tt}是一個包含的邊在sub-graphGtG_tVt×Vt|V_t|\times|V_t|維的鄰接矩陣;

  • Aˉ\bar AGˉ\bar G的鄰接矩陣;

  • AstA_{st}包含了兩個部分VsV_sVtV_t之間的邊;

  • Δ\Delta是由AA的所有非對角塊組成的矩陣。

類似的,將特徵矩陣XX和訓練矩陣YY根據區分[V1,,Vc][V_1,\dots,V_c]分組爲[X1,,Xc][X_1,\dots,X_c][Y1,,Yc][Y_1,\dots,Y_c]

塊對角近似的好處是GCN的目標函數可以分解成不同的batches(clusters)。設Aˉ\bar{A^{'}}Aˉ\bar A的歸一化版本,則最終embedding矩陣由Aˉ\bar A的塊對角形式變成(Attˉ\bar{A^{'}_{tt}}Aˉ\bar{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}中的分解形式。**在每一步中,對一個聚類VtV_t進行採樣,然後根據LAˉ\mathcal L_{\bar{A^{'}}}的梯度進行SGD更新,**這隻需要當前batch上的sub-graphAttXt,YtA_{tt},X_t,Y_t和模型{W(l)}lL\{W^{(l)}\}^L_l

Cluster-GCN使用了Graph聚類算法來劃分Graph。Graph聚類的方法,如metis和graclus等,旨在在Graph中的頂點上構建分區,使得簇內連接遠大於簇間連接,從而更好的捕捉聚類和區分結構。

  • embedding utilization相當於每個batch的簇內的連接。每個節點及其相鄰節點通常位於同一個簇中,因此經過幾次跳躍後,高概率的鄰域節點仍然位於同一個簇中;
  • 由於使用AA的對角近似Aˉ\bar A取代AA,並且誤差和簇間的連接成正比,所以要找到一種分區方法最小化簇間連接的數量。
    在這裏插入圖片描述
    在上圖中,全圖GG和聚類分區圖Gˉ\bar G來進行鄰域展開,如右邊所示,Cluster-GCN可以避免大量的鄰域搜索,而集中在每個簇中的鄰居上。

Time and Space complexity

由於在分區VtV_t中的節點,只連接VtV_t中的節點,所以每個節點不需要再AttA_{tt}外部執行鄰居搜索。對每個batch的計算將很純粹的只是AttˉX(l)W(l)\bar{A_{tt}^{'}}X^{(l)}W^{(l)}的矩陣乘積和一些element-wise的操作,時間複雜度低。並且每個batch只需要計算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值把圖分割爲V1,,VpV_1,\dots,V_p,然後對於SGD更新重新構建一個batch BB,而不是隻考慮一個簇。隨機的選擇q個簇:t1,,tqt_1,\dots,t_q,並把它們的節點Vt1VtqV_{t_1}\cup\dots\cup V_{t_q}包含在這個batch BB中。此外,在選擇的簇之間的連接:
Aiji,jt1,,tq A_{ij}|i,j\in t_1,\dots,t_q
被添加回去。這樣,簇間的連接會被重新合併,使得batch之間的差異更小。

Issues of training deeper GCN

類似與Resnet的跳接:
Z(l+1)=AX(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)}
本文通過放大每個GCN層中使用的鄰接矩陣AA的對角部分,實現在每個GCN層的聚合中對上一層的表示施加更多的權重,如將單位矩陣添加到Aˉ\bar 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)})
進而提出對角增強(diagonal enhancement)

  1. 首先向原始AA添加一個單位矩陣,然後標準化:
    A~=(D+I)1(A+I) \tilde 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)})

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。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章