2.3 万物之间的联系:基于关系的蒸馏


文档摘要

2.3 万物之间的联系:基于关系的蒸馏 本节摘要:关系蒸馏不要求学生逐点复刻教师的输出或特征,而是复刻教师眼中的"关系结构"——样本与样本之间的距离格局、层与层之间的相关模式、特征图内部的空间注视关系。本节讲两类关系教材的取法与损失设计,说明它为何比逐点模仿更宽容,也更适合跨结构传艺。 响应蒸馏学结论,特征蒸馏学步骤,本节学第三样:见识。一位老鉴定师的价值不只在"他说是真迹",更在他扫一眼就知道"这幅比展厅那幅更接近作者中期风格"——对样本之间关系的判断,是更抽象、也更容易迁移的知识。 从抄点位到抄格局 逐点模仿(无论是 logits 还是特征值)有一个隐含假设:师生两侧的"坐标系"是对得上的。一旦师生结构差异大,逐点对齐就要靠适配层硬拉,还容易把学生训练得只会贴着教师的坐标走。

2.3 万物之间的联系:基于关系的蒸馏

本节摘要:关系蒸馏不要求学生逐点复刻教师的输出或特征,而是复刻教师眼中的"关系结构"——样本与样本之间的距离格局、层与层之间的相关模式、特征图内部的空间注视关系。本节讲两类关系教材的取法与损失设计,说明它为何比逐点模仿更宽容,也更适合跨结构传艺。

响应蒸馏学结论,特征蒸馏学步骤,本节学第三样:见识。一位老鉴定师的价值不只在"他说是真迹",更在他扫一眼就知道"这幅比展厅那幅更接近作者中期风格"——对样本之间关系的判断,是更抽象、也更容易迁移的知识。

从抄点位到抄格局

逐点模仿(无论是 logits 还是特征值)有一个隐含假设:师生两侧的"坐标系"是对得上的。一旦师生结构差异大,逐点对齐就要靠适配层硬拉,还容易把学生训练得只会贴着教师的坐标走。关系蒸馏换了个问法:不要求学生输出与教师相同,只要求学生眼中样本间的关系格局与教师一致

以样本关系为例。一批 32 张图的 batch,教师对任意两张图算出特征距离,得到一个 32x32 的距离矩阵;学生同样算出它的矩阵。损失不再是逐特征的均方误差,而是两个矩阵之间的差异——常用做法是把距离矩阵展平后归一化,再算平滑 L1 或相关系数。学生学到的不是"这张图特征向量长什么样",而是"这三张图里,一三相近、二独一类"的格局。

import torch import torch.nn.functional as F def relation_pair_loss(s_feats, t_feats): """样本对关系蒸馏:对齐 batch 内样本两两距离矩阵。 s_feats、t_feats 形状均为 B x D,来自师生同层特征。""" # 两两欧氏距离矩阵,B x B def pdist(x): sq = x.pow(2).sum(dim=1, keepdim=True) d = sq + sq.t() - 2.0 * x @ x.t() return d.clamp_min(0).sqrt() d_s, d_t = pdist(s_feats), pdist(t_feats) # 归一化后展平,去掉对角线(自己与自己的距离恒为 0) n = d_s.size(0) mask = ~torch.eye(n, dtype=torch.bool, device=d_s.device) ds, dt = d_s[mask], d_t[mask] ds = ds / ds.norm() dt = dt / dt.norm() return F.smooth_l1_loss(ds, dt) s = torch.randn(32, 128) # 学生 batch 内 32 个特征向量 t = torch.randn(32, 256) # 教师 32 个特征向量,维度不同也没关系 print("关系蒸馏损失:", relation_pair_loss(s, t).item()) # 输出示例: # 关系蒸馏损失: 0.042 # 注意:损失不依赖特征维度一致,只比较距离"格局"。

两类关系教材

样本间关系:如上所示,对齐 batch 内样本两两的距离或相似度结构。它的教法价值在于给学生灌入"类内紧凑、类间分明"的几何直觉——教师认为哪些样本是一伙的、哪些疏远,学生照着排布自己的特征空间。扩展形式包括三元组损失(锚点、同类、异类)与对比式表征蒸馏(CRD),后者把师生对同一样本的表征拉齐、对不同样本推远,是近年分类任务上很能打的关系式教法。

