我们小区有位出了名的“消息灵通”王阿姨。每天清晨,她搬个小马扎坐在单元门口,听来往居民闲聊。奇怪的是,王阿姨从不会把话传岔——家里人的叮嘱她放在心上,同事的八卦她只当趣闻,楼下商户的促销广告她笑笑就过。为什么?因为她在心里给每种关系配了一把“尺子”:家事、公事、邻里事,各有各的掂量方式。 在人工智能的图神经网络(GNN)世界里,也有一位这样的“王阿姨”。早期的 GCN(图卷积网络)是个一根筋的传声筒:不管消息来自谁、通过什么关系传来,一律用同一套方式处理。可现实中的图——比如知识图谱——里面藏着多种关系:“张三是李四的老板”“李四是王五的丈夫”“王五住在杭州”。关系不同,消息的分量就该不同。 RGCN(Relational Graph Convolutional Network,关系图卷积网络)正是为此而生:它为每一种关系类型准备一个独立的权重矩阵,相当于给每类关系发一本专属“翻译手册”。这篇文章就带你看懂这本“手册”是怎么写的、怎么用的,又怎么控制成本。

岗位关联

学懂 RGCN,你就掌握了在异构图上建模多关系交互的核心武器。无论做知识图谱补全、社交推荐还是风控推理,它都是绕不开的行业标配,也是从 GNN 入门迈向实战的关键一跃。

目录
  1. 可视化演示
  2. 背景与动机:一根筋的传声筒为什么会翻车
  3. 核心思想:每类关系一本专属手册
  4. 消息传递:分组讨论再汇总
  5. 参数正则化:手册太多怎么办
  6. 模型训练:用谣言当反面教材
  7. 工程实现:台账分册落地
  8. 应用与局限:从小区走向全城
  9. AI 应用场景
  10. Python 演示
  11. 常见误区
  12. 面试题

可视化演示

展示RGCN为每种关系类型分配独立权重矩阵的消息传递机制,以及基分解与块对角两种参数压缩正则化策略的对比。

本节配有交互动效(进入视口后自动加载,约 3KB)。

多关系消息传递 R1 关系1:独立权重W1变换邻居特征 R2 关系2:独立权重W2变换邻居特征 R3 关系3:独立权重W3变换邻居特征 h_i = σ(Σ_r Σ_j W_r · h_j) 每种关系类型使用独立卷积权重进行消息聚合。

背景与动机:一根筋的传声筒为什么会翻车

王阿姨刚上任时也栽过跟头。那阵子她见谁都热情,碰上消息就往喇叭里念——结果把楼下花店的促销广告当成了“居委会紧急通知”,闹得整栋楼白跑一趟。问题出在哪?她没问一句“这话是谁、通过什么关系传来的”。在 AI 处理图数据的早期,GCN 就是这位一根筋的王阿姨。

先补一点背景知识:图(Graph)由节点(Node)和边(Edge)组成,GCN 做的事可以用一句话概括——“邻居消息汇总”:把一个节点的邻居特征加权求和,更新自己的特征。但它默认图里只有一种边,这叫同构图(Homogeneous Graph)。在真实的异构图(Heterogeneous Graph)里,边是有类型的:比如知识图谱中,“出生于”“就职于”“位于”各是各的关系。同一个邻居,通过“老板”关系传来的话,和通过“朋友”关系传来的话,分量完全不同。

把异构图硬塞给 GCN,等于把“老板的话”和“朋友的话”倒进同一个桶里搅匀,模型学不到“关系”这个维度的信息。学界把这类含多种关系类型的图称为多关系图,而知识图谱正是最典型的代表(典型关系如 (实体, 关系, 实体) 三元组)。为了让模型“看见”关系的差异,研究者提出了 RGCN(Relational Graph Convolutional Network,Schlichtkrull 等人 2018 年提出),核心就一句话:给每种关系类型配一套独立的卷积参数。模型在处理消息之前,先看“关系是谁”。

王阿姨后来在床头贴了三张便签,把“家人、同事、商户”分开记——这便是“按关系分类”的意识。GCN 到 RGCN 的跨越,也正是从“一根筋传话”到“分类处理”的跨越。

