跳转到内容

GCN 2017 — 把卷积搬到图结构上的最简版本

是什么

GCN(Graph Convolutional Network)是一种让神经网络处理”图结构”数据的方法。

日常类比:你想猜一个学生的兴趣,不光看他自己填的问卷,还看他朋友圈里的人填了什么——朋友越像,他就越可能像。GCN 把这件事写成数学:每一层,每个节点把自己和邻居的特征做加权平均,再过一道变换。

经典 CNN 处理的是网格——图像是二维网格、文本是一维序列,邻居是谁很清楚。但社交网络、引用图、分子这些数据没有规则邻居,每个节点的度数不一样,连接也乱。GCN 用一条简化到极致的公式解决了这个问题。

为什么重要

不理解 GCN,下面这些事都没法解释:

  • 为什么 2017 年之后图神经网络(GNN)会突然”爆发”——之前 Bruna 2013 的谱方法已经能做,但太慢太难训
  • 为什么社交推荐、药物发现、知识图谱补全都开始用同一套思路
  • 为什么 PyTorch Geometric / DGL 这些库的核心 API 长得都像 GCN 一层
  • 为什么 LLM 时代的 GraphRAG 也要先把文档建成图再”跑一遍 GCN 思路”做检索

GCN 的贡献不是”第一个”,而是简化到能被普通工程师 30 行 PyTorch 复现——这才点燃了 GNN 整条赛道。

核心要点

GCN 一层的公式(看不懂没关系,下面拆开讲):

H^(l+1) = σ( D̃^(-1/2) · Ã · D̃^(-1/2) · H^(l) · W^(l) )

把符号翻译成人话:

  1. Ã = A + I:A 是邻接矩阵(谁连谁),加单位矩阵 I 等于”给每个节点连一条到自己的边”。不加自环,节点会丢掉自己的特征
  2. D̃^(-1/2) Ã D̃^(-1/2):按度归一化。度大的节点(社交达人)权重压低,度小的节点权重抬高。否则”大 V”会主导整张图。
  3. H^(l):上一层的节点特征矩阵(每行一个节点)。第 0 层就是输入特征。
  4. W^(l):可训练的线性变换权重(和普通神经网络一样)。
  5. σ:非线性激活,比如 ReLU。

一句话总结:邻居加权平均 → 线性变换 → 非线性。两层这种结构堆起来,就够在 Cora 引用网络上把节点分类做到 SOTA。

实践案例

案例 1:用 GCN 给 Cora 论文分类

Cora 数据集:2708 篇论文(节点)、5429 条引用关系(边)、每篇有 1433 维词袋特征、7 个类别。

任务:只标注 140 篇(5%),让模型把另外 1000 篇分类。

# 伪代码(概念演示)
import torch.nn as nn
class GCN(nn.Module):
def __init__(self, n_feat, n_hid, n_class):
super().__init__()
self.W1 = nn.Linear(n_feat, n_hid)
self.W2 = nn.Linear(n_hid, n_class)
def forward(self, X, A_norm): # A_norm 已经做完 D̃^(-1/2) Ã D̃^(-1/2)
H = torch.relu(A_norm @ self.W1(X))
H = A_norm @ self.W2(H)
return H # 用 cross_entropy 就能训

关键观察:只有 30 行的模型,Cora 准确率 81.5%,比之前的 Planetoid(75.7%)高一截。

案例 2:从谱方法简化到一阶近似

GCN 不是凭空冒出来的。论文从谱图卷积推导:

  1. 图傅里叶变换需要算拉普拉斯矩阵的特征分解,O(n³) 太慢
  2. Defferrard 2016(ChebNet)用 K 阶 Chebyshev 多项式逼近,省掉特征分解
  3. GCN 取 K=1(只看一跳邻居) + 重归一化 trick

最后剩下的就是开头那条公式。简化才是贡献——把谱方法落地到能用。

案例 3:堆深就翻车(oversmoothing)

直觉上”层数越多越好”,GCN 不成立:

层数Cora 准确率
281.5%
379.0%
570.0%
10<40%

