前面废点话:
终于!来到了GNN最相关的内容!前面四章来说都是一些预备知识,或者说是介绍性的认识的东西,其实和GNN的关系不是特别大。但从这一章开始一上来就是GNN最核心的东西:图信号处理。这部分其实非常关键,但大部分人学的时候可能都会忽视这一点,认为自己可以直接进入GCN的部分,这是错误的。入门GCN最劝退的地方其实就是拉普拉斯和傅里叶变换那里,当然没懂的话也可以对着DGL或者PyG这两个轮子几行代码就写出来几个GCN,但轮子得来终觉浅,个人认为作为开山的论文,GCN的思想还是很重要的,所以这一章的读书笔记会做的比之前都详细,尽量能写出自己的理解。
夯实基础!什么叫夯实基础!矩阵乘法确实是整个机器学习的重中之重,所以我们先从最基础的开始看起。
对于矩阵\(A \in R^{K\times M},B\in R^{M\times P},C=AB\),我们有三种计算方式:
我们设\(A=\begin{bmatrix}1&-1&2\\0&2&1\end{bmatrix},B=\begin{bmatrix}2&0\\-1&1\\0&-1\end{bmatrix}\)。
进行矩阵乘法当然是简单的,也就是用传统的内积视角,很容易得到\(C=\begin{bmatrix}3&-3\\-2&1\end{bmatrix}\)。
如果我们用行向量的视角,则有\(C\)的第一行:\(\begin{bmatrix}3&-3\end{bmatrix}=\begin{bmatrix}1&-1&2\end{bmatrix}\begin{bmatrix}2&0\\-1&1\\0&-1\end{bmatrix}\)。
如果我们用列向量的视角,则有\(C\)的第一列:\(\begin{bmatrix}3\\-2\end{bmatrix}=\begin{bmatrix}1&-1&2\\0&2&1\end{bmatrix}\begin{bmatrix}2\\-1\\0\end{bmatrix}\)。
需要注意的特别是行视角的计算方式对理解空域图卷积的计算逻辑与意义有很大帮助。
图\(G=(V,E)\),假设共有\(N\)个节点,图信号是一种描述\(V\to R\)的映射,表示成向量\(x=[x_1,x_2,...,x_N]^T\),其中\(x_i\)表示在节点\(v_i\)上的信号强度。
拉普拉斯矩阵定义为\(L=D-A\),\(D\)是一个对角矩阵,对角线元素为节点的度数,\(A\)则是图的邻接矩阵。
拉普拉斯矩阵中的元素可以表示为
\[L_{ij}=\begin{cases}\text{deg}(v_i)&\text{if } i=j \\ -1&\text{if }e_{ij}\in E\\0&\text{otherwise}\end{cases} \]拉普拉斯矩阵还有一种正则化的表示(Symmetric Normalized Laplacian)\(L_{sym}=D^{-\frac{1}{2}}LD^{-\frac{1}{2}}\),各个元素可以表示为
\[L_{s ym}[i,j]=\begin{cases}1&\text{if } i=j \\ \frac{-1}{\sqrt{\text{deg}(v_i)\text{deg}(v_j)}}&\text{if }e_{ij}\in E\\0&\text{otherwise}\end{cases} \]很关键!GCN用的就是这个。
那么拉普拉斯矩阵是怎么来的呢?
考虑拉普拉斯算子:\(\Delta f=\Sigma^n_{i=1}\frac{\partial^2f}{\partial x_i^2}\),将其作用到离散的二维图像空间里,就能得到边缘检测算子:
\[\Delta f(x,y)=\frac{\partial^2f(x,y)}{\partial x^2}+\frac{\partial^2f(x,y)}{\partial y^2}=f(x+1,y)+f(x-1,y)+f(x,y+1)+f(x,y-1)-4f(x,y) \]具体的计算过程不赘述,就表明一点:因为是离散的空间,离散函数的导数退化为差分。
矩阵形式的表示为:\(\begin{bmatrix}0&1&0\\1&-4&1\\0&1&0\end{bmatrix}\)。其描述了中心像素与局部上下左右四邻居像素的差异,所以拿来进行边缘检测。
同理对于图信号,拉普拉斯算子也被用来描述中心节点与邻居节点之间的信号差异:
\[Lx=(D-A)x=[...,\sum_{v_j\in N(v_i)}(x_i-x_j),...] \]可以看到我们将拉普拉斯矩阵与图信号相乘后得到的向量中的元素\((Lx)_i\)代表的就是\(v_i\)的信号值乘\(v_i\)的度数再减掉其邻居的信号值之和。所以拉普拉斯矩阵可以用来刻画图信号的局部平滑度。
进一步可以定义二次型:
\[x^TLx=\sum_{e_{ij}\in E}(x_i-x_j)^2 \]这个被称为\(TV(x)\),图信号的总变差,是一个反应图信号的整体平滑度的标量。
我们先对拉普拉斯矩阵再进行一些分析:
假设图\(G\)的拉普拉斯矩阵有\(L\in R^{N\times N}\),由前面的定义很容易知道\(L\)是一个实对称矩阵,可以对角化,所以有:
\[L=V\Lambda V^T= \begin{bmatrix} \vdots&\vdots&\cdots&\vdots\\ v_1&v_2&\cdots&v_N\\ \vdots&\vdots&\cdots&\vdots \end{bmatrix} \begin{bmatrix} \lambda_1 &&&\\ &\lambda_2&&\\ &&\ddots&\\ &&&\lambda_N \end{bmatrix} \begin{bmatrix} \cdots&v_1&\cdots\\ \cdots&v_2&\cdots\\ \cdots&\vdots&\cdots\\ \cdots&v_N&\cdots \end{bmatrix} \]\(V=[v_1,...,v_N]\)是\(L\)的N个特征向量,且有\(V\in R^{N\times N}\)是正交矩阵\(VV^T=I\)。用\(\lambda_k\)表示第\(k\)个特征向量对应的特征值,并令\(\lambda_1\le\lambda_2\le...\le\lambda_N\)。
因为前面有\(x^TLx=\sum_{e_{ij}\in E}(x_i-x_j)^2\ge0\),所以拉普拉斯矩阵是半正定矩阵,其所有特征值均非负。且如果我们将全为\(1\)的向量带入前面的\(Lx\)显结果然为0,说明拉普拉斯矩阵具有最小特征值为0,对应的特征向量全为\(1\)。
之后考虑图傅里叶变换,对于图\(G\)上信号\(x\),其图傅里叶变换为
\[\tilde x_k=\sum^N_{i=1}V^T_{ki}x_i=\lang v_k,x\rang \]我们称特征向量为傅里叶基,\(\tilde x_k\)是\(x\)在第k个傅里叶基上的傅里叶系数。通过定义我们可以看出傅里叶系数本质上是图信号在傅里叶基上的投影,衡量了图信号与傅里叶基之间的相似度。
矩阵形式可以计算所有傅里叶系数:\(\tilde x=V^Tx\)。
因为\(V\)是正交矩阵,所以上式可以变换为\(V\tilde x=VV^Tx=Ix=x\),由此定义逆图傅里叶变换IGFT:
\[x_k=\sum_{i=1}^NV_{ki}·\tilde x_i \]同时可以有其向量形式:
\[\begin{aligned} x=V\tilde x&= \begin{bmatrix} \vdots&\vdots&\cdots&\vdots\\ v_1&v_2&\cdots&v_N\\ \vdots&\vdots&\cdots&\vdots\\ \end{bmatrix} \begin{bmatrix} \tilde x_1\\\tilde x_2\\\vdots\\\tilde x_N \end{bmatrix} \\&=\tilde x_1v_1+\tilde x_2v_2+\cdots+\tilde x_Nv_N \\&=\sum^N_{k=1}\tilde x_kv_k \end{aligned} \]这表明傅里叶基是一组完备的基向量,任意一个图信号都可以被这组基所表示。
此时我们再回头看总变差,可以将其改写为:
\[\begin{aligned} TV(x)&=x^TLx=x^TV\Lambda V^Tx \\&=(V\tilde x)^TV\Lambda V^T(V\tilde x) \\&=\tilde x^T(V^TV)\Lambda (V^TV)\tilde x \\&=\tilde x^T\Lambda\tilde x \\&=\sum^N_k\lambda_k\tilde x_k^2 \end{aligned} \]说明图的总变差与图的拉普拉斯矩阵的特征值之间有着线性对应关系,是图的所有特征值的一个线性组合,权重是图信号的傅里叶系数的平方。
之后书中分析了什么样的图信号具有最小的总变差,个人感觉这一段写的有些混乱,没太读懂,这里仅给出一个结论:如果\(x=v_i\),\(v_i\)是拉普拉斯矩阵的一个特征向量,那么总变差就为\(\lambda_i\)即特征向量对应的特征值。所以我们取最小特征值对应的特征向量就可以得到最小的总变差为0(拉普拉斯矩阵最小特征值为0)。还有一个引申出来的结论:特征值实际上是图信号平滑度的一种梯度刻画,可以将其视为”频率”,特征值越低,频率越低,傅里叶基变化的越缓慢,相近节点上的信号趋于一致;特征值越高,频率越高,傅里叶基变化的越剧烈,相近节点上的信号有很大不同。
好!这里已经灌输了太多概念和定义还有一些二级结论,我读的时候就有点晕,写这篇笔记的时候又晕了一次,所以我觉得要停下来做一点梳理。
我认为主要迷惑的点是GFT和IGFT为什么是那样定义的,我查询了一些资料,得到的结果是:别问,问就是定义。GFT实际上不是“基于数学”的,而是将傅里叶变换经过类比定义出了图上的一种计算操作,我们可以将其视为以拉普拉斯矩阵的特征向量为基对图信号进行投影,其将一个图信号分解到不同平滑程度的图信号上。
另一个迷惑的点是空域和频域在GFT里到底是啥,我的理解是原始的图信号是空域,得到的傅里叶系数则是在频域。
书中稍后也提到的傅里叶系数可以等价成图信号在对应频率分量上的幅值,反映了图信号在这个频率上的强度(前面说了将拉普拉斯矩阵的特征值看作频率)。那么再结合总变差中如果图信号是某特征向量那么总变差的值就是特征向量对应的特征值的结论,我们就有图信号在低频分量(较小的特征值)上的强度越大,信号的平滑度就越高(总变差小),反之平滑度越低。
由此就定义好了图信号的频域。我们又有IGFT,所以相应地可以得到空域。这样算对GFT有了一个基本的各方面的定义。
定义:对给定图信号的频谱中各个频率分量的强度进行增强或衰减的操作。图滤波器\(H\in R^{N\times N}\),那么有\(H:R^N\to R^N\),有经过图滤波器的输出图信号\(y\),则:
\[y=Hx=\sum^N_{k=1}(h(\lambda_k)\tilde x_k)v_k \]可以得到:
\[H=V \begin{bmatrix} h(\lambda_1)\\ &h(\lambda_2)\\ &&\ddots\\ &&&h(\lambda_N) \end{bmatrix} V^T \]对比拉普拉斯矩阵,图滤波器可以写为:
\[H=V\Lambda_h V^T \]\(Hx\)描述了一种作用在每个节点一阶子图上的变换操作。我们称满足这样性质的矩阵为\(G\)的图位移算子。
图滤波器具有以下几个性质:
称\(\Lambda_h\)为图滤波器\(H\)的频率响应矩阵,\(h()\)为\(H\)的频率响应函数。不同的频率响应函数可以实现不同的滤波类型,常见的即为低通、高通、带通。(插一句嘴,忘了哪篇paper分析过GCN实际上是低通滤波器~)
书里给了个计算的例子没头没脑的挺迷的...给了个式子但前面写\(L\)后面写\(H\)...没懂想表达什么,所以就只记录一下一些概念和结论。
贴一下给的空域的式子:
\[y=\sum^K_{k=0}h^kx^{k}\\ x^{k}=H^kx=Hx^{k-1} \](书里写的是\(x^k=L^kx\),我觉得写错了应该是H)
图滤波器的局部性:k阶的计算只涉及节点的k阶邻居。
空域角度下,滤波操作具有如下性质:
因为局部性,所以\(H\)可以看做一个聚合邻居的操作算子。(酷,马上想到GraphSAGE的聚合操作)
将拉普拉斯矩阵的定义带入到\(H\)的定义给出这样一个形式:
\[H=V \begin{bmatrix} \sum_{k=0}^Kh_k\lambda_1^k\\ &\sum_{k=0}^Kh_k\lambda_2^k\\ &&\ddots\\ &&&\sum_{k=0}^Kh_k\lambda_N^k \end{bmatrix} V^T \]这说明只要K足够大,那么可以通过这种形式来逼近关于\(\lambda\)的任意一个函数。
考虑
\[y=Hx=V(\sum^K_{k=0}h_k\Lambda^k)V^Tx \]这是频域视角下的滤波操作,其变换过程如下:
说是频域角度,其实最后还是得到空域的图信号。
对比空域,频域要先计算拉普拉斯矩阵的特征值和特征向量,本身时间复杂度不低,所以有一定的局限性。
定义:图信号\(x_1,x_2\),图卷积运算为:
\[x_1*x_2=IGFT(GFT(x_1)\odot GFT(x_2)) \]\(\odot\)是哈达玛积,在第2章的时候提到过(没看过的朋友快去看!),简单来说就是把矩阵相乘简化为元素相乘再凑成矩阵。
将图卷积展开有:
\[\begin{aligned} x_1*x_2&=V((V^Tx_1)\odot(V^Tx_2)) \\&=V(\tilde x_1\odot(V^Tx_2)) \\&=V(\text{diag}(\tilde x_1)(V^Tx_2)) \\&=(V\text{diag}(\tilde x_1)V^T)x_2 \end{aligned} \]将\(\tilde x_1\)变成对角阵那步从结果上来说和哈达玛积等价,所以可以去掉哈达玛积。
定义\(H_{\tilde x_1}=V\text{diag}(\tilde x_1)V^T\),回顾前面图滤波器的定义,显然其也是一个图滤波器,其频率响应矩阵为\(x_1\)的频谱,由此图卷积就变为了图滤波运算。
下面考虑的是如何将图卷积运算应用到图数据的学习中去。
这是很自然的想法,即定义这样的神经网络层:
\[\begin{aligned} X'&=\sigma(V \begin{bmatrix} \theta_1\\ &\theta_2\\ &&\ddots\\ &&&\theta_N \end{bmatrix}V^TX) \\&=\sigma(V\text{diag}(\theta)V^TX) \\&=\sigma(\Theta X) \end{aligned} \]\(\sigma(·)\)为激活函数,\(\theta\)是需要学习的参数,X是输入的图信号,X'是输出的图信号。
可以从空域和频域两个角度来考虑这层网络:
这样的方法简单,但也有一些问题:
就贴了个公式没细说,总之也是在学习图滤波器,略过,贴一下公式:
\[X'=\sigma(V(\sum^K_{k=0}\theta_k\Lambda^k)V^TX) \]这个方法在GCN的paper里也有提到,GCN就是从这个方法改进来的,所以重点还是看后续的GCN的部分。
终于!GCN来辣!
首先是考虑5.2里的公式,令\(K=1\)可以得到这样一个神经网络层:
\[X'=\sigma(\theta_0 X+\theta_1LX) \]令\(\theta_0=\theta_1=\theta\),有:
\[X'=\sigma(\theta(I+L)X)=\sigma(\theta \tilde LX) \]注意\(\theta\)是一个标量一个值,也就是对\(\tilde L\)的频率响应函数做了一个尺度变换,因为尺度变换最后会被归一化操作所替代,所以没必要引入这个参数,不妨就令其为1,所以就有了一个固定的图滤波器\(\tilde L\)。
那么对\(\tilde L\)的归一化就是:
\[\tilde L_{sym}=\tilde D^{-\frac{1}{2}}\tilde A\tilde D^{-\frac{1}{2}},\tilde A= A+I,\tilde D_{ii}=\Sigma_j\tilde A_{ij} \]再考虑一下\(\tilde L_{sym}\),想一下它是怎么来的:我们一步步定义、推导出了GFT和IGFT,定义了图滤波器,给出了图卷积的定义,将图卷积的运算写成了图滤波器的形式,为了加强图滤波器的拟合能力给出了多项式形式的图滤波器,最后我们将其化简为只有两项,得到了\(\tilde L\),再进行归一化得到了\(\tilde L_{sym}\)。
也就是说,\(\tilde L_{sym}\)就可以被看作是一个图滤波器,也可以看做是图位移算子,\(\tilde L_{sym}X\)就是在做图卷积!
而得到\(\tilde L_{sym}\)无疑是容易的,不需要计算特征值、特征向量,只需要得到邻接矩阵即可。
为了增强网络的拟合能力,考虑一个参数化的权重矩阵\(W\),即:
\[X'=\sigma(\tilde L_{sym}XW) \]\(W\)是可学习的(不然\(\tilde L_{sym}\)是确定的网络在学啥呢hh),上式就是一层GCN Layer所做的事情。GCN就是多层堆叠的神经网络,我们也叫它图卷积神经网络。
终于!在前面4章加上这一章大量的内容铺垫之后,GCN终于现出了真容。
由此我们可以简单分析一下GCN:
更多的分析会在之后的章节。书中5.6节是GCN的代码实战,我会专门再出一篇博客来写,敬请期待。
写在后面:
你可能注意到我好久之后才更新了这一章读书笔记orz
一方面是在准备期末焦头烂额,另一方面是这一章的内容硬核而且又非常重要,我读了好几遍确保我理解正确之后才开始动手写读书笔记(虽然也不确定我理解的是不是都对)。之前我对GCN的认识全来自于Kipf的论文,诚实地讲没太读明白,因为缺了很多基础的知识。这次顺着这本书读下来感觉好理解了很多。其实GCN的原理讲解网上一抓一大把,我也看了不少,但也都是似懂非懂的,这次真的读书笔记顺着写下来才有种豁然开朗的感觉。希望各位也都能有所收获。如果我的笔记有错误也请多多指教。