核心思想:每类关系一本专属手册

后来的王阿姨学聪明了。她在工作手册里夹了三张活页:跟家人说话,用“关心优先”的滤镜;跟同事沟通,用“就事论事”的模板;听商户推销,先拧小音量。同一句话,经过不同活页加工后,进入她脑子里的“分量”就完全不同了。

RGCN 把这种思路搬进神经网络:把“王阿姨”看作中心节点 i,把“活页”看作关系特定权重矩阵 W_r^{(l)}(r 表示关系类型,l 表示第几层网络)。节点 i 更新自己的特征时,不是把邻居信息混成一锅粥,而是先按关系把邻居分组,每组用各自的 W_r 做线性变换,再汇总。这就是 RGCN 的单层更新公式:

把公式翻译成生活场景:这是一场“碰头会”。先按关系分组——家人组、同事组、邻里组;各组内部先用各自的话术模板翻译一遍(W_r);再把意见汇总给王阿姨(聚合);最后王阿姨结合自己的底稿(自环 W_0)做总结。多层堆叠时,第 l 层的输出会成为第 l+1 层的输入,消息就能沿着不同关系的路径传播两跳、三跳,捕捉更高阶的语义。

hi(l+1)=σ(∑r∈R∑j∈Nir1ci,rWr(l)hj(l)+W0(l)hi(l))\displaystyle h_i^{(l+1)} = \sigma\left( \sum_{r \in \mathcal{R}} \sum_{j \in \mathcal{N}_i^r} \frac{1}{c_{i,r}} W_r^{(l)} h_j^{(l)} + W_0^{(l)} h_i^{(l)} \right)
这个公式的意思是:节点 i 的新特征 = 对每一种关系 r,把通过该关系相连的所有邻居 j 的特征分别做一次“关系专属变换”,按邻居数归一化后汇总;再加上自己的旧特征;最后过一道激活函数。
  1. 外层求和(关系遍历)对图中全部关系类型依次处理,每一种关系都贡献一份“分组意见”。
    ∑r∈R\sum_{r \in \mathcal{R}}
  2. 内层求和(邻居遍历)针对当前关系 r,把通过该关系与节点 i 相连的所有邻居逐一取出。
    ∑j∈Nir\sum_{j \in \mathcal{N}_i^r}
  3. 归一化系数先按关系 r 下邻居的多少对消息做平衡,避免“话多的人盖过话少的人”。
    1ci,r\frac{1}{c_{i,r}}
  4. 关系特定变换用该关系专属的权重矩阵 W_r 把邻居特征做一次线性变换,相当于用对应的“活页手册”先翻译再传话。
    Wr(l)hj(l)W_r^{(l)} h_j^{(l)}
  5. 自环保留额外保留节点 i 自己的旧特征,保证“我有底稿,不随波逐流”。
    +W0(l)hi(l)+ W_0^{(l)} h_i^{(l)}
  6. 非线性激活对汇总结果过激活函数 σ(如 ReLU),让模型能表达更复杂的关系模式。
    σ(⋅)\sigma(\cdot)

消息传递:分组讨论再汇总

王阿姨开碰头会从不七嘴八舌。她先把人分成三桌:家人桌、同事桌、邻里桌。每桌先内部商量——同桌人之间互相传话——再由桌长把结论报给她。这样既不会吵成一锅粥,又能保证每桌的意见都传达到位。

在 RGCN 中,这个“分桌”动作叫按关系子图传递消息。整个异构图可以按关系 r 拆成若干子图 G_r——每个子图只保留关系 r 的边。在每个子图内部,消息传递退化成普通的 GCN 操作:邻居 j 的特征 h_j 先经 W_r 变成一条“消息”:

所有子图的消息算完后,节点 i 把各子图的消息做“加法汇总”,再叠加自己的自环消息,最后过激活函数。这里 c_{i,r} 的取值通常是与 i 通过关系 r 相连的邻居数量(实践中也常用与 GCN 类似的对称归一化)。为什么要归一化?想象一个微信群有 500 人、另一个群只有 2 人:如果不做稀释,500 人群里每人只说一句,就把 2 人群的声音彻底淹没。“说的人越多,单条消息分量越轻”——这正是归一化的生活直觉。而这就是关系子图聚合的完整流程。

