开放集目标检测(Open-Set Detection):检测训练时没见过的类别——怎么做到的

一个目标检测器训练时只见过猫和狗,测试时眼前出现一只鹿,它会怎么办?正常的话,它会把鹿认成猫或狗,然后信心满满地输出一个边界框。你可能会觉得这没什么——其实这背后藏着一个很多模型都假装看不见的问题:分类器天生只能从已知选项里选答案。开放集目标检测要解决的,恰恰是「当答案根本不在选项里时,模型该不该说我不知道」。

AI technology illustration

分类器的闭集世界

先看传统检测器为什么做不到。以 Faster R-CNN 或 YOLO 为例,最后一步都是对候选框做分类,分类器是一个带 softmax 的线性层。softmax 做的事很简单——把一整组数字变成一组加起来等于 1 的分数,然后取最大的那个。问题在于,这个操作是上帝视角:它不管物体是什么,只管给现有选项打分。

换句话说,模型面对一只鹿时,它根本不会问「这像不像我知道的东西」。它只会问「这更像猫还是更像狗」。如果鹿的特征跟狗更近一点,它就会自信地告诉你这是狗。这是闭集假设的必然结果:已知类别的概率总和固定为 1,未知类别根本没有位置。

你可能觉得这没什么大不了的,毕竟很多应用场景类别是固定的。但在自动驾驶、医学影像、工厂质检里,真正的威胁恰恰是「没见过的东西」——路上的轮胎、皮肤上的罕见病灶、传送带上掉落的新零件。这时候,一个只会闭眼选的模型比没有模型更危险。

把问题从「它是谁」换成「它是哪来的」

那怎么办?办法是换一个提问的方式。闭集检测问的是「这是哪个已知类别」,开放集检测问的是「这个特征来自已知分布吗」。后者很像异常检测,但在高维视觉上要难得多——图像特征不是一维的,而且已知类本身的方差就很大。

目前主流方法可以分成两条路线。

第一条路线:在分类器里显式加一个「未知」类别。听起来直接,但真正做过的人都知道它有多别扭。我最早就是这么想的,拿一堆陌生数据当负样本,训练模型把「不像已知的」都归入未知类。结果模型学会了偷懒——它把大量正常但遮挡严重、姿态怪异的已知物体也推给了「未知」,因为这样最保险。后来我才想明白,未知类别的样本是永远采样不完的,你越加,模型越倾向于把所有不确定的东西都扔进这个垃圾桶。

第二条路线,也是现在更被认可的:放弃在类别维度上区分,转而利用特征空间的距离或能量分数。已知类在特征空间里会形成一个个聚类,如果你的特征离所有已知聚类中心都很远,就判定为未知。这里有一个很关键的工具叫能量函数。

为什么能量函数比 softmax 公正

能量函数这个词听起来抽象,但思路很简单。对任意一个输入,模型可以算出一个标量能量 E(x),这个值越低,说明输入越「符合」已知数据的分布。之所以用能量而不是 softmax 概率,是因为 softmax 有一个致命缺陷:它会被已知类别之间的相对差异干扰。就算鹿的特征很像狗,它只有狗这个选项可选,所以狗的概率也会很高;但能量值可以把「像狗」和「高度像狗」区分开。能量函数的提出者给出了一个直观解释:softmax 概率本质上被 log-sum-exp 这个操作污染了,因为里面含着所有已知类的得分之和,而这个和会随着类别数量变化。

在实现里,你只需要换掉模型的最后一层,用 logsumexp 计算能量分数,然后划一个阈值:低于阈值是已知,高于阈值是未知。Energy-based Out-of-distribution Detection 这篇论文的表格显示,这个简单替换就能把未知样本的召回率提升一个量级,而几乎不掉已知类准确率。

但能量函数只能告诉你「这是不是已知的」,它不能告诉你未知物体到底长什么样。它本质上仍然是个拒绝器,不是探测器。

更进一步的开放世界检测:给未知物体也画一个框

真正的开放集目标检测,英文叫 Open-World Object Detection,它要求模型主动把未知物体找出来,并且给它们打上「未知」的标签——注意这可是一个边界框,不是简单否认。这个方向最有代表性的工作是 Towards Open World Object Detection,发表在 CVPR 2021。

