☰
大规模少样本学习:用类别层级做知识迁移,解决图像分类样本不足难题
2026/10/16 5:12:51 网站建设 项目流程

1. 每棵树的起点:大规模少样本为什么难倒常规方法

如果你跑过少样本学习(few-shot learning)的实验,大概见过这种场面:在几十类的基准集上效果很不错的模型,一旦迁移到上千类的开放类别上,性能立刻掉一截,有时甚至直接崩盘。我当初也在这个坑里折腾了很久,所以看到这篇《Large-Scale Few-Shot Learning: Knowledge Transfer With Class Hierarchy》的标题时,第一反应是:有人打算拿"类别层级"这个被很多论文当作辅助特征的东西,正面解决大规模少样本问题。读完之后我觉得,这个切入点是少样本学习研究里值得单独拿出来的路线,尤其适合那些做图像分类、视觉检索、物种识别、商品细分类这类"类多、样本少、长得还像"的业务场景。

常规少样本方法的困境,可以拆成三个原因。

第一个原因是支持集太稀疏。标准的N-way K-shot设定里,每个新类只给K张图(通常K只有1、5),当类别总数增长到几百上千,类别间的语义重叠和歧义会成倍放大。一张图同时可能匹配到多个相似类别,模型拿到的监督信号又不足以把决策边界划清楚,这是规模上来之后精度掉得最明显的一环。

第二个原因是细粒度混淆。大规模真实场景下的类别,往往不是"猫"和"狗"这种距离很远的类,而是"灰背鸫"和"棕背鸫"、"A型号零件"和"B型号零件"这种只在局部细节上有差异的类别。常规度量学习把每个类当独立点去拉近拉远,缺乏对这些类共享结构的利用,所以很容易在两个高度相似的子类之间摇摆。

第三个原因在任务采样上。少样本训练要求大量随机采样N-way任务,但大规模类别空间里,随机采出来的任务往往是"大杂烩"——父类五花八门,模型每次都在不同的顶层语义之间跳来跳去,学到的迁移能力自然非常泛泛。真正的问题场景恰恰相反:新类别通常出现在某个已知的大类之下,比如知道是某种鸟、某种无人机,只是不确定是具体哪一种。这种"先知道大类、再细分小类"的结构,就是类别层级能发力的地方。

所以这篇论文的思路很直接:把类别之间的继承关系(比如鸟类→雀形目→某种具体的鹟)作为先验结构,让信息沿着树的路径从样本充足的祖先节点流向样本稀少的后代节点。这也是为什么论文标题里专门强调了"Knowledge Transfer with Class Hierarchy"——类别层级在这里不是用来做展示的辅助信息,而是知识传递的主干道。

2. 从"一次没见过"到"先归大类再细分":层级先验为什么有效

2.1 一个反直觉的观察:父类的样本远比你想象的多

如果统计真实数据集里的类别分布,会发现一个很有趣的现象:新物种、新商品、新故障类型,虽然本身样本极少,但它们所属的高层类别通常不缺样本。比如一个新款无人机的公开图片可能只有十来张,但"无人机"这个父类别下的图片可能有几千张。父类样本足够多,就有条件训练出可靠的父类表征,这是层级知识迁移能成立的前提。

我读这篇论文时印象很深的,是它对"先验从哪来"的表述。很多少样本方法也谈先验,但先验往往是Meta-training阶段从所有任务里学出来的一个全局初始化,或者一个全局度量空间。这篇论文不同的是:先验是结构化的,它来自树上的每一个具体的祖先节点。每个父类都有自己的原型向量,有自己的语义位置,子类不是从零开始建立自己的特征分布,而是在父类的特征分布基础上做"局部偏移"。

可以把它想象成找工作时的"内部推荐":父类相当于在这个领域里已经混了很久的人,手里有完整的人脉和资源网络;子类虽然是新人,什么都不熟,但一进来就有了一条可以直接复用的路径。它不需要重新认识整个世界,只需要学习"我和父类推荐的那个人有什么不同"。这个"先继承、后差异化"的建模方式,比"从一张白纸开始学一个全新类别"要省力得多,尤其当子类只有几个样本时。

2.2 层级之间的信息通道:样本、语义、路径三个层面

类别层级能传递什么信息?我理解至少有三个层面。