分组讨论、内部传话、桌长汇报、汇总总结,这套流程在 RGCN 里就叫“消息传递 + 多关系聚合”。王阿姨的碰头会越开越顺,RGCN 的消息也越传越准。

mj→ir=1ci,rWr(l)hj(l)\displaystyle m_{j \to i}^{r} = \frac{1}{c_{i,r}} W_r^{(l)} h_j^{(l)}
  1. 消息生成邻居 j 的特征先经过该关系专属矩阵 W_r 的变换,生成一条“带关系口音”的消息。
    Wr(l)hj(l)W_r^{(l)} h_j^{(l)}
  2. 归一化稀释除以 c_{i,r}(通常是该关系下的邻居数),让消息量级与邻居数量适配,避免“人多嘴杂”时每条消息过响。
    1ci,r\frac{1}{c_{i,r}}

参数正则化:手册太多怎么办

一年后,王阿姨的活页夹塞爆了:小区关系越理越细——不仅有家人、同事、邻里,还冒出“孩子同学家长”“快递驿站”“物业维修”……每来一种新关系就写一本全新手册,写到猴年马月?她灵机一动:这些手册其实有共通骨架,无非是“热情”“客气”“谨慎”几种底子,再搭配各自的语气词。于是她只定了几本“母版”,新关系照着母版微调几个词就成。

RGCN 同样面临“手册爆炸”:关系类型 R 一多,权重矩阵 W_r 的总量就是 R × d × d(d 是特征维度),极易过拟合,尤其是那些边很少的“稀有关系”几乎学不动。论文给出了两种“母版化”策略:基分解(Basis Decomposition)和对角分解(Diagonal Decomposition)。基分解的公式如下:

基分解把参数从 R×d² 降到 B×d² + R×B,通常 B 远小于 R,模型一下子瘦身不少。对角分解更“狠”:直接把 W_r 限制成对角矩阵,参数从 d² 降到 d,相当于每个特征维度只配一个独立旋钮(公式为 W_r^{(l)} = diag(w_r^{(l)}))。两种方法都在“表达力”和“参数量”之间做取舍,实践上基分解更常用,因为它保留了关系之间“借来借去”的灵活性。

“母版 + 微调”就是对参数做结构化共享;“只拧几个关键旋钮”就是对角分解。手册再多,也有省力气的写法。

Wr(l)=∑b=1Barb(l)Vb(l)\displaystyle W_r^{(l)} = \sum_{b=1}^{B} a_{rb}^{(l)} V_b^{(l)}
含义:把每个关系专属的 W_r,表示成 B 个共享基矩阵 V_b 的加权组合;每个关系只需要学一组系数 a_{rb},而不是一整个大矩阵。
  1. 共享基矩阵预设 B 个公共基矩阵 V_b,相当于社区总部提供的几本“公共母版”。
    Vb(l)V_b^{(l)}
  2. 组合系数每种关系学习一组系数 a_{rb},表示它“借用”各母版的程度。
    arb(l)a_{rb}^{(l)}
  3. 线性组合把母版按系数加权求和,合成关系 r 自己的专属矩阵,参数总量大大缩减。
    ∑b=1Barb(l)Vb(l)\sum_{b=1}^{B} a_{rb}^{(l)} V_b^{(l)}

模型训练:用谣言当反面教材

王阿姨想检验自己的关系手册好不好用,办法很简单:听一句“传言”,判断它是真是假。比如“李老板明天关店”——她翻手册一对照:消息源是邻居刘婶的“邻里闲谈”,权重低、可信度差;而儿子说“今晚不回家吃饭”,属于家人手册,权重高,判定为真。正反一对照,手册的准头就练出来了。

RGCN 最经典的落地任务之一是链接预测(Link Prediction):图中有些边是缺失的,模型要预测“某两个实体之间是否存在某关系”。训练时把已有的三元组 (s, r, o) 当正样本,再随机换掉头实体或尾实体,造一批假三元组——这就是负采样(Negative Sampling)——让模型学会给真三元组打高分、给假三元组打低分。损失函数通常用带 sigmoid 的二分类交叉熵:

打分函数 f(s,r,o) 常用 DistMult 一类与关系相关的内积形式:实体经 RGCN 编码成嵌入后,用「头实体嵌入 × 关系嵌入 × 尾实体嵌入」做三路交互。训练流程是端到端的:RGCN 编码实体 → 打分 → 计算交叉熵 → 反向传播同时更新实体嵌入、各层 W_r(或基分解系数 a_{rb})和打分器参数。

正样本是真事、负样本是谣言,交叉熵就是王阿姨手里的“谣言鉴别尺”。手册好不好用,拿谣言一验便知;模型准不准,拿负样本一测便知。

L=−1∣E^∣∑(s,r,o,y)∈E^[ylog⁡σ(f(s,r,o))+(1−y)log⁡(1−σ(f(s,r,o)))]\displaystyle \mathcal{L} = -\frac{1}{|\hat{\mathcal{E}}|} \sum_{(s,r,o,y) \in \hat{\mathcal{E}}} \left[ y \log \sigma\big(f(s,r,o)\big) + (1-y) \log\Big(1-\sigma\big(f(s,r,o)\big)\Big) \right]
意思是:对于每个三元组样本,如果它是真的(y=1),就让打分 f 尽量大;如果是假的(y=0),就让打分尽量小。所有样本的损失取平均,就是我们要最小化的目标。
  1. 正样本项y=1 时只保留第一项,鼓励真实存在的三元组拿到高分。
    ylog⁡σ(f(s,r,o))y \log \sigma(f(s,r,o))
  2. 负样本项y=0 时只保留第二项,鼓励伪造的三元组露出马脚、得分压低。
    (1−y)log⁡(1−σ(f(s,r,o)))(1-y)\log(1-\sigma(f(s,r,o)))
  3. 整体平均对所有正负样本的损失取平均,得到稳定可优化的总损失。
    −1∣E^∣∑(s,r,o,y)∈E^-\frac{1}{|\hat{\mathcal{E}}|} \sum_{(s,r,o,y) \in \hat{\mathcal{E}}}

工程实现:台账分册落地

台账越来越大,王阿姨给自己立了规矩:一种关系一本册子,册子里按居民姓名存档,绝不混记。这样翻起来快,记起来不乱。

RGCN 的工程实现同样是“分册”思路:把一张大邻接矩阵 A 按关系拆成系列矩阵 A_r——A_r 里只保留关系 r 的边。在矩阵形式上,RGCN 的更新可以写成:

工程落地的几个关键点:第一,稀疏存储——真实图谱很大,A_r 必须用稀疏矩阵(COO/CSR 格式)存储,避免稠密矩阵内存爆炸;第二,批量计算——整图前向用矩阵乘法,超大图可配合邻居采样(类似 GraphSAGE)做小批量训练;第三,框架选型——PyTorch 搭配 DGL 或 PyG,把“消息传递”封装成 scatter/gather 算子,也可以手写 index_add 聚合(见下文 Python 演示);第四,多关系循环展开——各关系共享同一份节点特征矩阵 H,分别过各自的 W_r,最后求和。

“一关系一册子”的台账法,对应到代码就是“按关系分组的三元组列表”。册子分好了,后面查得准、算得快。

H(l+1)=σ(∑r∈RA^rH(l)Wr(l)+H(l)W0(l))\displaystyle H^{(l+1)} = \sigma\left( \sum_{r \in \mathcal{R}} \hat{A}_r H^{(l)} W_r^{(l)} + H^{(l)} W_0^{(l)} \right)
  1. 归一化邻接矩阵\hat{A}_r 是关系 r 对应邻接矩阵做归一化后的结果,承载图结构信息。
    A^rH(l)\hat{A}_r H^{(l)}
  2. 矩阵化关系变换各关系的消息经 W_r 变换后,以矩阵乘法形式一次性处理所有节点,比逐节点循环高效得多。
    Wr(l)W_r^{(l)}
  3. 跨关系求和与自环把所有关系的结果相加,再叠加上自环项 W_0,最后统一过激活。
    ∑r∈RA^rH(l)Wr(l)+H(l)W0(l)\sum_{r \in \mathcal{R}} \hat{A}_r H^{(l)} W_r^{(l)} + H^{(l)} W_0^{(l)}

