阶段 8 · 前沿范式

一堆点加连线,怎么喂给网络

图片是格子,句子是一行,一堆特征是一团数。
可一个分子、一群朋友没有「第一个」「第二个」,只有谁和谁连着。这一章给第四种数据形状补上课。

1

排不成一行的数据

上一章《线性注意力与替代方案》换算法,数据还是排好队的:图片是网格、句子是一行、一堆特征是团成一个球的数。 现实里还有第四种:一堆点加一堆连线——一个分子有原子和化学键,一群人有朋友和来往, 城市之间有道路和航线,知识库里有实体和关系。换成图的说法,这些就是 节点 和 边:没有「第一个原子」,谁和谁连着才是全部信息。

麻烦在于普通网络只会收「排成一行的一串数」。那我们就把图排成一行试试: 下面这个 5 个原子的小分子,换一种编号,看排出来的那串数会怎么样。

互动 · 同一个分子,两种编号,两串数

编号一

右边这张 5×5 的表叫邻接矩阵(adjacency matrix):第 i 行第 j 列写 1,就表示 i 号、j 号之间有一条边。 换一种编号,同一张表只是行和列跟着重排。两串数长得完全不一样,但它们说的是同一个分子: 换成普通全连接网络,这就是两份毫不相干的输入;它费劲学到「第三个位置连着哪些位置」,一换编号就全对不上了。

所以图数据的第一条规则不是「怎么算」,而是「编号不重要,谁和谁连着才重要」。 这句话在数学里叫置换不变:编号怎么重排,答案都不该变。这一章的模型会从这条规则出发。

2

只知道两个人,猜出全部

这是一个真实的故事。1977 年,Zachary 记下了一个空手道俱乐部里 34 个人之间谁常来往:34 个点、78 条线。后来教练和管理员闹翻,俱乐部真的裂成了两派。

现在假装我们几乎什么都不知道,只被告知一件事:0 号站在教练这边,33 号站在管理员那边。 每个人的「看法」记作 h,就是一个数:越正越偏教练,越负越偏管理员,0 表示还没表态。 规则也只有一条:每一轮,每个人听一听和自己常来往的人怎么看,取个平均,当成自己的新看法。 拖下面的滑块,看这条规则能不能把 34 个人分对。

规则只有一句话 · 听邻居,改自己

v a b c v 的新看法 = ( h_v + h_a + h_b + h_c ) ÷ 4 自己 + 全部邻居,取平均

图里 v 是正在改看法的那个点,a、b、c 是它的三个邻居。 每个点同时做这件事:先把邻居的看法收上来,再加上自己,除以「自己 + 邻居的个数」。 文献里管这套动作叫消息传递。

互动 · 只给两个人的标签,传几轮能把全俱乐部认出来

0
看法偏向教练 还没表态 看法偏向管理员 真实派别(打开开关)
第几轮
0
已表态
2 / 34
和真实派别比
2 / 34 · 5.9%
大家的看法差多远
2.000

初始只有 0 号和 33 号有看法,其余 32 个人的 h 都是 0(灰)。

往下拖之前,先押一个:

先把滑块拖到 2 和 3:2 轮之后 34 个人全部表了态、猜对 32 人(94%),3 轮猜对 33 人(97%)。 从头到尾没人告诉它俱乐部该怎么分,它只知道谁和谁常来往。

再把滑块拖到 20、30、40:猜对的人反而掉到 30 人(88%)、23 人(68%)、17 人(50%)。 勾上「显示真实派别」,你会看到所有点的颜色越来越像——消息传得太远,大家的看法被互相抹平了。 这个现象叫过度平滑,第 5 节会把它算清楚。

还有一个例外值得盯住:8 号——Zachary 论文里的 9 号,论文从 1 开始给节点编号,本页从 0 开始。 它的 5 个朋友里有 3 个后来站在管理员那一派,它自己却去了教练派——规则一直把它算错。 模型没有坏,是这张图里本来就藏着一个不随大流的人。

💡 整章就这一句话

图神经网络做的事只有一件:每一轮,每个点都听一听邻居,再改一改自己。

3

一轮:听邻居,改自己

第 2 节那条规则拆开只有两步:把邻居的看法收上来、平均一下、写成自己的新看法。 传一轮听到「朋友」,传两轮听到「朋友的朋友」。所以一个点能听多远,只取决于传了几轮。

互动 · 点一个点,看它几步以内能听到谁

1 步

右边那行算式是现算的:8 号在第 1 轮之后听到了朋友们的看法,加上自己平均一下, 就得到它第 2 轮的新看法。点别的点,数字会整个换一套;规则不变,变的只是邻居是谁。

同一件事,两种说法:CNN 看几圈像素,GNN 听几步邻居

CNN · 叠一层看一圈像素 中心神经元看到的范围 GNN · 传一轮听一步邻居 传 1 轮听到圈内,传 2 轮听到蓝圈

这不是譬喻:CNN 的「几层」和 GNN 的「几轮」买的是同一件东西: 一个神经元/一个点的信息,能走多远。