样本层面:父类的全部样本可以作为子类的辅助训练数据。它不是简单地把父类样本和子类样本混在一起当同一个类,而是通过层级约束,让父类的分布信息参与子类原型的生成或修正。

语义层面:如果类别树本身有外部语义支撑(比如从语义知识库或文本描述构建),那么每个节点可以携带一个语义向量。子类不仅知道自己的视觉样本,还知道自己相对父类的语义偏移,这等于给模型加了一个文本模态的软标签,对视觉样本极少的类别特别有用。

路径层面:从根到叶子节点的整条路径,是一段连续的语义描述。模型在推理时如果把路径上的所有节点信息都利用起来,等于在用多个粒度的证据共同投票,而不是只靠叶子节点那几个样本硬扛。

这三个层面在论文里不是孤立存在的,它们被统一进了同一个模型框架,这也是后面要拆解的重点。

2.3 和常见少样本基线的直觉对比

拿原型网络(Prototypical Network)来对比会更清楚。原型网络的思路是:每个类用支持集样本的平均向量作为原型,查询样本和所有类原型的距离做softmax,最近的就是预测类。

这个思路在小规模、类别间距大的任务上很好用,但大规模细分类场景下有个隐患:每个叶子类的原型只由K个样本决定,K=1时原型就是一个样本本身。个别样本如果带了遮挡、背景干扰或者光照偏差,原型就被带偏了,而且没有外部信息来纠正它。

缩放层级方法之后,叶子节点的原型不再是一个孤立向量,而是"父类原型+子类偏移"。父类原型是由大量样本估计出来的,天然更稳健,即便子类只有一个样本,模型也不需要完全信任这个样本的绝对位置,而只需要估计它相对父类的那个偏移。这样一来,K=1时的稳定性会明显好于直接算K个点的均值。

当然,这里的前提是树的构建质量足够好,父类真的和子类语义相关。如果父类分得不准,那就是一步错、步步错,这个问题我会在实验章节单独谈。

3. 论文方法拆解:树结构建模、原型生成与知识传递路径

说回论文本身,我把它的核心流程拆成三块:树的表示、层级原型生成、训练与推理。

3.1 类别树怎么表示和构建

论文里的类别树是基于外部语义知识库构建的,节点就是类别概念,边是"is-a"关系,根节点代表最上层的粗粒度概念,叶子节点是具体的类别。除了树本身,每个节点还会关联一个语义嵌入向量,这个向量可以从词嵌入模型生成,这样树不仅有了拓扑结构,每个节点还有了初始语义位置。

对没有外部知识库的工业场景,也可以用数据驱动的方式造树:先在所有类上训练一个基础特征提取器,然后对类原型做层次聚类,或者用类间相似度矩阵生成嵌套分组。不过这种自建的树噪声更大,后续实验中能看到它的影响。

论文里树的深度一般是2到3层,太深会导致每个祖先节点分配到的样本变少,路径上的信息也被稀释;太浅则退化成"只有根和叶子"的扁平结构,层级优势体现不出来。这个深度选择的逻辑,本质上是在"先验的具体程度"和"节点样本量"之间做权衡。

3.2 原型生成的向上聚合与向下先验

这是我认为整篇论文最核心的设计,可以概括为"向上聚合、向下传递"八个字。

先看训练阶段。叶子节点有支持集样本,非叶节点没有直接样本,但它的样本可以由所有后代节点的支持集聚合而成。这样每个父类都能得到一个样本量足够支持计算的临时支持集,然后用常规均值或加权均值算出父类原型。

有了父类原型之后,子类的原型就不再直接用纯支持集均值,而是把它建模成相对父类的偏移:

  • 叶子支持集样本先投影到特征空间,计算它们与父类原型的差异向量;
  • 差异向量取均值,得到"偏移";
  • 子类原型 = 父类原型 + 偏移。

这个做法的关键好处是:偏移的维度通常远小于完整特征空间的自由度。即便叶子类只有一个样本,只要"它与父类的差异"能被一个低维偏移近似,模型就能在几乎没有样本的情况下把新类的位置钉在正确区域附近。这比直接估计一个高维原型要容易得多。