应用与局限:从小区走向全城

王阿姨的“情报站”出了名,街道办请她建设全城版。好消息是功劳簿添了一笔,坏消息是麻烦也不少:全城关系类型上百种,有的关系整个城市只有两对,她想写手册都找不到足够的素材。

RGCN 最成功的应用是知识图谱补全(KG Completion):图谱里“(张小龙,创建了,微信)”这样的边如果缺失,RGCN 可以打分预测出来。电商的商品知识图谱、社交平台的多关系推理(关注、好友、屏蔽)、反欺诈中的资金关系网络(转账、设备、IP 共用),都能用“RGCN 编码实体 → 链接预测/节点分类”这条链路落地。

具体到工程实践,通常先用 RGCN 编码实体,再用 DistMult 等打分器做下游预测;多关系可以叠加关系级别的注意力机制,给重要关系更高的聚合权重;对训练成本敏感的场景,可以用邻居采样把小批量化。但 RGCN 的短板也同样明显:参数随关系数量线性膨胀(“手册爆炸”);稀有关系学习不充分;整图训练的内存与时间成本高。未来的方向是让关系之间共享更多知识——注意力、元学习、条件参数生成,就像王阿姨最后总结的:手册不必一人一本,关键时刻能借来借去,才是真本事。

AI 应用场景

电商商品知识图谱补全

阶段:图表示学习(离线训练 + 在线推理)

解决的问题:商品图谱中“搭配”“替代”“属于”等关系边大量缺失。传统协同过滤只利用“用户-商品”一种关系,无法感知“搭配”与“替代”的本质区别。RGCN 把多种关系分别编码进实体嵌入,再直接预测缺失边,补全后的图谱能显著提升推荐与导购效果。

具体案例:某电商平台在商品知识图谱上训练 RGCN,预测“(冲锋衣,搭配,登山鞋)”这条边是否成立。模型补全了数十万条搭配关系,接入推荐系统后点击率提升约 8%。

社交平台多关系链接预测

阶段:召回阶段

解决的问题:用户之间存在“关注”“好友”“屏蔽”“共同群组”等多种关系,单关系 GCN 无法区分这些交互语义。RGCN 为每种社交关系单独建模,再预测“某用户是否会关注某用户”,用于“你可能认识的人”推荐。

具体案例:某职场社交平台用 RGCN 在“人-公司-职位”异构图上做链接预测,召回率比基线 GCN 提升 12%,好友推荐更贴合真实人脉。

风控反欺诈识别

阶段:特征构建 + 风险识别

解决的问题:诈骗团伙往往共用设备、共用 IP、频繁转账,构成“卡-设备-IP”多关系异构图。传统规则引擎看不出团伙结构,RGCN 则能把多类关系编码到同一套节点嵌入中,再做节点分类识别风险账户。

具体案例:某金融风控团队在资金关系图上训练 RGCN 二分类模型,对可疑账户的召回率提升 15%,误报率下降 20%。

Python 演示