这份直觉和 《感受野》那一章是同一件事的两面: CNN 叠一层,一个神经元往外多看一圈像素;GNN 传一轮,一个点往外多听一步邻居。 图上的「感受野」有多大,就看你传了几轮。

M

数学 · 把「平均」换成能学的

第 2 节那条规则里,「平均」是写死的:每个邻居说的一样重。可真实的数据里, 不同的邻居说的话本来就该有不同的分量。把平均换成「先按朋友数打个折、再乘一张表 W、过一个激活函数」, 这条规则就从写死变成了能学的,这才是 GNN 那一层真正的样子。

公式卡 · 一层 GNN 在算什么

W 是旋钮,学的是「听到的话怎么翻译成自己的看法」;σ 是那个折一下的 激活函数;d_v、d_u 是两个点各自的朋友数 +1(把自己也算一个邻居)。 把那一项取成 1 ÷(自己 + 邻居个数)、W 取成 1、σ 什么也不做,这条式子就退回第 2 节的纯平均。 所以新东西只有两处:邻居的汇总方式,和汇总之后的翻译方式。

互动 · 真的训练一个:只用两个人的标签

第几步
0 / 300
损失
—
34 人里猜对
—

每个人没有任何特征,只是一个编号;网络只被告知 0 号、33 号两个人站哪边。 两层 GNN(隐藏 4 个神经元)、300 步、学习率 0.2,全部现算。

同一场训练 · 损失一路往下掉

横轴是步数(0~300),纵轴是 0 号和 33 号两个人的交叉熵平均。

两层就是第 2 节说的传两轮:每层做一次「听邻居、改自己」,第二层听到的已经是「朋友的朋友」。 训练完通常能猜对 33 个人;错的那个总是 8 号——正是第 2 节那个人。 只标 2 个人也够,是因为每传一轮,这两个标签就被各自的邻居平均一次、往外扩一圈, 同一个圈子里的人互相听,看法很快趋同——剩下 32 个人的派别就是这么被顺带分出来的。

4

从这一张卡出发的一家子

第 M 节那张卡,其实就是 GCN 那一层。它留了两处可以动:邻居的消息怎么汇总、汇总之后怎么翻译成自己。 下面这张表里,第一行是 GCN 自己,另外四种方法各换它的一处。 表里的记号统一看:v 是要更新的点,u 是它的某个邻居,Σ_u 表示把每个邻居那一项加起来, d_v、d_u 是两边朋友数 +1(把自己也算上);分号表示把两个向量接在一起;M 负责把邻居的消息拼成一条,U 负责把它并进自己,ε 是一个可学的小数;e_vu 是 u→v 那条边自带的信息(比如友谊亲疏),边没有额外信息就省略。

一张卡,五个地方可以改

汇总邻居 + 乘 W → h′ GCN 按朋友数 开根号加权 GraphSAGE 朋友太多 只抽几个 GAT 每个朋友给一个 「该听多少」 MPNN 连边上也带 信息 GIN 平均换成 求和
方法它把卡上哪一处换了一行公式年份
GCN(图卷积网络) 平均时按两边朋友数 +1(把自己也算上)的开根号加权,朋友特别多的点自动说轻一点 h′ = σ( Σ_u W·h_u / √(d_v·d_u) )2017
GraphSAGE 朋友多到听不完,就只随机抽固定几个来听 h′_v = σ( W·[h_v ; 平均(抽到的 h_u)] )2017
GAT(图注意力网络) 不一律平均,给每个朋友算一个「该听多少」的权重 α h′_v = σ( Σ α_vu·W·h_u )2018
MPNN(消息传递网络) 消息不只来自邻居,边上也带信息(比如化学键的类型) m_v = Σ_u M(h_v, h_u, e_vu)
h′_v = U(h_v, m_v)
2017
GIN(图同构网络) 把平均换成求和,让模型分得清更多形状 h′_v = MLP( (1+ε)·h_v + Σ_u h_u )2019

注意 GAT 那一行:给每个朋友一个「该听多少」的权重——那个东西就是 注意力。反过来看,Transformer 就是「每个词都连着每个词」的 GAT: 图里人人互为邻居,谁该听谁全部由数据自己算。所以两章讲的是同一件事,只是一个从图出发,一个从句子出发。

用在哪代表工作它做到了什么
天气GraphCast(Lam 等,2023) 把地球表面铺成图做 10 天全球预报,分辨率 0.25°,一次算完不到 1 分钟; 在事先定好的 1380 个考核指标(各高度、各变量、各预报时长)里,有 90% 比传统数值模式更接近实况
材料GNoME(Merchant 等,2023) 批量筛出 220 万个候选晶体结构,其中 38.1 万个是此前未知的稳定材料
分子性质MPNN 一路的模型 把分子当图算量子化学性质,「消息传递」这个说法就是从那里来的
5

传得太多,会糊成一片

第 2 节已经露过一次马脚:传得越多,猜对的人反而越少。这一节把 GNN 的几笔账算清楚。

猜对率随轮数先升后降(数据和第 2 节同一份)