它的流程可以拆成三步:

  1. 先用已知类别训练一个普通检测器,提取候选框的特征。
  2. 使用对比学习拉近同类特征,推开不同类特征,让已知类在特征空间形成几个紧凑的聚类。
  3. 对每个新候选框,计算它到所有已知聚类中心的距离。如果距离都超出阈值,就把它标记为未知候选,并在图中保留下来。

最妙的一步是第四步:当人工标注这些未知候选之后,模型不用重新训练,可以直接在当前模型上扩张出一个新的聚类。因为聚类是向量在原空间的扩展,而不是重新学习一个分类器。这叫增量学习。

这个方案让我们第一次看到「检测未知」和「发现新类」被统一起来了。但注意,它依赖对比学习训练出来的特征空间足够规整。如果已知类自己就挤成一团,那聚类中心之间的距离很难划得开,未知物体也会被误吸收。

一张表说清三种检测范式

范式 类别集合 核心问题 典型方法
闭集检测 训练与测试完全重叠 把每个候选框分到正确的已知类 Faster R-CNN、YOLO
开放集检测 测试包含未知类 区分已知 vs 未知,并拒绝未知 能量分数、距离阈值
开放世界检测 未知类可以随时加入 检测未知,之后纳入已知 ORE、对比学习

注意,现实中大多数「开放集检测」论文其实只做了开放集识别(OSR),也就是只判断图片级标签,不做目标定位。真正的检测必须同时给未知物体画框,难度又高了一截。

你可能会问的四个问题

开放集检测跟零样本检测有什么区别?

零样本检测是「训练时见过类别描述,测试时识别没见过的新类别」,本质上是利用语义信息做迁移。开放集检测的未知类别没有给任何提示,模型只能在特征空间里靠分布外判定来兜底。所以开放集检测更难,也更有不确定性。

阈值怎么定?一个分数够用吗?

不够。现实场景里已知和未知的特征边界很少有清晰鸿沟,很多未知物体可能跟某个已知类很接近,这会迫使阈值卡在刀刃上。实际工程上一般会用验证集调阈值,并同时看已知类的 F1 和未知类的召回,做一个帕累托选择。

为什么不能用「置信度低就当未知」?

置信度低只能说明模型对已知类之间的区分没信心,不代表它看到了新东西。比如一个严重遮挡的狗,它的置信度也可能很低,但它是已知类。反过来,如果模型过度自信,一张从来没见过的图也可能给它 0.9 的置信度。能量分数之所以更好,是因为它衡量的不是「像哪个已知类」,而是「是否落在已知分布里」。

开放集检测模型会不会学得越来越偏?

会。如果训练数据里未知类出现的概率很低,模型就会倾向于把所有东西都预测为已知,因为这样经验风险最小。这是分布不平衡问题的天然结果,目前没有一个方法能彻底解决,只能靠数据采样加权。

能力边界:它最好的定位是安全过滤层

那开放集检测现在到底能做什么?我的判断是:它最好的定位是安全过滤层,而不是独立的识别器。真正商用系统里,它负责把可疑区域挑出来,让人类或后续专门的分类器再看一遍,而不是直接下结论。

它的一个明显问题是严重依赖特征质量。如果你的特征提取器只在某个数据集上训练过,那一个风格完全不同的未知物体很可能被挤出已知分布,造成大量误报。更根本的是,已知类准确率和未知类召回率存在一个不可调和的跷跷板:你越想抓住所有没见过的东西,就越会把见过的但长得奇怪的东西扔掉。

如果让我给方向打分,我认为基于特征距离的思路比基于分类器对抗的思路更有前途,因为它不跟类别数量绑定。但距离阈值本身仍然是一个令人头疼的手工参数。也许未来的方向会引入密度估计或混合高斯模型,让「未知」本身也被建模成一种概率分布。

在你想清楚「模型其实什么都不知道」之前,开放集检测听起来像一句废话。但一旦你意识到模型的每个输出都只是在已知选项里做选择,你就会明白:让模型说「我不知道」,比让它学会一万个类别更难。

原创文章,作者:guanweilu,如若转载,请注明出处:https://guanweilu.cn/article/2320.html

赞 (0)
上一篇 21小时前
下一篇 21小时前

相关推荐