1. 模型构造思路
本文将一个节点能从MP系GNN获得的信息分为来自context(节点自身的信息)和来自surrounding(节点的图拓扑信息,通过其2跳邻居的aggregation得到),并提出了两种smoothness metrics(feature smoothness和label smoothness)来分析不同的图数据上邻居信息的quantity和quanlity(或者说,给节点加上邻居信息,对节点能产生多少正面的信息增益,也就能更好地完成节点表示、节点分类等任务),最后提出CS-GNN模型。
CS-GNN模型是一种使用attention进行加权求和的MP系GNN,利用了两种smoothness metrics来增强模型的表现能力。
这篇论文我就看了个思路,他的原理我就听了个热闹。
我觉得它好就好在它的模型具体运行情况考虑到了数据集的特性。因为我最近的活就是在扒拉一堆数据集,我扒拉出来的经验就是模型在数据集的魔改面前脆弱不堪。所以我觉得跑模型就是要看数据集的特性呢,要不然跑出来的baseline没有一个能过方差检验的不就很扯淡。
我觉得这个结合思路很好,但是怎么结合的我实在是没看懂。而且我总觉得他data leakage了。(见2.4.2部分)
2. Notation和模型介绍
2.1 Notation
2.2 通用MP系GNN框架
简单来说就是aggregate+combine结构,先聚合邻居,然后将邻居的聚合向量与中心节点的表示向量结合起来。对这种结构的理解、对文中所提及模型的理解可参考我之前撰写过的cs224w课程笔记系列:cs224w(图机器学习)2021冬季课程学习笔记集合_诸神缄默不语的博客-CSDN博客
2.3 context+surrounding框架
context c v :节点 v 自身的信息(用节点特征来初始化)
surrounding s v :节点 v 的邻居节点aggregate后得到的信息(向量)
对2.2中aggregate+combine结构的GNN通用框架,可以用这种体系重写成:
这个框架就是对aggregate+combine结构的重写,具体怎么映射成这样的未完待续。
通过我没有看懂的Theorem1,本文指出合适的aggregator(最好的就是mean,pooling方法则根本没有denoise效果)能使某一节点邻居输入中的noise比context的更小。
pooling没有降噪的作用,sum反而会放大噪声。
引用文字及图源:【AI TIME PhD ICLR】-度量和改进图信息在图神经网络中的使用-侯逸帆_哔哩哔哩_bilibili
2.4 smoothness metrics
衡量图中相邻节点某些指标(本文中是feature和label)之间的相似程度。越大说明越不相似。
可以用来衡量一个数据集适不适用于传统GNN(见实验4.4.1和实验4.4.2)。
我感觉这个指标有点像Assortativity同配性。
同配性的事我以后再研究。
数学原理背景:(这部分我不懂,我flag放在这里,我以后学)
KL散度(或信息增益)
一般是用来衡量两个分布的差异性,这里给出的是另一种定义
注意KL散度是不对称的
本文用以衡量S对C的信息增益(其相似度)
图源:kl散度度量分布_ICLR 2020丨论“邻里关系”的学问:度量和改进图信息在图神经网络中的使用…_Maqiu467的博客-CSDN博客
本文提出了feature smoothness和label smoothness,前者衡量GNN过程中信息增益的quantity,后者衡量对应的quality。
2.4.1 feature smoothness
衡量图中相邻节点特征之间的相似程度。越大说明越不相似。
(Definition2,没有看懂)如果没有噪音,我们可以得到一个指标来衡量邻居特征信息能给予节点的information gain。但是这个ground truth是不可知的,因此我们可以使用 λ f 来估计它(Definition3)。
feature smoothness越大,就说明图中信息的频率越高,邻居节点的特征越不同,通过surrounding能提供给节点更多的信息。
那个公式,在实现的时候其实平方是在里面的。
就大略类似这样:
result=np.zeros(features.shape[1]) for i in range(features.shape[0]): z=np.zeros(features.shape[1]) for j in range(features.shape[0]): if adj[i,j]==1 and i!=j: z+=(features[i]-features[j])*(features[i]-features[j]) result+=z result=np.sum(result)/(features.shape[1]*5429) print(result)
(但是就是作者自己也说一般因为图太大了所以也不会像这样用邻接矩阵,而会用edge list。但是这个代码是读者问的,而且给的还挺清晰的,所以我觉得很有借鉴意义,我就扒拉出来了)
来源:sorry to bother again。。 · Issue #3 · yifan-h/CS-GNN
数学证明没看懂。总之也列一下我看的讲解内容。
C和S上的KL散度:
这个是定义在连续数据上的。现实图数据可以看作是真实连续图数据上的采样点。
引用自kl散度度量分布_ICLR 2020丨论“邻里关系”的学问:度量和改进图信息在图神经网络中的使用…_Maqiu467的博客-CSDN博客:
对图上所有节点,算出每个节点与邻居节点的距离之和的平方,然后对所有节点进行加和,取曼哈顿距离,最后除以特征维度和边的数目,得到特征平滑度。数学证明KL散度与特征平滑度成正比,即信息增益的大小与特征平滑度成正相关。
作者在GitHub的issue中说这个思路来源自graph signal processing,可以参考PyGSP。(some question about Feature smoothness · Issue #2 · yifan-h/CS-GNN)
这部分的视频讲解:
背景:
图信号处理后的平滑度
Lambda(傅里叶变换的频率)很小时,表示信号频率和很低,平滑程度很高。
Lambda很大时,表示信号频率很高,表现为很不平滑(平滑度很低)。
注意这里的KL散度是k=0时的定义,即还没有使用GNN网络时。因为我们的目的是评估图数据,而且定义应该适用于所有GNN模型(实际的aggregator是求均值)
以上视频指的是这个:【AI TIME PhD ICLR】-度量和改进图信息在图神经网络中的使用-侯逸帆_哔哩哔哩_bilibili
2.4.2 label smoothness
衡量图中相邻节点标签之间的相似程度(节点分类任务),即衡量信息增益的质量。越大说明越不相似。
label smoothness越大,说明邻居节点之前标签差异越大,说明邻居信息对学习任务会具有越大的干扰,GNN效果越差。
数学原理:
参考视频【AI TIME PhD ICLR】-度量和改进图信息在图神经网络中的使用-侯逸帆_哔哩哔哩_bilibili 讲解,该公式基于标签平移假设:
(然后这部分证明我没太看懂,就是说一个节点的邻居信息可以用indicator function来根据label smoothness进行重新表示,如果分类器的linearity很好(亦即数据线性可分),对标签聚合的方式就可以引起标签同样方式的改变,context就可以转化为y(文中给了这个参考文献:Hongyi Zhang, Moustapha Cisse, Yann N. Dauphin, and David Lopez-Paz. mixup: Beyond empirical risk minimization. In ICLR, 2018.)。从而根据这个重新表示的公式可知与原节点同标签的邻居节点可以使该节点的分类效果更好。)
(但这事真的需要证明吗?MP的假设就是基于同配性的,同配性低的图MP效果差这种事真的用证明吗?从WL test到label propagation,从GCN到APPNP,我们又aggregate又message transformation的不就是看中了图数据的homophily吗?要是没有这东西,节点之间的边存在的意义就跟假设不一样了,那还搞啥?但是感觉如果以后需要再证明这种不用证明的东西可以再过来研究研究这里在说什么以资借鉴(草,我想起那个数学笑话,在数学差的人眼中数学卷子上的证明题只有两种情况:这也用证?这也能证?))
实际计算:
在原论文中使用的数据集里只有BGP数据集有无标签节点,处理方法是去掉了无标签节点(也就是用有标签节点的node-induced subgraph)来算了它的label smoothness,以估算全图的label smoothness。
但问题在于我们划分数据集为train/val/test了,按理来说在训练前是不应该知道整张图上的label的,如果通过整张图来获得label smoothness信息然后借以训练模型,那不就data leakage了吗?整啥呢这是?
我看了一下GitHub,果然大家也有这种困惑,提出问题并得到了作者的回应:sorry to matter you again · Issue #4 · yifan-h/CS-GNN
大致来说,作者回应称feature smoothness是用全图做的,这在transductive任务里面很正常了;至于label smoothness,如果只用训练集数据来计算(就比如只用训练集节点的node-induced subgraph来算),其值就会严重取决于数据划分方法,尤其对半监督学习任务。当然在实际任务中可以只用训练集数据来估算label smoothness。作者对半监督学习任务的建议是用label propagation先搞出伪标签,然后在大点的subgraph上再估算label smoothness。
但是我看了一下代码,感觉作者就直接用全图数据算的。所以我觉得他data leakage了。
2.5 CS-GNN
有点像GAT,aggregator是用attention加权求和,然后concatenation。
第 k 层节点对 i , j 的attention是这么算的:
一共 2 ∣ E ∣个attention coefficient:乘性注意力机制。
leveraged(这个词我见好几次了,到底是啥意思?进行过线性转换的意思吗?)representation vector p 与邻居节点context向量 q (v 的context representation vector与邻居的leveraged representation vector之差)相点乘(类似cosine相似度),然后应用softmax归一化。
节点与邻居feature差别越大,说明聚合邻居能得到的information gain越多,q 就越大,a 就越大,即权重越大,反之亦然。
label smoothness用于截断一些邻居之间的信息传递:也就是把attention coefficient小于一个由label smoothness计算得到的比例的置0(相当于把边直接drop掉),label smoothness越大就drop掉越多的边以降噪。但是这个具体的值作者没说是怎么弄出来的。
feature smoothness用于决定隐藏层维度(p pp 和 q qq 的维度),就信息增益越高就让它维度也更高。这个具体值是实证得出来的(按我的经验来说就是调参调出来的意思)。
使用加权求和的方式聚合邻居节点信息:
分类任务的话就最后再叠一层全连接层:
视频 【AI TIME PhD ICLR】-度量和改进图信息在图神经网络中的使用-侯逸帆_哔哩哔哩_bilibili 中给出了图示(0和1之间的attention):
这个 q 的计算方式在视频中的解释:
2.5.1 side information
这部分我没看懂啥意思,大致感觉就是side information就是在节点(context)或边(surrounding)上的特征。
作者参考了GraphWave(Donnat et al., 20181)的方法,每个节点选取一个K跳邻居的node-induced subgraph,用类GraphWave方法就可以得到每个节点的 t v i (local topology feature vector)。
t v i不会在节点聚合过程中变化,所以就不用融合进representation vector。
在attention机制中 t v i 视作context information的一部分:
最后的全连接层:
GraphWave我放个以后要看的flag在这里。
2.5.2 和其他GNN模型的对比
(这里的additive啥意思,这部分除了不用再讲一遍的内容之外都没看懂,下一个)
3. 详细的数学推导和证明
等我学好信息论以后再回来补,下一个。
4. 实验结果
4.1 baseline
本文将baseline分成这样三类:
topology-based methods
featurebased methods
GNN methods
分别对应:
4.2 数据集
略,待补。
4.3 实验设置
大致来说在节点上的数据集划分是7-1-2(训练集比例好高啊),然后指标是F1-Micro。
其他略,待补。
4.4 实验结果
4.4.1 模型指标结果
那个LTF就是local topology feature。主要是用于与GAT对比smoothness指标的效果的(真的吗?我没搞懂,算了)。
其他略,待补。
4.4.2 GNN模型相比非GNN模型的优势性
注意PubMed是低feature smoothness,BGP是高label smoothness。就这里作者解释了一下为什么会这样,以及CS-GNN在这种数据集上的优势性。
具体略,待补。
4.4.3 调整smoothness查看对模型结果的影响
调整feature smoothness就是直接propagate特征向量,调整label smoothness就是随机drop一些把不同标签的节点连在一起的边。
用稠密且feature smoothness较大的Amazon数据集来完成这部分实验。
左图右边那几个就是GNN过拟合的后果了嘛。对左图中MLP数据一开始变好的解释是broadcast反而使之获得了跟GNN一样能获得邻居信息的能力。
右图的MLP过度坚挺了以至于显得很搞笑(〃‘▽’〃)
5. 代码实现和复现
5.1 论文官方实现
计算smoothness的代码:CS-GNN/smoothness.py at master · yifan-h/CS-GNN
我看这玩意算label smoothness就是拿所有数据算的,所以我觉得就是有数据泄漏问题。
其中实验4.4.3是用这个实现的:Why to feature_broadcast and label_broadcast? · Issue #7 · yifan-h/CS-GNN
这是我问的,具体解释略,以后再看。
(话说明明作者是说中文的为什么所有issue都是英文,连我都不好意思直接用中文写了)
具体代码没咋看懂,就浏览了一遍:
CS-GNN/utils.py at master · yifan-h/CS-GNN 加载数据的代码
CS-GNN/models.py at master · yifan-h/CS-GNN 模型
CS-GNN/train.py at master · yifan-h/CS-GNN 训练的主代码
CS-GNN/minibatch.py at master · yifan-h/CS-GNN 没看懂咋搞的
CS-GNN/encode.py at master · yifan-h/CS-GNN 应该就是那个用类似GraphWave方法算出来的拓扑向量,就是数据集里的feats_t.npy数据。
具体没看。DGL我也没用过,看不懂。有缘待补。
5.2 PyG官方实现
没有。(这个也不好实现吧,感觉很取决于数据集特征的)
5.3 我自己写的复现
没写。