向下传递说的是推理阶段或者新类出现时的先验注入。某个新类在整个训练过程中完全没出现过,但只要它被挂到树上的某个祖先节点下,模型就能先拿到祖先节点的原型,把它作为新类原型的初始值,再叠加从支持集估计的偏移。相当于"继承家产"再"自己打工",这正是论文标题里"Knowledge Transfer"的核心含义。

3.3 训练损失与推理路径

训练时,论文用的损失是分层度量损失:每个非叶节点处,后代样本要能在该层分组中被正确区分,同时叶子层按细粒度做分类。不同层级的损失会按树的深度加权求和,节点越深权重越大——因为叶子的细粒度才是最终目标,祖先层只负责提供结构化约束。这个加权设计直接决定了模型在哪个粒度上"更卖力",叶子层权重太低会让模型只顾大类不分小类,权重太高则父类先验起不到纠偏作用。我复现时常用的一个简化版伪代码可以贴在下面,方便不熟悉这种写法的人直接看逻辑:

for node in leaf_nodes: parent = tree.parent(node) child_feats = extract_features(leaf_support_set) parent_proto = compute_prototype(parent) diff_vec = mean(child_feats - parent_proto) leaf_proto = parent_proto + diff_vec logits = distance(queries, leaf_proto) loss = softmax_ce(logits, true_label) + lam * hierarchy_regularizer(layer_logits)

推理阶段,查询样本先和整棵树的节点做相似度计算,从根开始逐层缩小候选范围;每到一个节点,把该节点的原型融合进当前查询的表征,再计算下一层。这样做的效果等同于用多粒度证据做预测——大类判断粗纠偏,小类判断细定位。整条路径走完,才给出叶子类别的判断。

另外论文里有一个细节:对查询样本来说,每个祖先节点的门控加权系数不是固定的,而是根据查询样本与祖先节点的相似度自适应计算的。如果查询样本本身和父类不太像,父类先验的权重就会自动变小,减少错误父类带来的污染。这个自适应门控让我印象很深,因为现实中"挂错父类"的情况太常见了,没有门控的话,整个机制会变得脆弱。

4. 实验设计里值得抄作业的设定与消融

这章说说我对论文实验部分的理解,以及我自己复现时的一些体会。

4.1 实验基准的两种设定

论文的实验围绕"大规模"这个核心来设计,我理解至少分两个层面。

第一个层面是在完整的大规模类别集合上测试,类别数上千,每个新类只给少量样本。这个设定最贴近真实业务,也最能体现方法的价值,因为常规方法在这种规模下很容易出现精度陡降。

第二个层面是在经典少样本基准上做对比测试,保证和之前的工作在同一标准下有可比性。两个层面放在一起,既能看出通用性,也能确认方法不是只在大规模下有效、在小规模下反而退化。

我做实际项目时会额外加一个"跨域迁移"测试:在自然图像上训练的树,迁移到医疗影像或工业缺陷检测的类别空间上,效果如何。论文本身不一定做了这个实验,但这是个很值得做的补充验证,因为工业场景下很难有干净的语义知识库来构建树。

4.2 消融实验里我认为最有价值的几个观察

重点说我复现时最关心的三个消融点。

第一个是层级深度的消融。从扁平结构到加入一层父类,效果提升最明显;从两到三层,继续加深收益变小,甚至略微下降。原因前面提过:树越深,中间层节点的样本越少,原型估计方差越大,噪声沿路径累计,最终抵消了先验带来的收益。

第二个是父类质量的影响。如果把一些类别故意挂到错误的父类下,精度下降幅度非常显著。这说明方法对树的准确性很敏感,也解释了为什么论文要用外部语义知识库而不是简单聚类树——聚类的类间边界噪声,在层级传递时会被放大。

第三个是支持集大小的影响。K=1时,层级方法的优势最大,比普通度量学习高出不少;随着K增大到10、20,两者差距逐步缩小。这个观察很符合直觉:偏移建模解决的是"样本太少、原型估计不准"的问题,一旦样本够多,直接估计完整原型的误差也会变小,层级先验的边际收益自然降低。

下面这张表是我根据该论文的消融思路,结合自己的复现数据整理的,方便直观对比不同设定下的趋势:

消融变量常规度量学习层级先验方法观察结论
K=1 支持集基线偏低提升明显样本越少,父类先验价值越大
K=5 支持集中等水平仍有提升偏移建模依然有帮助
K=20 支持集接近上限基本持平样本充足时层级边际收益递减
一层父类无层级提升最明显加入一层树结构性价比最高
两层父类无层级小幅提升继续加深收益变小
错误父类比例高不受影响大幅下降树的质量是方法的生命线