层间与空间关系:教师内部也有关系可学。层间角度相似性(RKD 的一个分支)对齐"第一层与第三层特征的夹角关系";空间层面,把特征图上不同位置的响应视为一组"点位",对齐它们之间的角度关系而非绝对位置。这类教材的隐含假设是:绝对坐标不可迁移,但相对格局可以。

角度关系怎么算?取 batch 内样本特征两两连线,看连线之间的夹角——教师与学生不必维度一致,夹角本身就是无量纲的格局量:

# 角度关系蒸馏(RKD-A 的核心计算) import torch import torch.nn.functional as F def angle_relation_loss(s_feats, t_feats): """对齐 batch 内样本两两相似度格局。特征形状均为 B x D。""" def sim_matrix(f): f = F.normalize(f, dim=1) return f @ f.t() # B x B 余弦相似度矩阵 a_s, a_t = sim_matrix(s_feats), sim_matrix(t_feats) # 去掉对角线(自己与自己的相似恒为 1),归一化后对齐 n = a_s.size(0) mask = ~torch.eye(n, dtype=torch.bool, device=a_s.device) ds, dt = a_s[mask], a_t[mask] return F.smooth_l1_loss(ds / ds.norm(), dt / dt.norm()) s = torch.randn(64, 96) # 学生 96 维特征 t = torch.randn(64, 512) # 教师 512 维特征,维度不同无妨 print("角度关系损失:", angle_relation_loss(s, t).item()) # 输出示例: # 角度关系损失: 0.031 # 距离关系关注"远近",角度关系关注"方向", # 两者叠加(各占关系损失一半)是 RKD 的标准配置。

距离与角度可以互补:距离矩阵刻画"谁跟谁是一伙",角度矩阵刻画"从哪个样本看过去谁在哪个方向",两份格局教材叠着用,比单用一份更稳。

图 2-3 逐点模仿与关系模仿的差别

图 2-3 逐点模仿与关系模仿的差别

一条完整案例:跨结构给小模型补几何

背景。 团队的服务端教师是一个 Transformer 类视觉模型,精度高;学生是纯卷积结构,直接用特征蒸馏对齐困难(注意力特征图与卷积特征图空间组织方式不同),逐点 MSE 训练不稳。

操作。 放弃逐点对齐,改用关系教材:每个 batch 里同时取师生同深度段的特征,计算样本对距离矩阵并做关系损失(权重 0.3),叠加响应蒸馏(权重 0.7)。特征维度不同、空间组织不同都无所谓,只比格局。

结果。 纯响应蒸馏基线 89.1%;加特征逐点 MSE 一版不升反降 0.3 个点,训练曲线震荡;换关系损失后稳定到 90.4%,比基线高 1.3 个点。

解读。 这条案例给出关系蒸馏的定位:它是师生结构差异大时的"宽容教材"。逐点模仿失败的原因不是特征知识没用,而是坐标系对不上;关系教材把坐标系从知识里剥掉,只传格局。代价也要看到:关系损失丢弃了绝对信息,单靠它通常不如"响应加关系"的组合——本例 0.7 对 0.3 的配比是长期试出来的合理区间。

变式。 batch 很小时距离矩阵不稳定,可把 batch 从 64 起步或用动量队列缓存历史特征扩充关系对;想再抽象一层,用互信息式目标(师生表征互信息最大化)替代距离矩阵,思想相同、估计器不同。

⚠️ 常见坑:关系蒸馏的 batch 语义。样本间关系依赖"这一批里都有谁",随机增强与 shuffle 会让每个 epoch 的关系目标都在变。这是设计的一部分(关系知识本来就该多样),但如果你想复现结果,冻结 batch 组成做对照实验更可靠。

💡 关键直觉:当你为"师生对不上"发愁时,问一句——我真正想传的是点位还是格局?九成场景下,格局才是那件值得传的行李。

本节要点回顾

  • 教材第三形态:样本间距离格局、层间角度关系、空间注视关系,都是教师"见识"的载体。
  • 实现要点:对齐距离矩阵或归一化角度关系,不要求特征维度与坐标一致。
  • 定位:师生结构差异大、逐点对齐不稳时的首选宽容教材;通常与响应蒸馏搭配而非单用。
  • 典型配比:响应 0.7 加关系 0.3 是合理起点,batch 规模 64 起步更稳。
  • 进阶形式:三元组、对比式表征蒸馏、互信息目标,都是"传格局"的不同写法。

作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U