GCN 和 GAT 都在聚合邻域信息,但聚合权重的来源不同。理解这个区别,不需要先背一个数据集上的准确率。
GCN并不是给所有邻居相同权重
对经典无向图 GCN,加入自环后,用度矩阵做对称归一化:S = D^(-1/2) (A + I) D^(-1/2),然后计算 S X W。边的系数与相邻节点的度有关,因此不同邻居的系数可以不同;该算子各行之和也不要求等于 1。GCN 原论文与 PyG GCNConv 定义
下面只检查无向、无权图中的线性聚合,省略激活、偏置与训练。
import numpy as np
adjacency = np.array([[0., 1., 0.], [1., 0., 1.], [0., 1., 0.]])
with_self = adjacency + np.eye(3)
degree = with_self.sum(axis=1)
normalizer = np.diag(degree ** -0.5)
operator = normalizer @ with_self @ normalizer
np.testing.assert_allclose(operator, operator.T)
assert not np.allclose(operator.sum(axis=1), np.ones(3))
features = np.array([[1.], [2.], [4.]])
output = operator @ features
assert output.shape == (3, 1)
assert np.isfinite(output).all()
print("symmetric GCN normalization checked")
这里的矩阵约定只针对这个小例子;实际使用有向边列表时,必须确认源节点、目标节点、度计算和消息方向,不要机械照搬无向图推导。
GAT的归一化范围很关键
GAT 从特征计算边上的注意力分数,再对同一个目标节点的允许邻居做 Softmax,得到该次聚合的权重。它不是对整张图所有边统一归一化。是否加自环、多个头拼接还是平均,也会改变输出和维度。GAT 原论文
实践中应检查:每个目标的邻居集合是否正确、注意力权重对应哪一份返回边列表、是否在评估模式观察权重。训练时的注意力 Dropout 还会影响直接检查“权重和为 1”的结果。
注意力权重可帮助调试,但不能直接把“权重大”解释成“这条边造成了最终决策”。同时,模型名字也不是学习协议:GAT 原论文就包含归纳式评估,不能把它写成只能在固定图上使用。
节点分类怎么划分
固定图的半监督协议可以允许未标注测试节点的特征与边出现在消息传递中,但训练损失只使用训练标签。若目标是预测未来新增节点,图的可见范围和时间截点又要重新定义。
先声明协议,再确定训练、验证、测试掩码。验证集选超参数,测试集不应成为每轮选最优模型的依据。一次玩具矩阵检查通过,也不代表完成 Cora 基准训练。
来源与核验边界
本篇结合疏锦行图神经网络专题《节点分类:GCN与GAT》讲义,重点整理度归一化、注意力归一化和掩码边界,并纠正模型与协议被混为一谈的表述。矩阵示例已运行;未复现讲义中的 Cora 分数。视频尚未逐节核验,原课件不公开。
GCN与GAT笔记:先分清度归一化和邻居Softmax
本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。
评论交流
欢迎留下你的想法