GCN的一些理解
文章目录
零、背景
荣老师说了,一个程序员怎么能做到35岁不下岗,得不止会应用,还得了解算法的原理,比如搞RNN的得会写RNN,然后既然我要搞GNN,之前并不是很清楚其中的道理,那就看一下GNN的经典论文,因此我就看了我了解到的三篇比较经典写GCN的文章,分别是
Spectral Networks and Deep Locally Connected Networks on Graphs, 2013
[1]
Deep Convolutional Networks on Graph-Structured Data, 2015[2]
Convolutional Neural Networks on Graphs with Fast Localized Spectral Filtering, 2016
[3]
其中第一篇有人说的GCN的祖宗,第二篇有人说是GCN的祖宗,其实第二篇的作者和第一篇差不多,且第二篇引用了第一篇,两篇提出的GCN仅有一些细微的差别。第三篇则是相对改良了一些的GCN,这次我也打算三篇一起读,然后发现遇到了很大的困难,借助了两篇知乎的帖子[4,5]。
一、模型结构
我觉得第一篇和第二篇论文是劝退级别的,文中省略或者让读者自行了解了大量的重要数学内容,其中包含了在OI和ACM里恶心我五年了的傅里叶变换,使得最开始看得云里雾里,幸好有两篇知乎的文章给我讲解,让我稍微有了点理解,接着我就用我更好理解的思路来去讲GCN。
1.1 基本思想
我感觉理解了它大概在干啥讲原理能够讲得清楚一点,感觉包括[1]在内,会将GCN分为spectral和spatial的部分,可以翻译为谱上的和结构上的,我觉得看见谱这个词就很吓人,我感觉可以算是消息传递。而spatial就是将点逐步聚类,提取更宏观的联系。
1.2 谱的构建分析(消息传递部分)
y = U g θ ( Λ ) U T x y = Ug_\theta(\Lambda)U^{T}x y=Ugθ(Λ)UTx
我觉得这就是所谓的图卷积,也就是GCN最重要的部分。我感觉要是什么时候忘了的话,就记住其实只要学习 g θ ( Λ ) g_\theta(\Lambda) gθ(Λ)就行了,而这其实只是一个对角化的向量而已,通过这个 O ( k ) O(k) O(k)的向量对周边的信息进行聚合,而矩阵 U U U蕴含了图上其他节点的信息,后面会逐步解释他们的具体求法。然后自然会有两个问题,一个是为什么 U g θ ( Λ ) U T Ug_\theta(\Lambda)U^{T} Ugθ(Λ)UT能聚合周边的信息,一个是为什么只需要通过学习 g θ ( Λ ) g_\theta(\Lambda) gθ(Λ)就能进行聚合了呢,这对应了下面的两个问题,也就是拉普拉斯变换和图上的傅里叶变换。
1.2.1 拉普拉斯变换
1.2.1.1 拉普拉斯变换做了个什么
[4]这篇文章讲得非常好。我就拿他讲得作为一个例子。考虑图太复杂了,首先从链开始考虑,假设我们要建立一个链上的温度传导模型,如图1。
图
1
温
度
的
传
播
图\ 1\ 温度的传播
图 1 温度的传播
假设我们要考虑第
i
i
i个点下一时刻的温度,目前我们假定它只和两边的点的温度差有关系,那么
T
i
T_i
Ti 的更新公式为
∂
T
i
∂
t
=
k
{
(
T
i
+
1
−
T
i
)
+
(
T
i
−
1
−
T
i
)
}
\frac {\partial T_i} {\partial t} = k\{(T_{i+1}-T_i) + (T_{i-1}-T_i)\}
∂t∂Ti=k{(Ti+1−Ti)+(Ti−1−Ti)},简单变一下符号将加号变成负号就有
∂
T
i
∂
t
=
k
{
(
T
i
+
1
−
T
i
)
−
(
T
i
−
T
i
−
1
)
}
\frac {\partial T_i} {\partial t} = k\{(T_{i+1}-T_i) - (T_{i}-T_{i-1})\}
∂t∂Ti=k{(Ti+1−Ti)−(Ti−Ti−1)},注意大括号里面的项,其实是二阶导数的形式,即两个差再相减,因此能想到拉普拉斯了。
接着我们将这个温度传播的模型推广到更一般的图上,则有 ∂ T i ∂ t = − k ∑ j W i j ( T i − T j ) \frac{\partial T_i}{\partial t} = -k\sum _jW_{ij}(T_i-T_j) ∂t∂Ti=−k∑jWij(Ti−Tj),其中 W i j W_{ij} Wij为1是边,为0是没边,比前面的式子多了个负号因为换了下里面减的顺序。简单化简一下这个式子,则有 ∂ T i ∂ t = − k [ d e g ( i ) T i − ∑ j W i j ( T j ) ] \frac{\partial T_i}{\partial t} = -k[deg(i)T_i-\sum _jW_{ij}(T_j)] ∂t∂Ti=−k[deg(i)Ti−∑jWij(Tj)],其中 d e g ( i ) deg(i) deg(i)是第 i i i个点的度数。我们把 n n n个点的式子写到一起,就有
[ ∂ T 1 ∂ t ∂ T 2 ∂ t ⋯ ∂ T i ∂ n ] = − k [ d e g ( 1 ) T 1 d e g ( 2 ) T 2 ⋯ d e g ( n ) T n ] + k W [ T 1 T 2 ⋯ T n ] = − k ( W − D ) [ T 1 T 2 ⋯ T n ] \begin{bmatrix}\frac{\partial T_1}{\partial t} \\\frac{\partial T_2}{\partial t} \\\cdots\\\frac{\partial T_i}{\partial n} \\\end{bmatrix}= -k\begin{bmatrix}deg(1)T_1 \\deg(2)T_2 \\\cdots\\deg(n)T_n\\\end{bmatrix}+ kW\begin{bmatrix}T_1 \\T_2 \\\cdots\\T_n\\\end{bmatrix}= -k(W-D)\begin{bmatrix}T_1 \\T_2 \\\cdots\\T_n\\\end{bmatrix} ⎣⎢⎢⎡∂t∂T1∂t∂T2⋯∂n∂Ti⎦⎥⎥⎤=−k⎣⎢⎢⎡deg(1)T1deg(2)T2⋯deg(n)Tn⎦⎥⎥⎤+kW⎣⎢⎢⎡T1T2⋯Tn⎦⎥⎥⎤=−k(W−D)⎣⎢⎢⎡T1T2⋯Tn⎦⎥⎥⎤
其中D是对角化矩阵转化之后的 d e g ( i ) deg(i) deg(i)向量,而正好 D − W D-W D−W是拉普拉斯矩阵的一种定义,因此使用拉普拉斯矩阵可以很好的模拟图上的传播。
1.2.1.2 拉普拉斯变换怎么用
首先,图上的拉普拉斯矩阵的构建有很多种方法, L = D − W L = D-W L=D−W,是其中一种,还有一种是将 L L L规范化之后的版本即 L ′ = D − 1 / 2 L D = 1 / 2 L' = D^{-1/2}LD^{=1/2} L′=D−1/2LD=1/2,其中 L L L就是刚刚提到的 L L L,这个版本才是GCN中常用的,至于为什么则有点超出本文的范畴,而后文会用 L 来 代 指 L ’ L来代指L’ L来代指L’
接着,由于本文所讲得GCN适用于无向图,因此
L
L
L是个对称矩阵,因此它可以被特征值分解,即
L
=
U
Λ
U
T
L = U \Lambda U^{T}
L=UΛUT
其中
U
U
U被称作L的特征向量,有
U
U
T
=
I
UU^T=I
UUT=I,
Λ
\Lambda
Λ是特征值所构成的对角向量。
1.2.2 图上的傅里叶变换
1.2.2.1 傅里叶变化是干嘛的
之前有自己写过图像的傅里叶变化,进行图像处理,虽然图像处理的傅里叶变换和本文提到的图的傅里叶变换有巨大区别,不过思想却很相近。
以图像为例,傅里叶变换之后,如果我们想去掉噪声,往往只会保留变换之后的谱图以原点为圆心,附近的一个圆的区域,因为再往外就是噪声了;反之,如果我们只想保留一些边缘结构,(因为边缘和周围的像素差别较大),我们要去掉谱图里以原点为圆心的一个区域,因为这个区域代表了原图里变化比较少的地方。
这样可以看出来,通过傅里叶变换之后,噪音集中在了一起,比较正常的地方也集中在了一起,这样就可以很好被我们利用来分析某些性质。
1.2.2.2 图上的傅里叶变换怎么做
傅里叶变换往往是可以通过一个函数 f ( x ) f(x) f(x)变换到频域,再可以通过 I ( f ( x ) ) = x I(f(x))=x I(f(x))=x变换回来,变换到频域之后可以通过一个函数 g ( f ( x ) ) g(f(x)) g(f(x))进行一些处理,这样变换回去的信号和之前仍然差别不大,但是满足了我们想要的一些性质。
而在矩阵上,特征值分解刚好也可以为我们找到一个矩阵的主要成分和不重要成分,即特征值大的比较重要,特征值小的比较不重要,如果我们想滤到那些噪声,我们只需要选取前 K K K大的特征值所对应的向量,其他的略去即可。
而且,由于特征向量构成的矩阵满足正交性,那 U T x U^Tx UTx就相当于将x转换到了频谱上, U U T x UU^Tx UUTx则又将x从频谱上变换了回来。
再者,由于变换到频谱之后,可以更好对细节和非细节进行分析,往往会学习一个对角化向量
g
θ
g_\theta
gθ,这个就是图卷积的卷积核,图卷积的式子就变成了
y
=
U
g
θ
U
T
x
y = Ug_\theta U^{T}x
y=UgθUTx
如果
g
θ
=
Λ
g_\theta = \Lambda
gθ=Λ,那么就是1.2.1.2中提到的朴素的消息传播的样子了。
1.2.3 图卷积怎么做
在[1]和[2]所提到的所谓第一代GCN中,是直接学习一个长度为
n
n
n的向量
g
θ
g_\theta
gθ的,这样效果也不错,就是复杂度有一点高,且可以注意到拉普拉斯矩阵
L
L
L只进行了一步传播,就是聚集了和它相连节点的,更远的就聚集不到了,因此呢[3]中提到的GCN对[1]和[2]中的进行了改进,将
g
θ
g_\theta
gθ转换为了一个关于特征值
Λ
\Lambda
Λ的一个函数,即
g
θ
(
Λ
)
=
∑
k
=
0
K
−
1
θ
k
Λ
k
g_\theta(\Lambda) = \sum _{k=0}^{K-1}\theta_k \Lambda^k
gθ(Λ)=k=0∑K−1θkΛk
将学习的参数改成了一个长度为
K
K
K的向量
θ
\theta
θ,每次对
Λ
k
\Lambda^k
Λk赋予不同的权重进行聚合而且这个其实聚集了从x开始往外1步,2步,到K-1步的值,为什么呢,这是一个很有趣的算法/线性代数知识。
对于一个邻接矩阵 L L L来说,其中不为0的位置 ( i , j ) (i,j) (i,j)可以看作能从 i i i一步走到j,那么 L 2 L^2 L2中不为0的位置 ( i , k ) (i,k) (i,k),就代表了在矩阵乘法的时候,有一个 j j j使得 ( i , j ) , ( j , k ) (i,j),(j,k) (i,j),(j,k)同时不为0,才能乘出来 ( i , k ) (i,k) (i,k)不为0,这样就代表了是先从 i i i走到 j j j,再从 j j j走到 k k k,这样里面不为0的位置就是走两步能到达的位置,这样 L k L^k Lk次方就代表了走k步能到达的点了。
那为什么只对 Λ \Lambda Λ求k次方就可以了呢,因为 L k = ( U Λ U T ) k L^k=(U\Lambda U^T)^k Lk=(UΛUT)k,又因为中间的 U U T = I UU^T=I UUT=I消掉了,就只有 L k = U Λ k U T L^k=U\Lambda ^k U^T Lk=UΛkUT了,这样就以很少的参数量,聚集了很多步的信息。而又因为 Λ k \Lambda ^k Λk求解复杂度较大,可以用切比雪夫多项式去近似。
指的一提的是,这样聚集的话,较为近的点容易被走到多次,就是近的信息容易被聚合,如果相对雨露均沾的学习到呢,这好像也是一个最近在搞的研究方向,感觉可以在这个 L K L^K LK的意义,即走出去几步再设计设计,没准能取得比较好的结果。
这样我们就得到了开头的式子
y
=
U
g
θ
(
Λ
)
U
T
x
y = Ug_\theta(\Lambda)U^{T}x
y=Ugθ(Λ)UTx
1.3 结构上的一点分析
为了更宏观的去了解图的结构,可以对节点进行聚类,这样得到更粗放的图,这样能提取出更宏观的信息,也有利于减小复杂度。
在[1]中提取了一种比较暴力的聚类方式,选取一个要聚类的数量K,和一个阈值 ϵ \epsilon ϵ,选取学到的向量相似度小于 ϵ \epsilon ϵd K个作为下一层图卷积的点。然而这样复杂度过大。
为解决这个问题[3]提出了一种基于二叉树的结构,即每次将相邻边权最大(这个边权可以理解为相似度),且两个点都在这一轮迭代中没有被合并过的两个点合并成一个点,如图2,第一轮0-1,4-5,8-9合并得到图
g
1
g_1
g1,接着第二轮
2
−
3
,
4
−
5
2-3,4-5
2−3,4−5何必跟得到图
g
2
g_2
g2,由于作者想构建一个满二叉树,因此开了一些虚节点,这样进行
p
o
o
l
i
n
g
pooling
pooling等的操作复杂度会比较低。
图 2 点 的 聚 类 图\ 2\ 点的聚类 图 2 点的聚类
二、一点想法
- 比较重要的一点是GCN要求是一个对称的矩阵,好像很多论文忽略了这个条件,可能会导致结果不是很好。
- GCN因为每次都要算拉普拉斯矩阵,因此对于新节点要进来的话,只能重构,代价过大。
- 为了解决上面两个问题,有人使用Attention做了一套,效果非常好叫GAT,所以我打算下一篇看GAT。
- 我感觉之前应用的时候了解是一个特别粗的层次,就是基本什么都不明白,然后看了三篇论文之后理解了个大概,再要写出来又要更加了解一些,感觉这样学习一个算法确实比较好,不过读有精读和泛读,这几天看得都是要精读的,不过也不应该每个都这么精的读,不然容易过于耗费时间。
三、引用
[1] Bruna J , Zaremba W , Szlam A , et al. Spectral Networks and Locally Connected Networks on Graphs[J]. Computer Science, 2013.
[2] Henaff M , Bruna J , Lecun Y . Deep Convolutional Networks on Graph-Structured Data[J]. Computer Science, 2015.
[3] Defferrard M , Bresson X , Vandergheynst P . Convolutional Neural Networks on Graphs with Fast Localized Spectral Filtering[J]. 2016.
[4] https://www.zhihu.com/question/54504471/answer/630639025
[5] https://www.zhihu.com/question/54504471/answer/332657604