之前看GCN(Graph Convolutional Network)的时候总是一知半解、懵懵懂懂。在学习了GAT和GIN并深入阅读了源码后终于对GCN有了更进一步的了解。
意识流理解GCN
第一步:平均
这里我们可以同通过收集并平均你的neighbor的信息来提取信息:
a g g r e g a t r e ( X i ) = ∑ j ∈ n e i g h b o r ( i ) A i j X j aggregatre(X_i)=\sum_{j\in{neighbor(i)}}A_{ij}X_{j}aggregatre(Xi)=j∈neighbor(i)∑AijXj
第二步:加权平均
考虑到不同neighbor之间的重要性:
a g g r e g a t r e ( X ) = A X aggregatre(X)=AXaggregatre(X)=AX
这里我们将无权图改为有权图即可。
第三步:考虑自身因素
聚类一个Graph的时候往往要考虑自身feature的因素,所以,这里我们用一个单位矩阵实现:
a g g r e g a t r e ( X ) = ( A + I ) X = A X + X = aggregatre(X)=(A+I)X=AX+X=aggregatre(X)=(A+I)X=AX+X=
a g g r e g a t r e ( X i ) = ∑ j ∈ n e i g h b o r ( i ) A i j X j + X i aggregatre(X_i)=\sum_{j\in{neighbor(i)}}A_{ij}X_{j}+X_iaggregatre(Xi)=j∈neighbor(i)∑AijXj+Xi
通过展开式我们能够看出加上了自身的特征
第四步:差分
这里我们使用度矩阵D DD与邻接矩阵A AA做差分:
d i f f ( X ) = ( D − A ) X diff(X)=(D-A)Xdiff(X)=(D−A)X
第五步:归一化与对称归一化
这里我们令A ^ = A + I \hat{A}=A+IA^=A+I,D ^ \hat{D}D^为A ^ = A + I \hat{A}=A+IA^=A+I的度矩阵。通过D ^ − 1 \hat{D}^{-1}D^−1能够将求和变为加权平均(意识流理解,有空再写详细证明)。于是我们能够得到最终的GCN传播方式
H ( l + 1 ) = σ ( D ^ − 1 / 2 A ^ D ^ − 1 / 2 H l W ( l ) ) H^{(l+1)}=\sigma(\hat{D}^{-1/2}\hat{A}\hat{D}^{-1/2}H^{l}W^{(l)})H(l+1)=σ(D^−1/2A^D^−1/2HlW(l))
其中,σ \sigmaσ为非线性激活函数。
pyhton的代码实现为:
def _call(self, inputs):
x = inputs
x = tf.nn.dropout(x, 1 - self.dropout)
x = tf.matmul(x, self.vars['weights'])
x = tf.sparse_tensor_dense_matmul(self.adj, x)
outputs = self.act(x)
return outputs
注:之前就疑惑为什么传播公式里面的D ^ \hat{D}D^为什么不体现在code中,原来是因为数据集的不同,D ^ − 1 / 2 A ^ D ^ − 1 / 2 \hat{D}^{-1/2}\hat{A}\hat{D}^{-1/2}D^−1/2A^D^−1/2往往计算在内,这里的code只是书写形式罢辽。
读到这里,我也就能够明白为什么论文“HOW POWERFUL ARE GRAPH NEURAL NETWORKS?”中阐述GCN中AGGREGATE金额COMBINE步骤时用来MEAN来表示:

灵感来源
链接: 知乎大神:纵横.