python83 行
import numpy as npimport torchimport torch.nn as nnimport torch.nn.functional as F entities = ['李雷', '韩梅梅', '北京', '清华', 'AI公司', '工程师']relations = ['就读于', '出生于', '就职于', '位于']triples = [('李雷', '就读于', '清华'), ('韩梅梅', '就读于', '清华'),           ('李雷', '出生于', '北京'), ('韩梅梅', '出生于', '北京'),           ('李雷', '就职于', 'AI公司'), ('AI公司', '位于', '北京')]ent2id = {e: i for i, e in enumerate(entities)}rel2id = {r: i for i, r in enumerate(relations)}num_ent, num_rel = len(entities), len(relations) # 按关系分组, 并用目标节点度数计算归一化系数rel_pairs = {}for r in range(num_rel):    pairs = [(ent2id[h], ent2id[t]) for h, rr, t in triples if rel2id[rr] == r]    if pairs:        src = torch.tensor([p[0] for p in pairs], dtype=torch.long)        dst = torch.tensor([p[1] for p in pairs], dtype=torch.long)        norm = 1.0 / torch.bincount(dst, minlength=num_ent).float()[dst]    else:        src = dst = norm = torch.empty(0, dtype=torch.long)    rel_pairs[r] = (src, dst, norm)  class RGCNLayer(nn.Module):    def __init__(self, dim, num_rel):        super().__init__()        # 每种关系一个专属权重矩阵        self.W = nn.ModuleList([nn.Linear(dim, dim, bias=False) for _ in range(num_rel)])        self.W0 = nn.Linear(dim, dim, bias=False)  # 自环     def forward(self, H):        out = self.W0(H)        for r, (src, dst, norm) in rel_pairs.items():            if src.numel() == 0:                continue            out.index_add_(0, dst, self.W[r](H[src]) * norm.view(-1, 1))        return F.relu(out)  class RGCN(nn.Module):    def __init__(self, dim=16):        super().__init__()        self.emb = nn.Embedding(num_ent, dim)        self.layer1 = RGCNLayer(dim, num_rel)        self.layer2 = RGCNLayer(dim, num_rel)        self.rel_emb = nn.Embedding(num_rel, dim)     def encode(self):        return self.layer2(self.layer1(self.emb.weight))     def score(self, H, h, r, t):        return (H[h] * self.rel_emb.weight[r] * H[t]).sum()  def train(model, epochs=150, lr=0.02):    opt = torch.optim.Adam(model.parameters(), lr=lr)    for epoch in range(epochs):        H = model.encode()        pos = [(ent2id[h], rel2id[r], ent2id[t]) for h, r, t in triples]        # 负采样: 随机替换尾实体生成假三元组        neg = [(h, r, (t + np.random.randint(1, num_ent)) % num_ent) for h, r, t in pos]        pos_l = torch.stack([model.score(H, *p) for p in pos])        neg_l = torch.stack([model.score(H, *n) for n in neg])        loss = F.binary_cross_entropy_with_logits(pos_l, torch.ones_like(pos_l))        loss = loss + F.binary_cross_entropy_with_logits(neg_l, torch.zeros_like(neg_l))        opt.zero_grad()        loss.backward()        opt.step()        if (epoch + 1) % 50 == 0:            print('epoch', epoch + 1, 'loss', round(loss.item(), 4))  if __name__ == '__main__':    model = RGCN()    train(model)    H = model.encode()    pred = sorted(((e, model.score(H, ent2id['李雷'], rel2id['出生于'], ent2id[e]).item())                   for e in entities), key=lambda x: -x[1])    print('预测(李雷,出生于,?):', pred)
目的:用 PyTorch 从零实现一个迷你 RGCN,在自建的小型知识图谱上做链接预测,训练后能推理“李雷出生于哪里”。
  1. self.W = nn.ModuleList([nn.Linear(dim, dim, bias=False) for _ in range(num_rel)])关键点:每种关系一个独立的线性变换层,对应“一关系一活页”。
  2. self.W0 = nn.Linear(dim, dim, bias=False)自环变换,保留节点自身信息。
  3. norm = 1.0 / torch.bincount(dst, minlength=num_ent).float()[dst]按目标节点的关系邻居数计算归一化系数,实现公式中的 1/c。
  4. out.index_add_(0, dst, self.W[r](H[src]) * norm.view(-1, 1))把“关系专属变换 + 归一化”后的消息按 dst 下标累加到目标节点。
  5. neg = [(h, r, (t + np.random.randint(1, num_ent)) % num_ent) for h, r, t in pos]负采样:随机替换尾实体,制造“谣言”样本。
  6. F.binary_cross_entropy_with_logits(...)二分类交叉熵,拉大真假三元组的得分差距。
  7. def score(...)DistMult 打分:头实体、关系、尾实体三路嵌入逐元素相乘后求和。

常见误区