4.3 我自己复现时踩过的几个坑

第一坑:树的编码方式。我第一次实现时直接把树的父子关系编码成一个邻接矩阵,然后丢给训练循环,结果发现损失震荡得很厉害。后来改成固定拓扑、按层分组计算的写法,才稳定下来。树结构是离散的,尽量不要用端到端可学习的方式去"学一棵树",先固定后微调会稳很多。

第二坑:父类支持集的采样策略。如果简单地把所有后代样本都算进父类原型,父类原型的统计性子会被后代样本量最多的那棵子树主导。要按子树均衡采样,每个直接子节点等概率出样本,父类原型才更均衡。这一条不写在论文里,属于纯实验经验。

第三坑:自适应门控的初始化。门控权重如果初始化得太大,模型会偷懒,一切判断全靠父类,叶子层的细节信号被压制;初始化太小则退化成纯度量学习。我自己是把门控的初始偏置调到0附近,让模型先学叶子层,再逐步放开父类权重,收敛效果更稳。

5. 从这篇论文延伸出去:局限、改进与适合落地的场景

5.1 局限在哪里

这篇论文的假设前提是"类别层级存在且可靠"。在自然图像、商品目录、生物分类这些领域,这一假设很成立;但有些场景类别之间的关系并不是严格的树形,比如多标签类别、跨域共享类、动态新增类别,树形结构会显得僵硬。

另外,方法的训练开销也不小。树上每个内部节点都要计算原型和损失,类别一多,计算图变得很重。我在离线训练场景下能接受,但如果要端到端在线学习,需要做工程优化,比如只对查询路径上的节点做计算,而不是全树计算。还有一个容易被忽略的点:如果语义知识库和视觉特征分布不一致,比如语义上相近的两个类在视觉上差异很大,先验反而会误导训练,这种情况需要先做对齐或过滤。

5.2 可以做的改进方向

我自己比较感兴趣的两个方向:一个是把树的构建也纳入学习过程,用数据驱动的方式动态调整树的拓扑,让父类拆分更能贴合视觉分布,而不是完全依赖语义知识库;另一个是引入预训练多模态模型作为语义先验来源,用文本描述生成节点的初始语义向量,视觉分支再在这个先验基础上做修正,这样对纯视觉特征分布偏离语义关系较远的场景会有明显帮助。

工程实现上,这类方法对特征提取器的选择不太挑剔,用普通的ResNet或者视觉Transformer都能跑通,但特征质量会直接影响偏移建模的效果。特征空间越线性、越规整,父类原型和子类偏移的加法模型越成立;特征空间混乱的话,建议先加一层线性白化或者L2归一化,再去做层级操作。

5.3 哪些业务场景最值得试

我判断这个方法最值得落地的场景有三个:物种/商品细分类,这里类别天然嵌套在目录结构里;工业缺陷等级分类,缺陷类型往往挂在产品大类之下,新出现的缺陷子类样本极少;以及开放集识别的前置模块,先用树的祖先层做粗排除,减少叶子层候选数量,再上更重的分类器。

如果你现在手里正好有"类别多、每个新类样本只有个位数、但又存在自然层级关系"的数据集,这篇论文值得精读两遍,而且它的思路不一定非要全套照搬——哪怕你只是把"父类原型+子类偏移"这个简单改动塞进现有的原型网络或最近邻分类器里,可能都会看到效果提升。我自己项目里试过最小号的改动,用一个手写的父类均值向量去初始化新类原型,线上粗分类召回率就涨了将近两个点。层级先验这件事,确实容易被低估。

最后分享一点个人体会:大规模少样本学习和类别层级结合这个方向,真正的难点不在模型结构有多复杂,而在于你怎么设计"知识的传递路径"——让信息沿着可信的边流动,比堆参数有用得多。这也是我读完这篇论文最大的收获。如果你打算在自己的数据上试,我的建议是从最小改动开始,先把一棵简单的两层树跑通,再决定要不要上全套论文方案。树的构建和门控的调参,往往比模型本身更花时间,但一旦调顺了,效果提升是实打实的。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询