RepMet解析:少样本目标检测中的度量学习与多代表表示

📅 发布时间:2026/10/13 15:00:00
RepMet解析:少样本目标检测中的度量学习与多代表表示
这篇《RepMet》Representative-based Metric Learning基于代表学习的度量模型我第一遍是冲着“少样本目标检测”去读的读完发现它其实是先用少样本分类把度量空间讲清楚再把同一个思路顺延到检测上。整篇读下来我最深的印象是作者团队对“新类别参数从哪来”这个问题给出了一个很干净的回答——先在大量基类数据上学会一个衡量相似度的空间等新类别出现时只在这个空间里放几个代表点就能完成分类和检测。当时少样本检测的普遍做法是拿基类训一个检测器再用少量新类样本去微调最后的分类层。这个做法不是不行只是样本太少时很容易把分类边界学歪尤其是检测框里还有大量背景干扰微调几次就过拟合了。RepMet走的是另一条路分类器参数不微调而是改成在度量空间里做最近代表匹配。整篇论文的核心贡献可以概括成三点多代表表示、代表基元机制、端到端联合训练。如果你正在做少样本检测、度量学习或者想把目标检测器落到数据稀疏的业务场景里这篇都值得认真读。1. 为什么这篇论文值得读1.1 少样本检测的痛点与RepMet给出的答案先理清一个背景。常规目标检测训练时每个类别都有成千上万个标注实例检测器学到的分类权重天然带有“类别专属”的信息。一旦换成少样本场景比如只给你每类5张图你要做两件事找到物体在哪判断物体属于哪个新类。“找在哪”这件事RPN这类类别无关的区域提议机制勉强还能干难的是“判断属于哪个新类”——因为Softmax分类头的参数从来没学过新类少量样本也不足以把参数训好。RepMet的做法是把“分类”彻底换一种实现方式。它不再依赖一个分类权重矩阵而是维护一组类别代表representative每个代表是嵌入空间里的一个向量。预测时把候选区域也映射到这个嵌入空间算它和所有类别所有代表之间的距离距离哪个代表近就判给哪个类。这样一来新类出现时要做的事就变得非常轻只需要往代表集合里增加几个新向量不需要改动整个分类器。这个思路放在今天已经是少样本学习里最常见的框架之一但在当年是很有启发性的。它也解释了为什么论文标题要强调“Representative-based”整个方法的核心不是某个花哨的网络结构而是对“类别该怎么表示”的一种重新设计。1.2 读之前需要建立的两个背景概念如果你不是做度量学习出身直接读损失函数部分会有点绕。我建议先建立两个直觉。第一个是嵌入空间。可以把它想象成一个坐标系模型的目标是让属于同一类的东西落得近、不同类的东西落得远。这个坐标系本身不是手工设计的而是由神经网络从数据里学。RepMet里这个映射由两部分组成backbone提取原始图像特征embedding网络把RoI特征进一步压成一个d维向量所有的比较都发生在这个d维空间里。第二个是“用距离代替分类”。普通分类器会在网络最后接一个全连接层每个输出节点对应一个类别RepMet则把最后那层换掉——不训练类别权重而是把所有已知类别表示成若干个代表点用欧氏距离做最近邻判断。距离度量本身不可学习但代表点的位置和嵌入网络是共同学习的。换句话说模型学的不是“这是鸟”而是“鸟在空间里大致会长成什么样、和其它类别在空间里怎么区分”。少样本新类加入时这种表示方式的好处会被放大因为嵌入空间已经用大量基类数据训练稳定新类只需要映射少量样本到空间里并在合适位置放代表点。这也是这篇论文在思想上给我最大的收获。2. 方法核心多代表度量学习2.1 每个类不再只有一个原型很多早期的少样本方法每个类别只学一个原型向量比如把所有支持样本的均值当成代表。这样做简单但隐含一个假设每个类别的样本在特征空间里大致是单峰的、围绕一个中心分布的。现实中这个假设经常不成立。举例来说“鸟”这个类别展翅的、站立的、戏水的姿态在空间里可能分得很开“车”也有轿车、卡车、越野车等差别。用一个中心点去概括就会把多模态信息压成一个平均值类别边界容易被拉模糊。RepMet的关键改动是每个类别可以对应多个代表一个代表捕捉一种典型外观或语义子簇。多代表带来的挑战在于类别数量一多可学习参数会成倍增加。比如100个类、每类10个代表、每个代表256维那就是25万个参数。如果每个代表都独立去学在少样本设定下几乎必然过拟合。这就是为什么论文紧接着提出了代表基元机制。2.2 代表基元的共享与生成这是我读的时候觉得最有意思的部分。作者没有让每个代表直接作为独立参数去学而是引入了一组数量较少的“代表基元”representative basis。每个类别下的每个代表都由这些基元的加权组合生成。可以做一个生活化类比基元像一盒乐高积木的基本零件代表是用零件拼出来的成品。不同类别的成品可以共享同一批零件只是组合方式不同。比如“飞机”和“鸟”在嵌入空间可能都会用到“翅膀”相关的基元但因为权重不同最终代表的位置也不同。这种共享设计有两个直接好处一是参数总量小很多二是少样本新类加入时它只需要去调整少数几个基元组合权重而不是从零学一堆向量样本效率会高很多。Basis的引入也让“类别代表数量”和“样本数”解耦了。即使某个新类只有1个支持样本也不妨碍它生成多个代表——只要预训练阶段已经把基元学得足够好少量样本就能通过这些基元组合出合理的位置。这一点对新类尤其关键实际复现时也确实是K值越小基元机制的相对优势越明显。2.3 损失函数组合边缘似然、边距与多样性RepMet的监督信号不是传统交叉熵而是三类损失的组合。第一是负对数边缘似然。给定候选区域的嵌入向量x模型先找它所属类别内部最近的那个代表然后计算x属于该类的概率。分母要把x到所有已知类别的所有代表距离都算进来做一次softmax归一化。损失就是负对数概率。这个形式和普通softmax很像差别在于分母里出现的不是线性分类器的输出logits而是距离度量。用“边缘”这个词是因为模型隐含了一个变量x到底分配给所属类别里的哪一个代表这个变量在概率计算中被边缘化掉了。第二是边距损失。光有softmax式的损失训练时容易出现“正样本距离不紧、负样本距离不远”的凑合解。边距损失会专门挑那些极具竞争力的错误代表要求正样本与最近代表的距离比负样本的距离小一个margin。这个约束比单独跑softmax更直接训练也更稳定。第三是多样性正则。多代表最怕变成“多名代表一个观点”——如果多个代表收束到差不多同一个位置那多代表机制就废了。为了防止坍塌训练时会加一项惩罚鼓励同一类别内不同代表彼此拉开距离。这一项在消融实验里被验证是有效的。三个损失放在一起打包成一个整体去端到端优化。我复现时最直观的感受是多样性正则那项的权重不能设得太大否则代表的分布会被强行拉开反而破坏类内紧凑性但也完全不能省省了以后AP会掉一截。2.4 两阶段训练思路RepMet的训练分两个阶段。第一阶段在基类数据上进行。backbone、RPN、embedding网络、代表基元、还有每个基类自己的代表生成权重全部联合训练。这个阶段本质上是“学会整个度量空间”目标是让嵌入网络知道怎么把图像内容映射成有判别性的向量。第二阶段处理新类别。给定新类的K个标注样本作者将已经训练好的网络主体冻结只优化新类别代表的生成权重。也就是说嵌入网络不需要因为新类重新学习backbone也不需要调整模型只是往既有空间里“安放”新代表。K1到K10的实验里这个阶段都能很快收敛因为可学习参数很少。我自己对两阶段设计的理解是它精准地刻画了“知识”和“适应”之间的分工。知识在空间里适应在代表上。这个分工不仅减少了过拟合风险也降低了新类加入时的部署成本——你不用把整个检测器重新导出一遍只需要多存几个代表向量。3. 从分类到检测完整链路3.1 区域提议的类别无关性做少样本检测最开始我担心的是区域提议网络。RPN在基类训练后对新类物体能不能框得准理论上RPN本身是类别无关的它只回答“这个位置是不是一个物体”并不回答“是哪一类物体”。所以它在训练时虽然只看过基类但对新类物体仍然有一定响应只是分数往往偏低。RepMet没有在这个环节做太多文章而是把重点放在“框出来之后怎么分类”上。实操中如果要复现通常会把RPN的置信度阈值调低一些多保留候选框给后面的度量匹配留出余地。如果你在做不同数据分布的新类检测这一点更要注意。RPN的漏检问题在基类上不明显因为训练数据覆盖了基类的各种姿态和尺度但新类的物体外观如果和基类差异很大RPN不一定提得出来。这时候再好的度量空间也无济于事属于上游瓶颈。3.2 嵌入网络与RoI特征的对接具体链路是这样的图片进入backbone得到特征图RPN在特征图上产生若干候选区域。每个候选区域经过RoI Pooling或RoIAlign得到一个固定大小的特征块比如7x7。这个特征块再送进一个embedding网络被压缩成一个d维向量也就是嵌入空间里的坐标。关键在于这个embedding网络必须和代表处在同一空间里训练时才能通过距离互相牵制。RepMet把嵌入网络和代表联合训练让“提取特征”和“定义类别代表”是同一个优化目标下的两件事。我在动手复现时也会特别检查ROI特征的空间尺寸和embedding网络输入是否匹配很多人第一次跑通的时候都会在维度上对不上。embedding网络本身不需要很深我的经验是两三个卷积层加一个全连接层就够。它做的事更像是一个“空间投影器”而不是一个复杂的特征提取器。真正的视觉特征由backbone负责embedding主要负责把区域级的语义信息整到一个统一尺度的向量里。3.3 推理时的距离打分与阈值控制推理阶段每个候选区域被映射成向量后与所有已知类别的所有代表逐一计算欧氏距离。最终预测取距离最小的那个类别。这里有一个实际工程问题候选区域可能包含大量背景或低质量框如果它们离所有代表都很远硬分配反而会造成误报。RepMet的经典做法是设置距离阈值低于阈值才认为是某个已知类否则当作背景或忽略。阈值的选择需要结合具体数据集调整我一般先统计“正样本与正确代表之间的距离分布”和“负样本与错误代表之间的距离分布”在两者交叉区域附近找阈值比拍脑袋靠谱得多。另外多个类别代表之间的距离结构在推理阶段也是可以利用的。比如某个候选区域距离鸟类的第2个代表很近同时距离飞机类的某个代表也很近这种分数接近的情况容易造成类别混淆可以用类别间先验概率或NMS后处理来兜底。3.4 与常规检测器的一个直观对比常规Faster R-CNN在分类头里直接输出“类别数1”维的logits其中背景算一类。RepMet把这个逻辑换成“嵌入最近代表”背景判断也由距离阈值承担。这个替换表面上看只是改变输出形式实际上影响很深。在常规框架里每加入一个新类分类头的权重数量就会增加模型必须重新训练在RepMet里新类加入只是新增代表检测器的参数完全不膨胀。你甚至可以把代表当成一种“可插拔”的类别知识随时加入、随时移除。对长期维护一个检测系统的人来说这种解耦体验非常友好。当然代价也存在它要求嵌入空间一开始就要学得足够好。如果嵌入空间本身判别性不足后面再加代表也只是在一个烂坐标系里做文章。这也是为什么第一阶段联合训练非常重要不能省。4. 实验验证与消融分析的启示4.1 少样本检测基准与结果趋势RepMet在经典的少样本目标检测协议上做了验证比如把20个类别划分为15个基类和5个新类在K1、2、3、5、10张标注样本下评估新类AP也在COCO这种更大规模的基准上做了划分实验。当时的结论趋势非常清晰随着K增大新类AP稳步提升在同样的小样本设置下RepMet要明显高于“用基类预训练再对全部网络微调”的做法尤其K越小时差距越大。这说明两阶段训练加度量匹配的组合确实比直接在少样本数据上微调整个检测器要稳。有个细节值得注意新类AP和基类AP之间存在一定此消彼长。如果第二阶段的代表数量设得太大新类边界会侵入基类区域导致基类AP下降。我调参时发现控制好代表数量和多样性正则的权重可以把这个影响压到很小。4.2 少样本分类验证论文标题里专门写了classification说明分类实验不是顺带做的。他们在标准少样本分类benchmark上也验证了多代表表示的有效性通常还会对比每类只有一个原型的方法。结果上的核心结论是每类代表数量从1增加到M时准确率有明显提升但继续增加代表数量收益会饱和。这说明多代表的收益主要来自对类内多模态的建模而不是单纯增加模型容量。分类实验相对检测更干净很适合用来单独验证度量空间的质量。如果你只关心分类其实可以只保留论文前半部分的框架不接检测器。4.3 消融实验反应的三个关键因素我印象比较深的消融主要有三个方向。第一多代表对比单代表。去掉多代表机制、只用每类一个原型后性能下滑明显。这验证了“一个中心点不足以概括类别”的判断。第二代表基元对比直接参数化代表。作者对比了让每个代表作为独立可学习参数直接训练和用统一基元生成两种方式。结果显示基元生成在少样本设置下优势更大因为基元的共享能力缓解了代表参数过多带来的过拟合。这也印证了前面提到的“参数总量控制”的重要性。第三多样性正则的加入与否。去掉多样性正则性能同样会下滑因为代表会收敛到相似位置多代表退化成单代表。这些消融放在一起其实是把整个方法的设计逻辑完整推了一遍多代表提供了表达能力基元提供了共享与样本效率多样性正则保护了多代表的区分度。三者缺一不可。5. 复现路线与实操避坑5.1 从头搭建的五个步骤如果你想基于现有检测框架复现RepMet我建议按下面的顺序来。第一步准备数据划分。按少样本协议把类别分成基类和新类保证基类数据量充足新类的训练集只有K个标注样本。第二步搭建基础检测器。用Faster R-CNN作为底子完成backbone和RPN部分的初始化先用基类数据把检测器训练收敛得到一个可用的baseline。这里不需要急着接embedding先把定位能力稳住。第三步接入embedding网络和代表模块。RoI特征经过embedding网络得到向量同时定义好代表基元和每类代表数量把距离匹配损失替换掉原来的softmax分类损失。第四步联合训练第一阶段。把RPN损失、box回归损失、度量损失、多样性正则同时优化观察嵌入空间的类别聚类情况。第五步固定主干与embedding网络进入第二阶段。用新类的K个样本训练新类代表生成权重保存后加入推理流程完成少样本检测。5.2 参数设置与初始化技巧embedding维度一般取256或512太低放不下复杂的类别关系太高在少样本下容易过拟合。代表数量M从每类3到5个开始试不要一上来就设很大。基元数量B建议大于类别数但要远小于代表总数这样才能逼出共享。边距损失里的margin通常取0.1到0.5之间我一般先取0.2看训练早期损失是否稳定下降不稳定再调小。代表初始化很重要。如果直接用随机向量初始化训练初期容易把多个代表推到接近的位置再靠多样性正则拉回来效率很低。更稳的做法是用基类数据预先跑到一个弱分类器把每个类别的特征空间聚类成M簇用簇中心初始化代表。这个技巧实验里帮助很大。5.3 我在实际复现中踩过的坑第一个坑是训练损失尺度不一致。RPN和box分支的损失通常比度量损失大很多如果不做损失配平embedding网络很容易被引导着只练定位类别空间学不干净。我的做法是给度量损失单独设一个较大的权重并监控每类损失量级做动态调整。第二个坑是类别采样不平衡。检测器一图里RoI数量巨大多数是背景和易分样本。如果无脑把全部RoI丢进度量损失少数类别会淹没在大量易分类别里。我后来加了简单的难样本挖掘每个batch里从每个类别抽出同等数量的困难正负样本来算度量损失训练稳定很多。第三个坑是第二阶段的迭代次数。新类只有K张图的话训练几十步就能过拟合损失降得很漂亮但测试AP反而变差。我一般用验证集做early stopping实在没有验证集时就固定一个很小的迭代步数比如每类10到20步然后观察代表是否还在合理范围。第四个坑是推理时的后处理。由于预测依赖距离单纯比最小距离容易出现一个区域被多个类别同时接近的情况。我会对每个类别保留第二近的代表距离作为参考两者差距太小时宁可判给更常见类别或直接拒绝这在工程里能减少不少误检。5.4 常见疑问速查表我把平时被问得比较多的几个问题整理成了一张表方便快速查阅。疑问解答思路新类只有K个样本怎么还能学多个代表代表由预训练好的基元组合生成K个样本只需要学组合权重不需要从头学完整向量为什么不用triplet losstriplet需要构造三元组难样本选择策略复杂RepMet对所有负代表维护边距更稳定也更省心检测框定位怎么处理RPN负责找到候选框box回归分支仍按常规方式训练论文的主要改动集中在分类侧能不能把代表机制用到其它检测器上可以只要能从检测器拿到区域特征后面接embedding网络和代表匹配即可新类加入后旧类AP掉怎么办检查代表数量是否偏大、多样性正则是否合理必要时在第二阶段混入少量基类样本保持旧类边界结尾如果只让我给这篇论文留一条笔记我会写少样本场景下与其教模型认识更多新类不如先教会它一个稳定可靠的比较空间。RepMet把这一点贯彻得很彻底网络主体在基类上学会“怎么看东西”新类来了只需要在空间里放几个代表点。这个设计乍看简单但每个环节——多代表、基元共享、多样性正则、两阶段训练——都是在回答“少样本情况下参数从哪来、怎么不学歪”这个根本问题。后来我再看很多少样本检测或开放世界方向的工作都能隐约看到它的影子。如果你也正在做相关方向我建议别只盯着最后的实验数字而是把方法设计多读几遍每一个组件都可以单独拆出来迁移到自己的项目里。我自己复现时踩过的那些坑也大多集中在距离尺度、类别采样和第二阶段的过拟合上提前留意会少走很多弯路。