误区RGCN 名字里带个"R",我以为它就是把 GCN 的层数加深、宽度加大,本质没什么区别。反正都是图卷积,多加几层效果自然更好。

正解RGCN 与 GCN 的分水岭不在层数,而在“是否按关系分参数”。GCN 无论叠多深,所有邻居仍共用同一个权重矩阵,关系信息被搅匀;RGCN 是在每一层内部按关系类型拆分成独立的 W_r。就像王阿姨的进步靠的是“分类意识”,而不是多跑几趟腿。

为何常见:看到“图卷积”三个字就默认结构相同,忽略了输入图从“同构”到“异构”的本质变化。

误区既然是卷积,就讲究公平,所有邻居按同一套权重处理才是对的。给不同关系不同权重,是不是引入了偏见?

正解恰恰相反,RGCN 的价值正在于打破“一视同仁”。现实中“家人”和“商户”的消息当然不该同等对待;模型需要学的,正是每种关系各自的贡献模式。若强行均等,等于退化成不考虑关系类型的普通 GCN,永远区分不了“老板的推荐”和“同事的吐槽”。

为何常见:GCN 的均等聚合先入为主,让人误以为“公平”是优点,而忽略了异构图里关系类型本身就是信息。

误区反正每种关系都有专属权重矩阵,我把关系拆得越细,模型获得的信息越多,效果一定越好。

正解关系数量翻倍,参数量也近似翻倍,容易过拟合;更麻烦的是“稀有关系”——有些关系全图只有一两条边,专属矩阵根本学不动。这时需要用基分解或对角分解共享参数,甚至合并关系。关系拆分的粒度要和数据量匹配,不是越细越好。

为何常见:只看到“参数变多=表达力变强”的一面,忽略了统计学习里“数据不足时参数越多越危险”的铁律。

误区公式里那个 1/c_{i,r} 看起来像个超参数,应该像学习率一样反复试,找到最优值。

正解c_{i,r} 不是超参数,而是由图的度直接计算出的结构常数:它等于节点 i 通过关系 r 连接的邻居数量。它随图结构确定,前向计算一次即可,无需梯度更新也无需手工调节。真正要调的是网络层数、维度、基分解的基数量 B 等。

为何常见:公式里出现“系数”两个字,就容易联想到超参数,忽略了它由数据本身决定。

误区RGCN 的权重矩阵是跟着有向关系走的,所以只能处理有向图,无向图没法用。

正解无向关系完全可以建模为“两个方向”的关系类型,例如“朋友”拆成“A→B 朋友”和“B→A 朋友”两种边;也可以把无向边存成双向两条边。所以 RGCN 既能处理有向关系,也能处理无向关系,自由度反而更高。

为何常见:看到关系 r 带方向语义(如“出生于”),误以为模型只能沿单一方向传播消息。

面试题

Q1. RGCN 与传统 GCN 的核心区别是什么?

单选题 · easy

  • A.RGCN 网络层数更多更宽
  • B.每种关系都有专属权重矩阵← 正确答案
  • C.用注意力机制取代图卷积
  • D.不需要聚合邻居的消息

答案:B。传统 GCN 假设图中只有一种边,所有邻居共用同一套卷积权重;RGCN 为每种关系类型分配独立的权重矩阵 W_r,从而能区分不同关系传来的消息。层数更宽(A)、注意力机制(C)都不是 RGCN 的本质特征,(D)与图卷积的基本思想相悖。

Q2. RGCN 更新公式中的 W0 起到什么作用?

单选题 · easy

  • A.对邻居消息做归一化
  • B.保存并传递节点自身信息← 正确答案
  • C.压缩节点特征向量维度
  • D.计算最终损失函数数值

答案:B。W0 对应的自环项 W0·h_i 把节点自己的旧特征保留并传递到下一层,相当于王阿姨开会时“结合自己的底稿”。(A)是 c_{i,r} 的作用,(C)是线性层维度设计问题,(D)与损失函数无关。

Q3. 基分解正则化的核心思想是什么?

单选题 · mid

  • A.为每个关系单独初始化权重
  • B.用共享基矩阵组合出关系权重← 正确答案
  • C.把邻接矩阵拆成多个子图
  • D.用对角矩阵替代全部权重

