前言
前几周读了Semi-Supervised Classification with Graph Convolutional Networks(GNN arxiv
)一文,感觉对它的理解还凑合,就写个博客。本文旨在提供一个high level的idea,并不讨论细节(如论文中较大篇幅严谨的公式推导)。
来自卷积的灵感
模型既然叫Graph Convolutional Networks,那说明它肯定和CNN有联系的,联系是什么呢?我们都知道,卷积操作是kernel与feature map的对应元素相乘再相加:
图可以怎么表示呢?对了,邻接矩阵,那么我们是否可以类似地创建一个卷积核,对邻接矩阵进行卷积操作呢?
答案是不可以:因为在CNN中,kernel对应的feature map中的像素,有着天然的空间上的相邻关系;而在图的邻接矩阵中,kernel对应的元素在实际上可能并不是相邻节点,比如上图中节点1和节点3、4是邻居,而和节点2不是邻居,所以不行。
CNN只能处理常规的欧氏结构数据(节点有固定的排列规则和顺序,比如在图像中一个像素的邻居是它上下左右斜的像素),卷积依赖于数据的平移不变性;图数据是非欧式的,节点没有固定的排列规则和顺序,每个节点的邻居数量也不同,不满足平移不变性。
那我们该怎么办呢?其实卷积中体现了一种思想:用权重提取元素信息(相乘),再聚合(相加),即,我们把这个思想迁移到GNN中。
方法
1. 元素表示
我们先来看下面这个式子:
表示的邻居节点以及自己,表示用权重提取元素信息,起到聚合的作用。
起到归一化的作用,就是节点的度,就是说如果一个节点的邻居很多,那么它给邻居传递的信息就是“雨露均沾”,如果一个节点的邻居很少,那么它就是“鸡蛋都装到了一个篮子里”。
2. 矩阵表示
然后我们来看论文中给出的公式:
是加了单位矩阵(对应)的邻接矩阵,起到的作用;
是上一层的激活,在初始时就是节点属性矩阵,对应之前公式的;
是每一层需要学习的权重,对应之前公式的;
是度矩阵,计算方法是,对应之前公式的;
是非线性激活函数,如ReLU、Softmax等。
总结一下就是:GCN像CNN一样,用权重提取节点信息并加和,特殊操作就是归一化。
在CNN中,经过几次卷积,feature map中包含了比较大范围的信息;在GCN中,第一次“卷积”,每个节点获得邻居的信息,第二次“卷积”,每个节点获得邻居的邻居的信息……
实验
实验做的是顶点分类任务。
1. 模型设置
使用一个两层的GCN(蓝色背景为第一层, 是用度矩阵规范化后的 ):
2. 数据集
四个数据集,从上到下顶点边越来越多(图越来越大),标签比例越来越小(适合半监督的任务)
结果
我们来看一下GCN屌不屌。
1. 隐藏层可视化
可视化的就是上文中提到的两层GCN中蓝色背景的部分。可以看到总体分类情况还不错,少部分点不太好。
2. 四个数据集上的表现
可以看到GCN当时在四个数据集上都是sota,并且速度还很快,GCN太屌啦!
3. 关于模型层数的探究
两层的GCN已经很屌了,那是不是层数越多越好呢?不一定。作者给出了在三个数据集上的实验,其实差不多,我们以Citeseer为例:
对比虚线(无残差链接)和实线(有残差链接),我们发现没有残差链接的话模型准确率会在8层之后迅速下降;
观察Test线,对于Citeseer数据集,最好的表现是2层,Cora是2~4层,Pubmed是2~3层,所以2~3层的GCN已经能够取得不错的效果,GCN真的是太屌啦!
结语
沐神在B站有讲解GCN的视频:沐神GNN/GCN
有两个博客写的非常好,而且还是交互式的,这里给出链接:GNN介绍,各种GNN
欢迎在评论区探讨!