(数字为示意趋势,不同实现细节会有差异)。每层都做”邻居平均”,多次平均后所有节点特征趋同——这就是 oversmoothing。后续工作(DropEdge / GCNII / PairNorm)专门修这个洞。

踩过的坑

  1. 忘加自环 A + I:节点把自己的特征丢了,只剩邻居的”投票”,效果直接掉 5-10 个点。

  2. 归一化方式选错:行归一化(D^-1 A)比对称归一化(D^-1/2 A D^-1/2)效果差,论文里有消融。原因是非对称矩阵特征值分布更不稳定。

  3. 以为能 inductive:原始 GCN 是 transductive 的——训练时整张图(含测试节点的连接)都要在内存里。要做 inductive(新节点加进来)得用 GraphSAGE 或 FastGCN。

  4. 大图放不下:Cora 才 2708 个节点,full-batch 没问题。换到 OGB 几百万节点,显存直接炸。需要 mini-batch 邻居采样。

  5. 一视同仁的邻居:所有邻居权重只按度归一化,没法表达”这个邻居比那个重要”。GAT 用 attention 修了这点。

适用 vs 不适用场景

适用

  • 节点分类(半监督,标签稀疏):引用网络、社交网络、蛋白质相互作用
  • 图相对静态(训练和测试时图结构差不多)
  • 中小规模图(百万节点以下)
  • 想要一个简单基线——再复杂的 GNN 也常被 GCN 比下来

不适用

  • 大规模动态图(节点/边一直变)→ 用 GraphSAGE / PinSAGE 采样版
  • 需要区分邻居重要性 → 用 GAT
  • 异质图(多种节点/边类型)→ 用 R-GCN / HGT
  • 长程依赖(要走 10 跳才相关)→ GCN oversmoothing;考虑 Graph Transformer

历史小故事(可跳过)

  • 2008:Scarselli 提出最早的 GNN,用迭代到不动点训练,难训也慢
  • 2013:Bruna 把谱方法引进图卷积,理论漂亮但 O(n³) 太贵
  • 2016 Sept:Kipf(博士在读,导师 Welling)把 ChebNet 一阶截断 + 重归一化 trick 写成 ICLR 投稿。代码挂 GitHub,30 行 TensorFlow
  • 2017 ICLR:录用,引用迅速破万。Kipf 同年做了 R-GCN(关系图)、VGAE(图自编码器),博士论文成了一系列经典
  • 2018-:GraphSAGE / GAT / GIN 接力,GNN 成 ML 子领域
  • 2024-:LLM 时代回潮,GraphRAG 把图结构搬进检索增强生成

学到什么

  1. 大胆简化:从复杂方法(谱卷积)狠狠砍到能跑(一跳邻居 + 一阶近似)——简化本身就是贡献
  2. 归一化决定能不能训:邻居加权那一步对称归一化不是装饰,是稳定性保证
  3. 深度不是越深越好:消息传递类模型有 oversmoothing 这道天花板
  4. 半监督的甜区:图结构本身就是”伪标签”——通过邻居把少量标签传播出去,这是 GCN 在 5% 标签场景碾压全监督模型的根本原因
  5. 可复现 = 影响力:30 行代码 + 公开 repo,让 GCN 在一年内被全社区试遍

延伸阅读

关联

  • attention —— GAT 用 attention 替换 GCN 的固定邻居权重
  • graphrag —— LLM 时代把”先建图再传播”的思想用到检索增强
  • pytorch —— PyTorch Geometric / DGL 是 GCN 类模型的主流实现框架
  • adam-2014 —— GCN 训练用的优化器,原论文也用 Adam

反向链接

  • adam-2014 —— Adam — 让深度学习自己挑步长的优化器
  • attention —— Attention Is All You Need
  • gat-2018 —— GAT — 让图神经网络的邻居自带权重
  • graphrag —— GraphRAG — 微软的知识图谱 + RAG
  • graphsage-2017 —— GraphSAGE 2017 — 给没见过的节点也能算嵌入
  • pytorch —— PyTorch — 深度学习主流框架