Part V · 第 17 章 网络架构 · 17.4

图神经网络 (Graph Neural Networks)

机器人的世界由“东西和它们之间的关系”组成:绳子是一串由弹簧连着的质点,腿足机器人是由关节连着的连杆,桌面场景是物体和“在……上面”的关系,多机器人队伍是由无线链路连着的机器人。图神经网络直接把这张图当作输入:在每个节点和每条边上反复运行同一个小网络,让相邻的东西互相传递消息。所以它对任意数量的节点都适用,不在乎节点怎样编号,还能学会物理:本节就在浏览器里现场训练一个绳子与布料的模拟器。

约 40 分钟 前置:17.1 MLP 与 CNN · 17.3 Transformer 与 Attention · 16.3 反向传播 6 个交互

    1为什么机器人需要它

    前面几节的网络各自假设了输入的“形状”。MLP 要一个长度固定、顺序固定的向量;CNN 要规则的像素网格;Transformer 要一串 token,并让每个 token 都能看到所有其他 token。可机器人遇到的很多数据是另一种形状:

    • 可变形物体:绳子、布料、面团可以看成许多质点(或网格顶点),相邻的质点之间有力。
    • 机器人本体:连杆和关节组成一棵树(7.1 节);四足、六足和蛇形机器人的树长得不一样。
    • 场景:物体和它们之间的关系(“杯子在桌上”),也就是 15.3 节讲的三维场景图。
    • 多机器人:每台机器人只能和通信范围内的邻居交换信息。
    • 点云:激光雷达的点和它附近的点(12.1 节)。

    这些数据有三个共同点:东西的数量会变(6 段绳子还是 12 段,4 条腿还是 6 条);东西的编号是随意的(谁是 1 号质点不影响物理);相互作用主要是局部的(一个质点只被和它相连的弹簧拉)。把它们拼成一个长向量喂给 MLP,这三点全都违反了:换个大小网络就要重训,换个编号输出就变,而且网络得从数据里自己猜出谁和谁相连。

    图神经网络(GNN)把图本身当作输入。它在每条边上运行同一个“消息函数”,在每个节点上运行同一个“更新函数”,重复几轮。这样得到的网络对任意大小的图都能用,对节点编号天然不敏感,而且只让相连的东西直接对话。本节先看消息传递在做什么(FIG 1),再现场训练一个学出来的绳子模拟器(FIG 2),然后看置换等变性、图注意力 GAT、Transformer 与 GNN 的关系,以及层数太多时的“过平滑”。

    2直觉:每一层,节点和邻居说一次话

    每个节点 \(i\) 带一个特征向量 \(\mathbf h_i\)(对绳子是质点的速度,对机器人是关节角,对物体是它的类别和位置)。GNN 的一层做三件事:

    1. 发消息:每条边 \(j\to i\) 用同一个小网络 \(\phi\) 算出一条消息 \(\mathbf m_{ij}=\phi(\mathbf h_i,\mathbf h_j)\)。
    2. 汇总:节点 \(i\) 把来自所有邻居 \(\mathcal N(i)\) 的消息加起来(或取平均、取最大)。加法不在乎顺序,这一点后面很关键。
    3. 更新:用另一个共享的小网络 \(\psi\) 把汇总结果和自己原来的状态合成新的 \(\mathbf h_i\)。

    一层之后,节点只“听说”了它的直接邻居;两层之后,邻居已经带着邻居的邻居的消息,于是信息传了两跳。\(L\) 层 GNN 里,节点 \(i\) 的输出只依赖于 \(L\) 跳以内的节点:这就是它的感受野,和 CNN 每加一层感受野就变大(17.1 节)是同一回事。下图用最简单的、没有任何可学参数的消息传递来看这个过程:每个节点的新值是它自己和所有邻居的平均。我们只在一个“源”节点 s 放入 1,其余为 0,看这个信号怎样一层一层扩散。

    FIG 1消息传递:L 层 = L 跳
    14 个节点、19 条边的图。点击节点可以设定源 s(琥珀色粗圈)或目标 t(紫色粗圈),由上方的选择器决定点击设定哪一个。每个节点里琥珀色圆盘的面积正比于它在第 \(L\) 层的值(相对于当前最大值);没有圆盘就是值为 0,信号还没到。琥珀色粗边是第 \(L\) 层真正传递了非零消息的边。紫色虚线圈标出目标 t 的感受野:距离 t 不超过 \(L\) 跳的节点。源落进这个区域,目标才会亮。
    试一试
    • 选一对相距至少 4 跳的源和目标(默认那一对相距 5 跳),找出让目标刚好亮起来的最小层数 \(L\):它正好等于两者之间的跳数。
    • 找一个源,使得只用 3 层就能让全部 14 个节点都亮起来。(只有一个节点做得到:图的“中心”。)
    核心洞见

    GNN 由局部规则定义:每个节点只和邻居交换消息,规则在所有节点、所有边上共享,就像 CNN 在所有像素上共享同一个卷积核。共享带来两样好处:参数个数和图的大小无关;图里某处学到的规律,在别处、甚至在更大的图上也能用。代价是:信息每层只能走一跳,远处的东西要很多层才能互相影响。

    3动手:现场训练一个“学出来的模拟器”

    给真实的绳子、布料或面团写一个准确的物理模型很难,参数也难测。另一条路是让网络从数据里学会“下一步会怎样”,再像模拟器一样一步步滚动预测,这类模型叫学出来的模拟器(learned simulator),学动力学模型的一般方法见 24.1 节。GNN 特别适合做这件事,因为物理本来就是局部的:一个质点的加速度只取决于和它相连的弹簧。

    下面的“真实世界”是一根质点-弹簧绳:每个质点质量为 1,弹簧刚度 \(K=400\)(单位质量下为 N/m),静止长度 \(L_0=0.4\) m,有重力和速度阻尼 \(1.5\,\mathrm{s^{-1}}\),第一个质点被钉住(可以拖动)。图的节点是质点,边是弹簧。GNN 只做一轮消息传递:

    • 每条边用两质点的相对位移 \(\mathbf d_{ij}=\mathbf x_j-\mathbf x_i\) 算出一条消息 \(\mathbf m_{ij}\)(可以理解为“弹簧对 \(i\) 的拉力”,但网络并不知道有弹簧这回事)。
    • 节点把所有消息加起来,再加上一个只看自己速度的项 \(\psi(\mathbf v_i)\)(让它学会重力和阻尼),得到加速度 \(\hat{\mathbf a}_i\)。
    • 用半隐式欧拉法积分(\(\Delta t=1/240\) s,2.5 节)得到下一时刻的状态,再把它喂回 GNN:这就是“滚动”(rollout)。

    训练数据是 600 个随机形状、随机速度的6 质点绳子快照,损失是预测加速度和真实加速度之间的均方误差(16.1 节的监督回归)。我们同时训练两种边网络,它们只在一点上不同:通用版 \(\mathbf m_{ij}=\mathrm{MLP}(d_x,d_y,\|\mathbf d\|)\in\R^2\);等变版先只用长度算一个标量,再沿弹簧方向放出去,\(\mathbf m_{ij}=\mathrm{MLP}(\|\mathbf d\|)\,\mathbf d/\|\mathbf d\|\)。两者都只用相对位置,所以整根绳子平移时预测不变;等变版还保证:整根绳子旋转,消息跟着一起旋转。

    FIG 2学出来的模拟器:在 6 质点绳子上训练,在别的图上滚动
    左:紫色空心圈和粗线是真实物理,琥珀色是通用 GNN 的滚动预测,蓝色方块是等变 GNN 的滚动预测;三者从同一个初始状态出发,钉点由你拖动的圆形手柄决定(布料有两个钉点,一起移动)。真实绳子里拉伸超过 1.6 \(L_0\)(训练数据里最长的弹簧)的那一段会变成红色。训练在后台进行,滚动用的始终是当前的权重。右:两个模型在 100 个未见过的 6 质点快照上的相对加速度误差(对数坐标),虚线是 5%。“偏差”是同一时刻预测质点与真实质点的平均距离;“静止”指真实绳子和等变绳子的动能都低于 \(10^{-3}\)。如果某个模型的绳子数值发散,它会被重置到真实状态,并记一次“重置”。
    • 按“训练”:等变模型大约 100 步就把测试误差压到 3% 以下;通用模型要大约 1700 步才降到 5% 以下(视电脑快慢,几秒到半分钟)。等到通用模型也低于 5%。
    • 两个模型都训练好以后(通用模型低于 5%),保持 6 质点绳子,按“释放”,等它停下来:等变绳子停在离真实绳子 1 cm 以内的地方,通用绳子通常差好几厘米甚至更多。
    • 切换到“布料 3×4”(12 个质点,每个有 2 到 4 个邻居,两个钉点:训练里从没见过这样的图)。在等变模型误差低于 3% 时释放并等它静止:等变布料的偏差仍在 1 cm 以内。
    值得注意的几件事

    (1) 同一个网络,换一张图照样能用:模型只在 6 质点的绳子上训练过,却能直接模拟 12 质点的绳子和一块布,因为它学的是“一根弹簧怎样拉一个质点”这条局部规律,而布料只是把同样的局部片段换了一种拼法。MLP 做不到这一点:它的输入长度就是 6 个质点。 (2) 对的对称性比更多的数据管用:等变模型只需要学一个一维函数(拉力随长度怎样变),通用模型却要在每个方向上分别学会“拉力沿着弹簧”。两者的单步误差都只有几个百分点时,静止形状的差别仍然很大:挂着的绳子对横向的力很敏感,单步预测里方向上一点点的偏差,就会让它歪出几厘米。 (3) 局部规律只在训练见过的范围里可靠:切到 12 质点绳子,让它静止下来,最上面的弹簧被下面 11 个质点拉长到约 1.67 \(L_0\),超过了训练数据里最长的 1.6 \(L_0\)(红色那一段)。这里等变模型的偏差明显更大:训练早期有几厘米(100 步时约 6 cm),要再训练几千步才缩到 1 cm 左右。

    4另外几个视角:编号、注意力、Transformer 与层数

    置换等变:一个策略,控制许多种身体

    给图的节点重新编号,图本身并没有变。GNN 的每一步都只用“我的邻居是谁”和“加起来”,不用“我是第几号”,所以重新编号之后,每个节点的输出原封不动地跟着它走:这叫置换等变(permutation equivariance)。如果再把所有节点的输出加起来得到整张图的一个向量(readout),这个向量连跟着走都不用,完全不变:置换不变。

    这对机器人的意义是:同一个 GNN 策略可以读入任意一种身体的“关节图”,为每个关节输出一个力矩。下图里的策略是一个随机初始化的两层消息传递网络(没有训练,我们只关心它的结构性质):节点特征是关节类型(躯干、髋、膝、踝或蛇的体节,独热编码)加上关节角和角速度,关节角随时间按步态变化。作为对比,旁边是一个把所有关节特征按编号顺序拼起来的 MLP 策略。

    FIG 3重新编号:GNN 的输出跟着关节走,MLP 的不会
    每个圆是一个关节(节点),里面的数字是它当前的编号,灰色粗线是连杆(边)。每个关节旁有两根条:上面蓝色是 GNN 策略给这个关节的力矩,下面红色是 MLP 策略给的(向右为正)。按“打乱编号”会暂停步态,并用空心框留下打乱前的力矩,方便比较:蓝条落回自己的框里,红条却跳到别处。右侧读数给出打乱前后同一个物理关节的力矩最大变化,以及两种策略的参数个数。
    • 在至少 3 种身体上各按一次“打乱编号”:GNN 的力矩变化每次都是 0(最多是 \(10^{-16}\) 量级的浮点舍入),MLP 的变化则是 1 的量级;GNN 的参数个数始终是 893,MLP 的参数个数随关节数变化,换一种身体就得重新训练。

    等变性也有另一面:GNN 分不清两个“看起来一样”的节点。如果四条腿的特征完全相同,它们必然得到完全相同的力矩,网络不可能让左前腿和右后腿做不同的事。所以真实的形态学策略会给节点加上能区分它们的特征,比如关节类型、关节在身体上的位置、或者它在树里的深度(这里用的是类型,加上各关节在步态里不同的相位)。

    GCN 与 GAT:固定权重还是学出来的权重

    汇总邻居时,每个邻居该占多大比重?图卷积网络(GCN,Kipf 与 Welling,2017)的答案由图的结构决定:每个邻居(连同自己)按度数归一化后的固定权重,平均下来大致是 \(1/(d_i+1)\),\(d_i\) 是节点的度数。图注意力网络(GAT,Veličković 等,2018)则让网络自己决定:对每条边算一个分数,在邻居之间做 softmax,得到权重 \(\alpha_{ij}\),这和 17.3 节的注意力是同一个机制,只是每个节点只能注意它的邻居。

    什么时候这个区别要紧?看一个编队任务:一群机器人里,每台跟随者都要输出领队广播的速度指令 \(s\)。它的邻居里恰好有一台领队,其余是其他跟随者,各自也报着自己的 \(s\)(干扰项)。节点特征是 \([b_j,\ s_j]\),领队的 \(b_j=1\),其余为 0。下面同时训练一个单层 GCN 和一个单层 GAT,两者的消息变换和输出层完全一样,唯一的区别是权重来源:GCN 用均匀权重,GAT 用学出来的注意力。每一步用 16 个新的随机样本,邻居数在 2 到 6 之间。

    FIG 4跟随领队:均匀平均做不到,注意力做得到
    左:同一个样本分别交给 GCN(蓝色)和 GAT(琥珀色)。中心是要做决定的跟随者,周围是它的邻居,每个节点旁写着它报出的 \(s\);领队带紫色粗圈和字母 L。边的粗细和旁边的数字是这条边的权重(GCN 是均匀的 \(1/(k+1)\),GAT 是 \(\alpha_{ij}\)),中心节点给自己的权重写在它正下方;每个面板最下方是预测 \(\hat y\) 和目标 \(y\),误差小于 0.05 时显示为绿色,否则为红色。右:300 个固定测试样本上的均方误差(对数坐标)。
    • 按“训练”:几百步内 GAT 的测试误差降到 \(10^{-3}\) 以下,而 GCN 一直停在 0.28 左右(目标 \(s\) 本身的方差是 1/3,GCN 只解释了其中一小部分)。
    • 训练好之后按几次“换一个样本”,找一个至少有 5 个邻居的样本:GAT 给领队的权重仍然超过 0.9,其余边几乎为零。

    为什么 GCN 学不会?它的输出是邻居特征的固定加权平均再做变换,领队的 \(s\) 只占其中 \(1/(k+1)\),而且混着其他跟随者的 \(s\):网络无法根据“是否领队”这个特征去调整权重,因为权重根本不由特征决定。GAT 的分数函数看得到这个特征,只要给“是领队”很大的分数,softmax 就把几乎全部权重给它。这不是说 GCN 没用:当邻居都同样重要(比如平滑一个传感器场,或者网格上的扩散)时,固定权重正合适,而且更便宜、更稳定。

    Transformer 是完全图上的 GNN

    把 GAT 的“只注意邻居”去掉,让每个节点注意所有节点,就得到了 17.3 节的自注意力层:Transformer 就是在完全图上做消息传递的 GNN,注意力权重就是边上的权重。反过来,一个 GNN 也可以看成一个带“掩码”的 Transformer:不相连的节点对的注意力分数被设成 \(-\infty\),softmax 之后权重为 0。区别就在于这张图从哪里来:GNN 把“谁和谁有关”作为先验写死在图里,Transformer 让网络自己去学。

    下图有 10 个 token(可以想成场景里的 10 个物体,位置可拖动),图由半径 \(r\) 决定:距离不超过 \(r\) 的两个 token 之间有边。右边是 \(10\times10\) 的注意力矩阵,每一行是一个 token 对其他 token 的权重。两种分数:局部分数 \(e_{ij}=-\|\mathbf p_i-\mathbf p_j\|^2/2\),近的物体互相关注,类似物理相互作用;非局部分数 \(e_{ij}=1.2\,x_j\),所有人都去看最东边的那个物体(像所有机器人都盯着同一个目标)。

    FIG 5注意力加掩码 = GNN;去掉掩码 = Transformer
    左:token 与半径图,悬停或拖动一个 token,它那一行在右边的矩阵里会被框出来,它的半径用青色虚线圆画出。右:注意力矩阵,行是“谁在看”,列是“被看的”。每个格子里琥珀色方块的面积正比于掩码之后的权重;被掩码去掉的格子只画一个小点(悬停公式里的 \(M_{ij}\) 时变成红色叉)。“丢失的注意力”是:如果不加掩码(完全图),这一行本该分给图外 token 的那部分权重。
    • 用“局部”分数,调半径使得算的格子少于一半(少于 50 个),同时每一行丢失的注意力都不到 5%:掩码几乎不损失什么,却省了一半以上的计算。
    • 保持同样少的格子(少于 50 个),换成“非局部”分数:平均每行丢失的注意力超过 30%。局部的图在这里成了错误的先验。

    这就是选 GNN 还是 Transformer 的核心权衡。如果相互作用真的是局部的(弹簧、接触、相邻的点),图是一个好先验:计算量随边数线性增长而不是 \(n^2\),数据也省。如果重要的关系可能出现在任意两个东西之间(一句话里相距很远的两个词,一个机器人策略里“看到的物体”和“要动的关节”),完全图更安全,代价是 \(O(n^2)\) 的计算。完全图里没有结构信息,所以 Transformer 必须靠位置编码知道 token 之间的关系;图 Transformer 常用图拉普拉斯矩阵的特征向量或随机游走统计量作为节点的位置编码,把图的结构以“软”的方式交还给它。

    层数太多:过平滑

    既然 \(L\) 层只能看到 \(L\) 跳,那把层数加到很多不就行了?问题是:每一层都在对邻居做平均,而反复平均会把所有节点的特征拉到同一个值,就像热量在一块金属里扩散到处处同温。这叫过平滑(oversmoothing)。下图是两个社区(各 10 个节点,圆形和方形)组成的图,社区内部连得紧,之间只有 7 条桥(紫色虚线)。初始特征是“社区 A 为 +1,B 为 −1”再加噪声,然后反复做 FIG 1 那样的均值聚合。

    FIG 6过平滑:先去噪,再把一切抹平
    左:社区 A 是圆形节点,B 是方形节点。节点里圆盘的面积正比于特征的绝对值(相对于初始特征的最大绝对值),琥珀色为正、青色为负。右:随层数 \(L\) 变化的两个量(对数坐标):紫色是两个社区平均值之差(“社区差”,这是我们想保留的信号),绿色是社区内部的标准差(“社区内离散”,主要是噪声);虚线是 \(\lambda_2^L\) 乘以初始的社区差,竖线是当前的 \(L\)。滑块 \(\alpha\) 加入“初始残差”:每一层把一部分原始特征重新混进来(APPNP 的做法)。
    • \(\alpha=0\) 时把层数拉到让社区差跌破初始值的 1%(需要 54 层以上):圆盘几乎消失,两个社区再也分不开。注意前 2 层:社区内离散从 0.61 降到 0.28,而社区差只从 1.96 降到 1.50,几层平均其实是在去噪。
    • 把 \(\alpha\) 设到 0.1 或以上,再把层数拉到 64:社区差停在初始值的一半左右,不再随层数衰减。
    一个想法,几种看法

    卷积:CNN 是规则网格图上的 GNN,但它更强一点:卷积核对“左边的邻居”和“右边的邻居”用不同的权重,而普通 GNN 只能对所有邻居用同一个函数,除非边特征里带着方向(FIG 2 的相对位移就是这样的边特征)。 集合:没有边的 GNN(每个节点只和自己说话,最后求和)就是 Deep Sets,PointNet 用最大值池化做点云分类也是这种置换不变的结构。 注意力:GAT 是带掩码的注意力,Transformer 是完全图上的 GAT(FIG 5)。 概率推断:因子图上的置信传播也是“沿着边传消息、在节点上汇总”,GNN 可以看成把手写的消息规则换成了学出来的网络。 扩散:一层均值聚合是图上的一步热扩散,过平滑就是扩散到了稳态(FIG 6)。

    5再看数学

    提示:把鼠标悬停在公式中带底色的符号上,图中对应的元素会被高亮(邻居、感受野、消息、编号、注意力权重、掩码、\(\lambda_2\) 曲线)。

    图与消息传递

    图 \(G=(\mathcal V,\mathcal E)\) 有 \(n\) 个节点,邻接矩阵 \(A\in\{0,1\}^{n\times n}\)(\(A_{ij}=1\) 表示 \(i,j\) 相连),节点特征按行堆成 \(X\in\R^{n\times d}\),边可以有特征 \(\mathbf e_{ij}\)(比如相对位移)。记 \(\mathbf h_i^{(0)}=\mathbf x_i\)。一般的消息传递神经网络(MPNN,Gilmer 等,2017)的第 \(l\) 层是

    $$ \mathbf m_{ij}^{(l)}=\phi^{(l)}\big(\mathbf h_i^{(l)},\mathbf h_j^{(l)},\mathbf e_{ij}\big),\qquad \mathbf h_i^{(l+1)}=\psi^{(l)}\Big(\mathbf h_i^{(l)},\ \bigoplus_{j\in\hl{nbr}{\mathcal N(i)}}\mathbf m_{ij}^{(l)}\Big) $$

    \(\phi\) 和 \(\psi\) 是小 MLP,在所有边、所有节点上共享;\(\bigoplus\) 是对邻居的求和、平均或最大值,任何“与顺序无关”的运算都行。反复代入可知 \(\mathbf h_i^{(L)}\) 只依赖于 \(\hl{rf}{\mathcal N_L(i)}=\{j:\operatorname{dist}(i,j)\le L\}\) 里的输入:这就是 FIG 1 的感受野。FIG 1 的无参数版本是 \(\phi(\mathbf h_i,\mathbf h_j)=\mathbf h_j\)、\(\bigoplus\) 取和、\(\psi\) 除以 \(\deg(i)+1\),整层写成矩阵就是 \(H^{(l+1)}=\tilde D^{-1}\tilde AH^{(l)}\),其中 \(\tilde A=A+I\) 加了自环,\(\tilde D\) 是 \(\tilde A\) 的度数对角阵。

    FIG 2 的学出来的模拟器是 \(L=1\) 的特例(Battaglia 等的 interaction network 正是这种“边算作用、节点汇总”的结构):

    $$ \hat{\mathbf a}_i=\hl{msg}{\sum_{j\in\mathcal N(i)}\phi(\mathbf x_j-\mathbf x_i)}+\psi(\mathbf v_i),\qquad \mathcal L(\theta)=\frac{1}{|\mathcal D|}\sum_{(X,V)\in\mathcal D}\ \frac{1}{|\mathcal F|}\sum_{i\in\mathcal F}\big\|\hat{\mathbf a}_i-\mathbf a_i\big\|^2 $$ $$ \phi_1(\mathbf d)=\mathrm{MLP}(d_x,d_y,\|\mathbf d\|),\qquad \phi_2(\mathbf d)=\mathrm{MLP}(\|\mathbf d\|)\,\frac{\mathbf d}{\|\mathbf d\|}\ \ \Rightarrow\ \ \phi_2(R\mathbf d)=R\,\phi_2(\mathbf d)\ \ \forall R\in\mathrm{SO}(2) $$

    真实加速度是 \(\mathbf a_i=\sum_j K(\|\mathbf d_{ij}\|-L_0)\,\mathbf d_{ij}/\|\mathbf d_{ij}\|+\mathbf g-c\,\mathbf v_i\),其中 \(\mathcal D\) 是训练快照的集合,\(\mathcal F\) 是没被钉住的质点;\(\phi_1\) 是通用版,\(\phi_2\) 是等变版。等变版只需要学会一维函数 \(K(\|\mathbf d\|-L_0)\)。滚动时 \(\mathbf v\leftarrow\mathbf v+\Delta t\,\hat{\mathbf a}\),\(\mathbf x\leftarrow\mathbf x+\Delta t\,\mathbf v\)。悬停 \(\sum_j\phi\) 会在 FIG 2 里画出等变模型在每个质点上的消息之和(绿色箭头)。

    置换等变与不变

    重新编号用置换矩阵 \(P\) 表示:特征变成 \(PX\),邻接矩阵变成 \(PAP^\top\)。设 \(F\) 是一层(或多层)GNN,输出每个节点一行。则

    $$ F\big(\hl{perm}{P}X,\ PAP^\top\big)=P\,F(X,A),\qquad r(X,A)=\sum_{i}F(X,A)_i\ \Rightarrow\ r\big(PX,PAP^\top\big)=r(X,A) $$

    左式是等变:输出跟着节点一起重排;右式是不变:读出完全不动。证明只要一行:节点 \(i\) 的新状态由它自己的特征和多重集 \(\{\mathbf h_j:j\in\mathcal N(i)\}\) 决定,重新编号不改变这个多重集,而 \(\bigoplus\) 不在乎元素的顺序。MLP 策略 \(f(\operatorname{vec}(X))\) 没有这个性质:它的第一层把第 1 个关节的特征乘上第 1 组权重,重新编号就换了一组权重,FIG 3 里的红条就是这样跳走的。

    GCN、GAT 与 Transformer

    $$ H^{(l+1)}=\sigma\big(\tilde D^{-1/2}\tilde A\,\tilde D^{-1/2}H^{(l)}W^{(l)}\big) $$ $$ \hl{alpha}{\alpha_{ij}}=\frac{\exp\big(\mathrm{LeakyReLU}(\mathbf a^\top[W\mathbf h_i\,\|\,W\mathbf h_j])\big)}{\sum_{k\in\mathcal N(i)\cup\{i\}}\exp\big(\mathrm{LeakyReLU}(\mathbf a^\top[W\mathbf h_i\,\|\,W\mathbf h_k])\big)},\qquad \mathbf h_i'=\sigma\Big(\sum_{j\in\mathcal N(i)\cup\{i\}}\alpha_{ij}W\mathbf h_j\Big) $$ $$ \alpha_{ij}=\operatorname{softmax}_j\Big(\frac{\mathbf q_i^\top\mathbf k_j}{\sqrt{d}}+\hl{mask}{M_{ij}}\Big),\qquad M_{ij}=\begin{cases}0, & j\in\mathcal N(i)\cup\{i\}\\ -\infty, & j\notin\mathcal N(i)\cup\{i\}\end{cases} $$

    三行依次是 GCN、GAT 和带掩码的注意力。GCN 的权重 \(1/\sqrt{\tilde d_i\tilde d_j}\) 只由度数决定;GAT 的权重 \(\alpha_{ij}\) 由特征算出,\([\cdot\|\cdot]\) 是拼接,\(\mathbf a\) 是可学的打分向量,实际中还会像 Transformer 一样用多个“头”并行再拼接。最后一行把 17.3 节的注意力写成了 GNN:\(M\equiv0\) 时就是完全图,也就是普通的 Transformer 层;\(M\) 按图取 0 或 \(-\infty\) 时就是在图上做注意力。悬停 \(\alpha_{ij}\) 会在 FIG 4 里高亮 GAT 的权重标签,悬停 \(M_{ij}\) 会在 FIG 5 里把被掩码的格子标红。FIG 4 的 GAT 打分正是上式(多一个偏置项),只是 LeakyReLU 负半轴的斜率取 0.01,而不是原论文的 0.2;FIG 4 的 GCN 用的是均值形式的均匀权重 \(1/(k+1)\),而不是对称归一化。每层的计算量:GCN 和 GAT 都是 \(O(|\mathcal E|)\),完全图上的注意力是 \(O(n^2)\)。

    表达能力:求和、平均、最大值不一样

    聚合函数决定 GNN 能区分哪些邻域。设一个节点的邻居特征多重集是 \(\{a\}\),另一个是 \(\{a,a\}\):平均和最大值给出一样的结果,求和却不同(\(a\) 对 \(2a\));多重集 \(\{a,b\}\) 与 \(\{a,a,b,b\}\) 平均值相同,\(\{a,b\}\) 与 \(\{a,b,b\}\) 最大值相同。Xu 等(2019)证明,只靠消息传递的 GNN 区分不同图的能力最多和 Weisfeiler-Lehman(1-WL)图同构测试一样强,而用“求和 + MLP”的 GIN 能达到这个上限。所以当“有几个”很重要时(几个接触点、几个邻居),用求和;FIG 2 正是这样:弹簧力是加起来的,平均就错了。

    过平滑的谱解释

    没有可学权重时,\(L\) 层均值聚合就是 \(H^{(L)}=P^LX\),\(P=\tilde D^{-1}\tilde A\)。\(P\) 与对称矩阵 \(\tilde D^{-1/2}\tilde A\tilde D^{-1/2}\) 相似,特征值都是实数,落在 \((-1,1]\) 里(加了自环之后最小的也大于 \(-1\));连通图的最大特征值 \(\lambda_1=1\),对应的特征向量是全 1 向量。把初始特征按特征向量展开:

    $$ P^L\mathbf x=c_1\mathbf 1+\sum_{k\ge2}c_k\lambda_k^L\mathbf u_k\ \xrightarrow{L\to\infty}\ c_1\mathbf 1,\qquad \big\|P^L\mathbf x-c_1\mathbf 1\big\|=O\big(|\hl{lam2}{\lambda_2}|^L\big) $$ $$ \mathbf h^{(l+1)}=(1-\alpha)P\,\mathbf h^{(l)}+\alpha\mathbf x\ \ \Rightarrow\ \ \mathbf h^{(\infty)}=\alpha\big(I-(1-\alpha)P\big)^{-1}\mathbf x $$

    所有节点收敛到同一个值 \(c_1\),差别以 \(|\lambda_2|^L\) 的速度消失。FIG 6 的图里 \(\lambda_2=0.919\),\(\lambda_3=0.643\):社区差几乎全部落在 \(\lambda_2\) 对应的特征向量上(它的正负号大致把两个社区分开,这就是谱聚类的道理),所以每层只衰减 8%;社区内的噪声多半落在 \(\lambda_3\) 及以后的特征向量上,衰减快得多。这解释了“先去噪、再抹平”:前几层有益,之后有害。社区之间连得越紧,\(\lambda_2\) 越小,过平滑来得越早。第二行是带初始残差的版本(APPNP,即个性化 PageRank),它的不动点不再是常数向量,所以社区差留了下来。悬停 \(\lambda_2\) 会加粗 FIG 6 里的虚线。真实的 GNN 每层还有权重和非线性,分析更复杂,但同样的现象在实践中很常见;常用的对策是残差连接、归一化,以及干脆不用太多层,让远处的信息通过别的途径(比如一个连到所有节点的“虚拟节点”或全局注意力)传过来。

    图本身是模型的一部分

    同一组数据可以连成很多种图:按半径连、按 k 近邻连、按网格拓扑连、全部连上。选哪种图就是在选先验:它决定了谁能直接影响谁、要几层才传得到、计算量有多大。学出来的模拟器里,边往往还会随状态变化(两块物体靠近时临时加一条“碰撞边”),图要每一步重新构建。

    6机器人中的它

    在机器人里,GNN 主要出现在四类问题上,它们恰好对应本节的几个图:可变形物体与粒子的动力学(FIG 2),可变形态的身体(FIG 3),多机器人和场景里的关系(FIG 4、FIG 5),以及点云这类没有天然顺序的数据。

    真实系统里

    学出来的模拟器:Interaction Networks(Battaglia 等,NeurIPS 2016)提出了“边算作用、节点汇总”的结构;Sanchez-Gonzalez 等(ICML 2018)用图网络学习 MuJoCo 里各种身体的动力学,并用于基于模型的控制;GNS(Sanchez-Gonzalez 等,ICML 2020)把流体、沙子、黏性材料表示为粒子,用按半径连接的图和多轮消息传递预测加速度,能推广到比训练时多得多的粒子;它在训练时给输入加随机游走噪声,让模型学会纠正自己滚动中的误差。MeshGraphNets(Pfaff 等,ICLR 2021)在网格上做同样的事,模拟布料和弹性体,并在两块物体靠近时临时加上“世界空间”的边来处理碰撞。 机器人操作可变形物体:DPI-Net(Li 等,ICLR 2019)学习粒子动力学并用于操作刚体、可变形物体和流体;RoboCraft(Shi 等,RSS 2022)用 GNN 粒子模型加模型预测控制(13.4 节)去捏塑面团。 形态学策略:NerveNet(Wang 等,ICLR 2018)把强化学习策略写成身体图上的 GNN,可以迁移到不同大小的身体;Shared Modular Policies(Huang、Mordatch、Pathak,ICML 2020)用一个在所有肢体上共享的模块化策略同时控制多种形态;后来的 AMORPHEUS(Kurin 等,ICLR 2021)发现,在所有肢体之间做注意力的 Transformer 往往比只沿身体图传消息更好:这正是 FIG 5 讲的“图是先验,可能太强”。 多机器人:Li、Gama、Ribeiro、Prorok(IROS 2020)用 GNN 让每台机器人只和通信范围内的邻居交换特征,学出分布式的多机器人路径规划。 场景与点云:三维场景图(15.3 节)的节点和边可以直接交给 GNN 做推理;DGCNN(Wang 等,ACM TOG 2019)在点云上动态地建 k 近邻图再做消息传递;PointNet(Qi 等,CVPR 2017)则是不连边、只做置换不变池化的极端情形。 软件:PyTorch Geometric、DGL 和 Jraph(JAX)都提供“边列表 + 散射求和”的消息传递原语,本页的实现就是这种写法的最小版本。

    和 Part IV 的联系也值得一提:15.2 节的位姿图也是一张图,节点是位姿,边是相对测量,但那里的“消息”(雅可比、信息矩阵)是从测量模型推导出来的,求解是一个最小二乘问题。GNN 用同样的图结构,只是让消息规则从数据里学出来。两者可以结合:用 GNN 预测因子图里的测量或权重,再交给经典优化器求解。

    7常见误区

    误区 1:用平均或最大值,却需要“数个数”

    平均聚合分不清“一个邻居”和“两个一样的邻居”,最大值聚合分不清“一个 b”和“两个 b”(第 5 节)。如果输出依赖于邻居的数量,比如合力、接触点数、一个物体被多少东西压着,就要用求和。反过来,求和的输出会随度数变大,度数差别很大的图(一个中心节点连着几百个邻居)上需要归一化或用平均,否则数值会爆掉。选聚合函数时先问:这个量在物理上是加起来的,还是取平均的?

    误区 2:想靠堆层数看得更远

    \(L\) 层只能看 \(L\) 跳,但层数一多就过平滑(FIG 6)。另一个问题叫过度挤压(over-squashing,Alon 与 Yahav,ICLR 2021):远处成指数增长的大量节点,信息全都要挤过少数几条边、压进一个固定长度的向量里。所以需要长程信息时,不要只加层:用残差或初始残差,加一个连到所有节点的虚拟节点,加几条“捷径”边,或者在 GNN 之外再加全局注意力。

    误区 3:单步误差小,就以为滚动也准

    学出来的模拟器在训练时只看单步,滚动时却把自己的预测当输入,误差会累积,状态还会漂到训练从没见过的区域(FIG 2 的 12 质点绳子,最上面的弹簧超出了训练范围)。FIG 2 的通用模型单步误差只有几个百分点,静止形状却能差好几厘米。常用的对策有:训练时给输入加噪声(GNS),用多步滚动的损失训练,把训练数据的分布做宽,以及像等变模型那样把已知的对称性直接写进结构。评估模拟器时,一定要看长时间滚动的结果,而不只是单步误差。

    误区 4:输入用绝对坐标

    如果把每个质点的绝对位置 \(\mathbf x_i\) 当节点特征,网络就得在每个位置分别学一遍物理:在训练区域外(比如把钉点拖到别处),预测会失效。物理定律只依赖相对位置,所以应该把 \(\mathbf x_j-\mathbf x_i\) 放在边上(平移不变),把真正属于节点本身的量(速度、质量、材料类型)放在节点上。同理,重力这种有方向的外场是“破坏旋转对称”的,要作为单独的输入给出,不能指望等变结构自己猜出来。

    误区 5:给节点加编号来“区分”它们

    对称的节点得到相同的输出(FIG 3 的讨论),于是有人把节点编号的独热向量加进特征。这确实能区分节点,但同时破坏了置换等变:模型又依赖编号了,也就无法迁移到大小不同的图。更好的做法是加有物理意义、与编号无关的特征:关节类型、在身体坐标系里的位置、到根节点的深度、左右侧的标志;如果需要真正的“位置编码”,用拉普拉斯特征向量之类由图结构算出的量。

    8小练习

    1. 一个 3 层的 GNN,节点 \(i\) 的输出可能受哪些节点的输入特征影响?
    每层信息走一跳,并且每层都保留节点自己的状态,所以 3 层之后 \(i\) 汇集了 0、1、2、3 跳内所有节点的信息:这是它的感受野 \(\mathcal N_3(i)\)(FIG 1 里的紫色区域)。超过 3 跳的节点无论特征怎样变,都影响不到它。选项 B 只有在图的半径不超过 3 时才成立。
    2. 把一张图的节点重新编号后再输入同一个 GNN。节点级输出和“把所有节点输出求和”的图级读出会怎样?
    这是置换等变 \(F(PX,PAP^\top)=PF(X,A)\) 和置换不变 \(r(PX,PAP^\top)=r(X,A)\),对任何权重都成立,因为每一步只用邻居多重集和与顺序无关的聚合(FIG 3 的蓝条)。选项 D 错在这是结构性质,与权重无关。
    3. 在 FIG 4 的“跟随领队”任务上,单层 GCN 学不会、单层 GAT 学得会。根本原因是什么?
    GCN 确实看得到领队的特征(选项 B 不对),但它只能以固定份额 \(1/(k+1)\) 混进平均值,和其他跟随者的 \(s\) 搅在一起,而且份额随邻居数 \(k\) 变化。GAT 多出的只是一个很小的打分层(选项 A 不是关键),它让权重取决于内容,这正是注意力的意义。
    4. 节点 u 有两个邻居,特征都是 \(a\);节点 v 只有一个邻居,特征也是 \(a\)。哪种聚合能让 GNN 区分 u 和 v 的邻域?
    求和给出 \(2\phi(a)\) 对 \(\phi(a)\),可以区分;平均和最大值都给出 \(\phi(a)\),分不开。这就是 GIN(Xu 等,2019)选择“求和 + MLP”的原因,也是 FIG 2 用求和的原因:两根弹簧的力本来就该加起来。(只要 \(\phi(a)\ne0\),求和就能区分。)
    5. 在一张连通图上反复做均值聚合(没有可学权重)。层数趋于无穷时节点特征会怎样,速度由什么决定?
    \(P=\tilde D^{-1}\tilde A\) 的最大特征值是 1,对应全 1 向量,其余特征值的绝对值都小于 1,所以 \(P^L\mathbf x\to c_1\mathbf 1\),偏差按第二大特征值的 \(|\lambda_2|^L\) 衰减:这就是过平滑。选项 D 描述的是社区差,它确实是最后才消失的部分(沿 \(\lambda_2\) 的方向),但仍会以 \(\lambda_2^L\) 消失;FIG 6 里 \(\lambda_2=0.919\),54 层后社区差不到 1%。

    9延伸阅读

    • F. Scarselli, M. Gori, A. C. Tsoi, M. Hagenbuchner & G. Monfardini, The Graph Neural Network Model, IEEE Transactions on Neural Networks, 2009 — 最早的 GNN 形式之一
    • J. Gilmer, S. S. Schoenholz, P. F. Riley, O. Vinyals & G. E. Dahl, Neural Message Passing for Quantum Chemistry, ICML 2017 — 把各种 GNN 统一成消息传递框架
    • T. N. Kipf & M. Welling, Semi-Supervised Classification with Graph Convolutional Networks, ICLR 2017 — GCN
    • P. Veličković, G. Cucurull, A. Casanova, A. Romero, P. Liò & Y. Bengio, Graph Attention Networks, ICLR 2018 — GAT:边上的注意力
    • K. Xu, W. Hu, J. Leskovec & S. Jegelka, How Powerful are Graph Neural Networks?, ICLR 2019 — 与 WL 测试的关系,求和聚合与 GIN
    • Q. Li, Z. Han & X.-M. Wu, Deeper Insights into Graph Convolutional Networks for Semi-Supervised Learning, AAAI 2018 — 把 GCN 看成拉普拉斯平滑,指出过平滑
    • J. Klicpera (Gasteiger), A. Bojchevski & S. Günnemann, Predict then Propagate: Graph Neural Networks meet Personalized PageRank, ICLR 2019 — APPNP 与初始残差
    • P. W. Battaglia, R. Pascanu, M. Lai, D. Rezende & K. Kavukcuoglu, Interaction Networks for Learning about Objects, Relations and Physics, NeurIPS 2016 — 学出来的物理
    • A. Sanchez-Gonzalez, J. Godwin, T. Pfaff, R. Ying, J. Leskovec & P. W. Battaglia, Learning to Simulate Complex Physics with Graph Networks, ICML 2020 — GNS:粒子模拟器与噪声注入
    • T. Pfaff, M. Fortunato, A. Sanchez-Gonzalez & P. W. Battaglia, Learning Mesh-Based Simulation with Graph Networks, ICLR 2021 — MeshGraphNets:布料与弹性体
    • T. Wang, R. Liao, J. Ba & S. Fidler, NerveNet: Learning Structured Policy with Graph Neural Networks, ICLR 2018 — 身体图上的策略
    • V. G. Satorras, E. Hoogeboom & M. Welling, E(n) Equivariant Graph Neural Networks, ICML 2021 — 把旋转、平移等变性写进消息(FIG 2 等变模型的一般形式)
    • P. W. Battaglia et al., Relational Inductive Biases, Deep Learning, and Graph Networks, arXiv 2018 — “图网络”框架的综述
    • W. L. Hamilton, Graph Representation Learning, Morgan & Claypool, 2020 — 入门教材
    • M. M. Bronstein, J. Bruna, T. Cohen & P. Veličković, Geometric Deep Learning: Grids, Groups, Graphs, Geodesics, and Gauges, arXiv 2021 — 用对称性统一 CNN、GNN 与 Transformer