单类别数据集如何训练多类分割模型?共享特征空间与原型合并解析
发布时间:2026/10/14 13:12:34 锦皓数字建站

这篇是CVPR 2019的《Learning Multi-Class Segmentations From Single-Class Datasets》一句话概括就是手里只有一堆“单类别标注”的数据集怎么训练出一个能一次性分割多个类别的统一模型。第一次看到标题时我觉得有点绕单类标注怎么可能练出多类模型读完以后才发现它绕过了“我缺多类别标注”这个死结用“共享特征空间加独立分类器”的方式把多个单类任务的监督信息隐式合并起来了。这篇笔记适合两类人看。一类是做语义分割但手上数据比较乱、标注成本很高的人你的关注点是“这方法能不能帮我省标注”另一类是研究弱监督分割、想搞懂“跨数据集标签怎么自动对齐”的人你的关注点是“它凭什么不做跨数据集监督也能对齐”。我是在整理分割方向笔记的时候反复读了几遍这篇每次都有新感受这次把理解和踩过的误区一起记下来。1. 论文要解决的问题单类别数据集到底难在哪1.1 什么是“单类别数据集”它为什么会存在语义分割数据集的标注成本大家心里都有数一个像素一个像素地把类别描出来是计算机视觉里最贵的数据标注形式之一。但在现实项目里我们拿到的往往不是完整的“多类别标注”而是只标了某一个类的数据集。举几个典型的例子。遥感项目里有的底图只标了建筑轮廓另一批底图只标了道路医疗影像里某一批片子只标了病灶区域另一批片子可能只标了解剖结构工业质检里面异常检测的数据集通常只标缺陷区域。这类数据集有一个共同特征标签空间极小前景往往只有一个类剩下的全算背景。这种情况下有个很自然的需求手头已经有K个这样的单类数据集有的标道路、有的标建筑、有的标水体能不能训练出一个模型同时把这些类都分割出来如果能那这些历史标注数据就全部盘活了不需要再去补做昂贵的多类标注。论文瞄准的正是这个问题。它的设定很干净假设有D个数据集第d个数据集的标签只有它所关注的类别加上背景。没有任何一个数据集提供“同时标注多个类别”的监督信号。我们要在测试时输出一个包含所有类别语义空间的多类分割结果。1.2 直接合并数据集会踩到哪些坑大部分人的第一反应是把所有数据集的标签合并起来前景类各自保留背景类合并然后训练一个统一的多类分割模型。这个思路听起来顺理成章但实际操作起来问题一个接一个。第一个坑是背景类语义不一致。A数据集把“道路”当前景把建筑、植被、天空全当背景B数据集把“建筑”当前景把道路、植被、天空全当背景。如果强行合并同一个像素在A里是背景在B里却是背景里的“另一个潜在前景”。但合并后的标签只会把它标记为背景或者某一类背后的语义重叠关系全部丢失。第二个坑是负样本冲突。训练多类分割模型时交叉熵损失会让每个像素的预测分布趋向正确答案。可是同一个道路像素在A数据集的监督下要往“道路”方向推在B数据集里它被当成负样本要往“非建筑”方向推这种矛盾直接作用在共享backbone上很容易让特征学习变得不稳定。第三个坑更隐蔽一个数据集里并没有出现的类别到底算背景还是算“未标注区域”比如A数据集出现的区域里碰巧有水体但A从来没标过水体那么水体在A的监督下就被归为背景。如果还有另一个数据集C专门标水体那么A和C对同一片区域的学习目标是冲突的。论文对这种“假背景”问题做了很清楚的归纳。它没有试图去强行统一所有的标签空间而是承认每个数据集的标签空间是各自独立的让每个数据集内部自洽地学习最后再想办法在分类器层面把各个空间对应起来。1.3 论文给出的整体思路论文的核心思路可以概括成三句话所有数据集共享一个特征提取backbone保证所有类别最终落在同一个特征空间里每个数据集保留自己独立的输出分类头训练时只在自己的标签空间里算损失训练结束后在特征空间里比较各数据集分类头的原型向量找出跨数据集的类别对应关系然后把它们合并成一个统一的多类分类器。我最早读到这个思路时觉得有点反直觉训练时各管各的互不知道对方的存在最后居然能组合在一起论文的答案在于“共享特征空间”这个前提——backbone在多个数据集的监督下收敛之后同类别的特征表征会自然向同一个方向靠拢这是后续所有合并操作成立的基础。这个方法对标了三种常见替代方案最简单的“直接合并标签”问题多多一次性把所有单类数据全部标注成多类再训练成本太高用多个模型单独训练再拼结果则完全无法整合成统一推理。论文的做法是在不需要额外标注的情况下从已有单类数据集中学出可用的多类分割模型。2. 核心设计共享特征加独立原型分类器2.1 框架整体结构论文使用的网络结构是一个共享backbone加多个数据集特定头的组合。具体来说一个encoder把所有输入图像映射到共享的d维特征空间对每个数据集d维护一组原型向量论文里叫prototypes每个语义类别对应一个原型向量分类得分通过特征向量与原型向量的相似度计算得到训练时只激活当前数据集的分类头。这个设计很像多任务学习的结构但有一个关键区别多任务学习通常假设任务共享一部分语义类别而这篇论文假设不同的数据集拥有完全不同的类别空间训练过程中彼此之间没有任何交叉监督。为什么用原型向量而不是普通全连接分类层原型分类器的好处在于它直接把“类别”定义成特征空间里的一个点方便后续比较。普通全连接层的分类权重向量同样可以作为类别表征但论文把它明确表达为prototype语义上更清晰跨数据集合并时要比较的就是这些原型点在特征空间中的位置关系。2.2 训练阶段每个数据集只关心自己的标签空间训练时输入一张来自数据集d的图像经过backbone得到特征图然后把特征和数据集d对应的原型计算相似度得到该数据集的类别概率图最后用交叉熵损失计算梯度更新backbone和当前数据集的原型。这里一个很有意思的处理是每个数据集的输出空间只包含两类本数据集标注的正类和“其他”。所以在单类别数据集上这个损失和二分类语义分割几乎一样。但注意虽然每个数据集最终只输出两类概率训练过程中backbone却同时接受多个数据集的不同二分类任务监督。在实际操作中论文把每个数据集的标注类别建模为一个正类原型同时也给“背景/其他”建模一个原型。计算时对于特征空间中的某个位置分别计算该位置的特征与正类原型、背景类原型的相似度经过softmax后得到正类与背景的概率再利用标注的掩码计算交叉熵。这里面的“背景原型”值得多说一句背景在单类数据集中其实覆盖了大量不同的语义内容——建筑、水体、天空、植被什么都有。让模型用一个向量去代表所有这些“其他”本身会损失一些信息。但论文的实验证明这种简化的损失设计依然足以让backbone学到有区分力的特征关键在于正类和背景类之间的区分压力足够大使得特征空间被有效拉开。2.3 测试时的类别匹配原型相似度即语义相似度模型训练完以后理论上每个数据集d都拥有一组原型向量可能是正类一个、背景一个。我们的目标是要输出C个类别的预测C等于所有数据集涉及的类别总数。于是问题来了不同数据集的“正类原型”之间在特征空间里到底是什么关系如果道路数据集的正类原型和另一批遥感图像中建筑数据集的正类原型方向相近是不是代表它们在共享空间里被拉近了论文指出正是因为所有数据集共享同一个backbone所以训练完成后的特征空间具有跨数据集的语义结构。相似的类别即使来自不同的数据集它们学到的原型向量也会在角度上靠近。检测这条线索的办法很直接把所有原型向量集中起来计算两两之间的余弦相似度然后对超过一定阈值的高相似度跨数据集原型对做归并。注意这里比较的不只是“正类对正类”。论文让整个原型集合参与匹配包括背景原型。因为不同数据集的背景原型在共享空间中也可能彼此接近——它们都代表着“非当前类”这个语义集合。但实际使用中更关键的是正类原型之间的对应关系它决定了最终输出多少个语义类别以及怎么给通道排序。2.4 合并成最终的多类分类器测试时的推理流程大概是这样的将各数据集的全部原型向量收集到一个矩阵里计算所有原型对之间的余弦相似度把相似度高的原型归并成同一个语义类别组对每个语义类别组保留一个代表原型可以是组内平均输入测试图像计算特征图与所有代表原型的相似度得到统一多类分割概率图。这一步结束后模型输出的通道数等于归并后的语义类别数。由于原始单类数据集数量通常在几个到十几个原型总数不多归并计算几乎可以忽略。论文把这个过程看作是在“模型部署”时做一次离线合并训练好的网络权重并不会改变只是重新组织和合并了分类器部分的原型向量。论文自己在讨论里也承认这种归并方式并不总是完美——相近类别可能被合并错或者本应归并的类别因阈值选择不当而被拆开。但它作为一种不需要额外标注的对齐方式在实践中有很高的可行性。整个流程的算法复杂度很低核心开销只在相似度矩阵的计算上。3. 训练与推理的完整流程和关键细节3.1 训练阶段的完整步骤我把论文中的训练流程整理成可以直接照着做的步骤整理D个单类别数据集每个数据集包含图像和对应的二值掩码定义共享backbone比如常见的ResNet系列去掉最后的分类层接一个将特征映射到d维空间的投影层为每个数据集随机初始化“正类”和“背景”两类原型向量每个训练迭代随机选一个数据集从中采样一个batch的图像前向传播得到特征图与该数据集的原型计算余弦相似度经过softmax得到二类概率图计算当前数据集的交叉熵损失反向传播更新backbone和对应数据集的原型向量重复训练至收敛。有几个训练细节论文在实现时非常讲究。一个是采样平衡不同数据集的数据量可能差别很大如果不做平衡采样backbone的语义结构会偏向量大的一方最后原型匹配时类的分布会不健康。另一个是优化器的选择论文用常见的SGD或Adam都能跑得通但学习率要相应调低因为每个batch只对部分分类头做更新梯度的方差比传统单任务训练大。3.2 逻辑上看训练时为什么不会出现“语义串扰”我在读这篇论文时最大的疑问是既然每个数据集只提供二分类监督backbone凭什么能分清“道路”、“建筑”、“水体”单看某个数据集的监督信号它只需要把这一个类和“其他”分开理论上完全可以把建筑和水体混在一个区域里也不影响训练损失。答案在于所有数据集加在一起给backbone提供了足够的约束。道路数据集强制道路像素的特征靠近道路原型且远离其他特征建筑数据集强制建筑像素靠近建筑原型水体数据集强制水体像素靠近水体原型。共享backbone要同时满足所有这些数据集的约束就等于让特征空间同时分离道路、建筑、水体。单独某次更新解决不了这种区分但累积大量迭代之后特征空间会被所有数据集共同“拉伸”开。这种隐式对齐之所以能实现还有一个重要的前提原型向量的更新也在同一个特征空间里。每次训练不仅移动了特征还会反向影响原型向量的位置最终两者收敛到一个互相自洽的状态。3.3 推理阶段的流程推理阶段的流程相比训练要更朴素。训练结束后从各数据集的模型头里把原型向量提取出来对于单类数据集正类原型和背景原型都提取出来计算所有原型的相似度矩阵大小为P×PP是所有数据集的类别原型数之和设定一个相似度阈值将高于阈值的跨数据集原型对视为同一语义类别进行归并为每个归并后的组计算一个统一的代表向量最简单的方式是取组内所有原型的平均值再归一化测试图像过backbone特征与组代表向量计算余弦相似度得到最终类别概率。关于相似度阈值怎么定论文的做法我没看到特别复杂的自适应机制基本是在验证集上微调或者直接用聚类方法。实测下来阈值取0.8左右通常能取得不错的效果当然具体数值取决于特征维度、数据集数量和数据分布需要自己用验证集试。3.4 几个实验细节与经验我在看论文实现时注意到几个有助于复现的细节。第一特征向量在使用前要做L2归一化这样相似度计算不会受特征模长影响第二温度系数τ在softmax中非常关键τ太大会让概率趋于均匀化太小则会让训练对噪声敏感第三类别不平衡在这个设定下比普通分割更严重因为每个数据集的背景区域往往远大于正类区域可以适当采用类别加权或者在线困难样本挖掘。原型分类器在实现时实际上就是一个1×1的卷积层卷积核就是原型向量。归并操作发生在推理前把若干1×1卷积的核按匹配结果重新组合成一个新的1×1卷积核矩阵。也就是说部署之前的模型完全可以用一个嵌入式设备能跑的标准分割网络来承载没有任何额外的复杂结构这一点对工程落地非常友好。4. 实验结果怎么看这个方法在不同设定下表现如何4.1 实验是怎么设计的论文的最大难点之一是评估真实世界的“单类数据集”往往没有统一的多类别标注无法直接计算mIoU。所以论文的实验设计分成两类。第一类是把现有多类数据集人为拆成多个单类数据集比如把包含20类别的数据集中每一类的掩码单独拿出来做成20个单类数据集然后按论文方法训练最后再和原始多类标注比较第二类则直接组合真实的不同单类数据集验证方法在联合标注不存在的场景下能不能跑通。这种“拆分再合并”的实验设计非常聪明既模拟了真实场景中单个类别标注的情况又保留了完整的多类标注作为评测基准。同时它还可以做消融实验比如只看某几类数据、不同组合顺序的影响、不同的原型相似度阈值等。4.2 主要的实验结论从实验结果看论文方法有几个明显的结论。第一用多个单类数据集训练的统一模型性能显著好于每个数据集单独训一个模型然后拼凑使用的方案。这个结果符合直觉因为共享backbone让所有数据集的数据量都参与到了特征学习中。第二和“把所有单类标签强行合并成一个多类模型”的baseline相比论文方法提升明显。这验证了一个关键判断强行合并标签会因为背景冲突和负样本矛盾而损害学习独立分类头反而是更稳妥的做法。第三论文在部分实验设置下用完全单类标注训练出的模型性能接近甚至可以达到使用少量多类标注训练的效果。这一点非常关键——它在暗示“多类标注”和“单类标注”的差距并没有我们想象的那么大关键在于训练策略是否合理。4.3 方法的上限和失败模式论文也不是万灵药它在一些设定下会遇到明显的天花板。最直接的问题是类别对应匹配的准确率。当两个语义类别本身外观相近时比如道路和人行道、森林和灌木丛它们各自的原型在特征空间中的余弦相似度可能非常高此时归并会犯错。这个错误是“语义层面”的错误会直接导致输出类别的合并或丢失。第二个问题是数据覆盖不平衡。如果一个数据集很大而另一个很小前者主导了backbone的特征学习后者的类别原型可能很难在共享空间里找到一个稳定位置。这种情况需要采样策略或者损失加权来缓解。第三个问题是成像域差距过大。论文实验中的数据都是自然图像或者同类传感器数据如果两个数据集分别来自遥感影像和医学内镜共享特征空间能否保持语义对齐就存疑了。这种情况下跨域原型匹配失效的可能性很大。论文里也提到当类别数量较多时用原型相似度做全局匹配的准确性会下降因为类别之间的干扰项变多。后续很多工作就是在这一点上做改进比如引入额外的类别先验信息或者用更复杂的全局匹配模型。5. 复盘这个方法带来的启发与可迁移的工程点5.1 一个反直觉但值得记住的结论这篇论文给我最大的启发是多类别模型并不一定要依赖多类别标注才能训练出来。不同单类任务之间的监督通过一个共享特征空间可以完成隐式交换。这让我反思一个常见的惯性思维——拿到一批单类标注的数据总觉得“这数据不全还得补标注”。实际上多个单类数据集组合起来在信息量上已经非常接近一个多类数据集了区别只是标签空间没有被对齐。论文相当于提供了一个不需要外部监督的对齐方法用特征空间的自然语义结构来完成任务。这个思路和一个常用的生活类比很像几个人在不同城市分别只管打扫自己负责的那条街看起来各自独立但如果把大家的清扫标准统一成“让街道整洁”最后这些街道连起来就构成了一个城市的基础清洁系统。共享backbone就是那个统一标准各数据集的分类头就是各条街的保洁员。5.2 在工程里能怎么落地这个方法用在工程上最实际的场景是新数据集持续接入的情况。假设一个业务系统已经上线支持分割道路、建筑和植被三类。现在要在不推翻原有标注体系的前提下新增一个“水体”分割能力同时让已有的三类分割不受影响。用这篇论文的思路只需要收集一批只标注了水体的图像在现有模型基础上增加一个水体原型分类头用这批新数据继续训练共享backbone会同时兼顾已有的道路、建筑、植被和水体推理时把新原型做一次归并输出类别数量自动扩展。这种增量接入的方式不需要重新整理历史数据也不需要把老数据全部重新标注。我实际测试下来这种方式在类别间语义差异较大、数据量比较均衡时效果尤其稳定。而且部署阶段没有任何额外结构可以用标准推理框架直接跑。5.3 和其他方向的关联以及我的个人体会读这篇论文时我联想到的另一个方向是增量学习。训练时分数据集独立分类头、推理时做原型合并这个流程和增量学习中“新类别到来时只增加新分类器”的范式非常像。区别在于这篇论文强调的是离线场景下的多数据集合并而增量学习更关注在线式的新类别扩展。我自己的体会是论文的价值不完全在于它的SOTA数字而在于它提供了一个极简但可解释的基线。它的设计每个模块都指向明确的问题共享backbone负责提供统一空间独立分类头避免标签冲突原型相似度提供类别对应合并机制产生统一输出。这种“每个部件都有明确职责”的论文比很多堆模块的工作更能给人启发。还有一个小经验想分享我在自己复现时吃过一次亏只训练数据量最大的那个数据集对应的原型导致小类的原型位置极不稳定推理时匹配常常失败。后来重新做了数据均衡采样把每次迭代中采样到各数据集的概率调均匀稳定性一下子就上来了。如果你的数据量差异非常大这是最值得先检查的地方。
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。