这笔账什么时候真的会痛换成什么
过度平滑
over-smoothing
任务要靠长距离上的差异(比如找关键人物、分开两个社区)时; 图越大、传得越多,大家的看法越趋同,信息被互相抹掉 常见做法是 2~3 层(Kipf 正文用两层),先试 2 层看验证集再决定要不要加;加残差(把上一层的输出直接加到下一层)或门控(像开关一样决定留多少);回看第 2 节滑块拖到 40 的样子
信息挤在独木桥上
over-squashing
图有「细腰」:两头很多点,中间只有一两条边。远处的消息全要从这里过, 就像下班高峰只开一个闸口 重新布线、加一个和所有点都相连的虚拟节点,或改用全连接的注意力(就是第 4 节那条回链)
有些形状它分不出 两个三角形和一个六边形,每个点都恰好 2 个朋友,这套规则给它们的读数完全一样, 但它俩是不同的分子 换聚合函数(把邻居汇总起来的那一步;GIN 用求和)、加边上或点上的额外特征;见下面那张小图
大图算不动 图有上亿个点、边还在长:一个点的三步邻居可能是几百万人,整张邻接矩阵根本放不下 邻居采样(GraphSAGE)、把大图切成小块(子图采样),拆成小批来练

互动 · 两个三角形和一个六边形,读数永远一样

第 0 轮

每个点都恰好有 2 个朋友,一开始的值又一样,于是「平均」这一步在两张图上算出完全相同的结果。 一个分子是两个三元环还是一个六元环,化学性质天差地别;最朴素的 GNN 看不出—— 这是 GIN 把平均换成求和的理由(第 4 节表里最后一行)。

6

小结

这一章站在「② 没有免费午餐」上:它先把「编号不重要、只看谁和谁连着」写成一条假设。 这条假设帮它只用两个标签猜对 33 个人,也让它分不出两个三角形和一个六边形。它同时站在 ⑥ 层层组合上:传 k 轮 = 叠 k 层。

它对应哪条线 ② 没有免费午餐——它先认定「编号不重要,只看谁和谁连着」。 这个假设是它全部本事的来源:第 2 节只用两个人的标签就猜对了 33 个人; 同一个假设也让它分不出两个三角形和一个六边形(第 5 节)。它同时站在 ⑥ 层层组合上: 传 k 轮 = 叠 k 层,每多一层多听一步远
一句话 每个点每一轮听一听邻居、改一改自己;传几轮,就能听到几步以内的点。 它把「谁和谁连着」直接写进计算,而不是先排成一行、再把顺序忘掉
它牺牲了什么 传得远就糊成一片,传得近又听不到远处——「传几轮」没有两全的答案。 换编号不变也有代价:有些形状它天生分不出来
🎬 自己验一遍

回第 2 节,把「传几轮」滑块从 3 拖到 40:猜对的人数从 33 人掉到 17 人,图上颜色一点点糊成一片。

再去第 5 节点几下「传一轮」:左边两个三角形和右边一个六边形,读数永远一模一样——那是这套规则的天花板。

它在暗线里站在哪

暗线这一章的回答
A 信息流动 / 它假设了什么 数据是「点 + 边」,信息沿边走:传 k 轮,一个点就听到 k 步以内所有邻居的消息(第 3 节)。 它假设「谁和谁连着」比「编号顺序」重要(置换不变),也假设消息只来自邻居(局部性)—— 比 Transformer 省,但也比 Transformer 看不见远处
C 参数账本 输入特征是每个点一行。第 M 节这里每个点用一个 34 维的独热编码(自己的那一维是 1,其余是 0), 两层 W 的大小由特征维度决定,是 34×4 和 4×2,一共 34×4 + 4×2 = 144 个参数; 34 个点共用同一套 W。但换更多点时特征维度也要跟着变,所以真实任务里用点自带的特征,而不是独热。
D 跑在什么上 带宽受限的那一类。图是不规则的读写:每个点要捞哪些邻居,事先不整齐, 喂不满张量核心;大图还得先做邻居采样,GPU 常常在等内存而不是等算力

它接住了《线性注意力与替代方案》什么:上一章换算法,这一章换数据——只看连着谁。 它接住了《感受野与下采样》什么:图上「看多远」和 CNN 的「看多大一块」是同一笔账(第 3 节)。 它接住了《注意力机制》什么:GAT 那一行给每个朋友算的权重就是注意力(第 4 节)。

它给后面留了什么:标签很少、关系很多时,把结构写进模型收益最大。下一章《扩散语言模型》换掉的是「生成顺序」先验。

一句话带走图神经网络

图就是「点 + 连线」。GNN 给它的规则只有一条:每一轮,每个点听一听邻居、改一改自己; 传几轮就听到几步以内的点,所以层数本身是个要付代价的选择。

7

拓展阅读

上面讲的都是「够用」的版本。想往下挖,这里有两个入口—— 它们不是必修内容,是给想再往前走一步的读者准备的。

📄 这一章的说法从哪来

💻 工业界怎么写