答案:B。基分解预设 B 个公共基矩阵 V_b,每个关系的 W_r 由这些基矩阵按系数 a_{rb} 线性组合而成,相当于“母版 + 微调”,能大幅减少参数量。(D)描述的是对角分解,不是基分解。

Q4. 以下哪个场景最适合用 RGCN 建模?

单选题 · mid

  • A.只有点赞关系的社交网络
  • B.含多种边类型的知识图谱← 正确答案
  • C.只有引用关系的论文网络
  • D.无向同质化的分子结构图

答案:B。RGCN 的用武之地是“边有多种类型”的异构图,知识图谱中的“出生于”“就职于”“位于”正是典型。其余选项都只有一种边类型,属于同构图,用普通 GCN 即可。

Q5. RGCN 做链接预测训练时常用哪些手段?

多选题 · mid

  • A.随机替换实体生成负样本← 正确答案
  • B.用交叉熵拉大真假样本差距← 正确答案
  • C.把所有关系边合并成无向边
  • D.完全依赖无标签数据训练

答案:AB。负采样(随机替换头或尾实体)制造反例,交叉熵损失迫使正样本得分高、负样本得分低,两者配合完成训练。合并关系边会丢失关系类型信息(C 错);链接预测是有监督/自监督任务,并非“完全无标签”(D 错)。

Q6. RGCN 中归一化系数 c(i,r) 的作用是什么?

单选题 · mid

  • A.控制梯度下降的学习率
  • B.平衡不同邻居数量的量级← 正确答案
  • C.设定每条边的权重初始值
  • D.决定关系类型数量的上限

答案:B。c(i,r) 由节点 i 在关系 r 下的邻居数(度)决定,用来稀释消息量级,防止“话痨邻居”淹没“安静邻居”。它是图结构导出的常数,不是学习率、初始化值或关系数量上限。

Q7. 关系特定矩阵 W(r) 在消息传递中的角色是什么?

单选题 · hard

  • A.将邻居特征线性变换成消息← 正确答案
  • B.将特征映射为分类概率
  • C.把图结构压缩成一维序列
  • D.计算正负样本的损失数值

答案:A。W_r 的作用是把邻居 j 的特征 h_j 做线性变换,生成“带关系口音”的消息 m = W_r·h_j,再参与聚合。(B)是分类头的工作,(C)是图嵌入的笼统说法,(D)是损失函数的工作,都不属于 W_r 的职责。

Q8. 下列哪些策略能有效缓解 RGCN 参数过膨胀?

多选题 · hard

  • A.基分解共享公共基矩阵← 正确答案
  • B.对角分解只学对角权重← 正确答案
  • C.大幅增加网络隐藏层数
  • D.把邻接矩阵转为稠密存储

答案:AB。基分解把 W_r 表示为少量基矩阵的线性组合,对角分解把 W_r 限制为对角矩阵,两者都能大幅压缩参数、抑制过拟合。加深网络(C)和稠密存储(D)只会增加计算与内存负担,无法缓解参数膨胀。

Q9. RGCN 中“自环”指的是什么?

单选题 · easy

  • A.节点自身的循环连接← 正确答案
  • B.两个节点之间的双向边
  • C.关系类型之间的环路
  • D.图遍历过程的回退路径

答案:A。自环是节点到自身的连接,在 RGCN 中由 W0 实现,用来保留节点自己的特征,避免多层传播后“丢失自我”。(B)是双向边,(C)是关系间的环,(D)是遍历概念,均与自环无关。

Q10. 当某类关系边非常稀疏时,合理的处理方式有哪些?

多选题 · hard

  • A.用基分解借用其他关系参数← 正确答案
  • B.使用关系级别的注意力加权← 正确答案
  • C.直接把稀疏关系边全部删除
  • D.为该关系单独扩大矩阵维度

答案:AB。基分解让稀疏关系共享公共基矩阵,关系级注意力则能为稀有关系动态分配聚合权重,两者都能缓解“学不动”问题。直接删除会丢失信息(C 错),单独扩大维度只会加剧过拟合(D 错)。