问题描述
Open World Detection
何为开放世界目标检测,文章认为需要完成两个目标
- 当一张图片中出现来自未知类别的物体,应该被分类至“未知”标签。
- 当已识别的“未知”标签可用时,模型应该可以逐步学习新类别。
难点
模型会在训练中将未知类别物体识别为背景:在训练已知类别物体的数据集时,未知类别物体作为“背景”出现在其中。
解决方法
在检测头发现一个未知物体后,会有一个Oracle在未知类别中为其提供标签。该方法被称为ORE,ORE包含:
- 对比聚类
- 未知感知提议网络
- 基于能量的未知识别
ORE
卷积模型在潜在空间中识别不同类别的物体,文章假设在目标检测器的潜在空间中学习类别之间的明确区分可能具有双重效果:
- 帮助模型学习一个未知实例的特征表示如何不同于一个已知实例的特征表示。
- 有助于学习新类别的特征表示,而不会于潜在空间中先前类别重叠。
为了实现如上效果,文章使用对比聚类。为了实现最好的聚类效果,需要在未知实例上进行监督,因此文章使用了RPN进行自动的未知伪标签标记。潜在空间中自动标记的未知实例的固有分离有助于文章基于能量的分类头区分已知和未知实例(?)
实现过程:
输入图片–>backbone提取特征–>RPN层选取感兴趣区域,即生成一组前景和背景实例的边框预测,以及相应的对象性分数,同时将具有高对象性分数但是不与gt框重叠的候选框标记为潜在的未知实例–>ROI head层–>对ROI head残差块(?)生成的特征进行对比聚类–>分类头学习一个能量函数,标记一个未知的预测。
对比聚类(Contrastive Clustering)
聚类损失计算如下:
其中C为类别的集合,c为当前认为的类别,D表示距离的函数,△定义相似和不相似项目的接近程度,fc为当前实例在中间层输出的特征向量,pi为某个类别的特征向量的平均值。当c=i即类别相同,距离越远惩罚越大,反之距离越远惩罚越小(-D)。
所有类别的特征向量的平均值需要不断进行维护,只有在轮数到达
I
b
I_b
Ib时才会开始计算对比聚类损失此后每
I
p
I_p
Ip轮更新P。
RPN自动标记未知类别
由对比聚类可知,对于未知类别需要一个标签(0)来使对比聚类函数生效,文章认为RPN是类别无关的,因此将RPN检测背景类别分数最高的k个标记为潜在的未知实例。
基于能量的未知检测器
Faster R-CNN 的分类头通常输出每个类别的概率(通过 softmax 函数计算)。在这种情况下,作者将这个分类头转换为一个能量函数,这意味着他们将分类头的输出解释为一种能量值,而不是概率。
赫姆霍兹自由能(Helmholtz free energy)表示系统在恒定温度下可以用来对外做功的最大能量。公式为:
F
=
U
−
T
S
F = U - TS
F=U−TS
- U:系统的内部能量。它表示系统所包含的总能量,包括动能和势能。
- T:系统的温度。
- S:系统的熵,代表系统的混乱程度或不确定性。
TS为无法用来对外做功的能量。
- 平衡态:在平衡态下,系统的亥姆霍兹自由能达到最小值。这意味着系统自发地演化到一个亥姆霍兹自由能最低的状态。
- 自发过程:对于自发过程,亥姆霍兹自由能会减少,直到达到最小值。自由能的减少意味着系统可以释放能量来做功
赫姆霍兹自由能:
在给定特征下,标签的概率密度为:
g l ( f ) g_l(f) gl(f)为模型的logits输出, p ( l ∣ f ) p(l|f) p(l∣f)近似softmax?与赫姆霍兹自由能相联系可以看出对于某个标签的赫姆霍兹自由能相当于负的logits输出。
由公式(2)可以看出,当温度不变时,微观状态的能量越大,自由能越大,对应到(3)中即Logits输出越小,自由能越大。
作者选择使用位移 Weibull 分布来建模。如果已知类别的能量值小于未知类别的能量值,则该样本可以被标记为未知类别。
复现踩坑记录
环境相关
参照https://zhuanlan.zhihu.com/p/501819672
完成detectron2的安装
问题:
- 安装requirement.txt中的reliability包时在在Preparing metadata卡住
参考https://blog.csdn.net/sinat_29957455/article/details/130285223
更新setuptools - TypeError: canonicalize_version() got an unexpected keyword argument ‘strip_trailin
参考https://blog.csdn.net/2302_76761277/article/details/140596436
提升setuptools版本
运行train_net.py
问题:
- 报错:ImportError: cannot import name ‘packaging’ from ‘pkg_resources’
参考https://blog.csdn.net/Vikanill/article/details/139338358
降低setuptools版本 - 报错:ValueError: tuple.index(x): x not in tuple
复现使用了自己的数据集,因此需要在detectron2/data/datasets/pascal_voc.py中修改VOC_COCO_CLASS_NAMES - 报错:Checkpoint detectron2://ImageNetPretrained/MSRA/R-50.pkl not found!
参考https://github.com/cunjunyu/BalancedMetaSoftmax-InstanceSeg/issues/3
运行如下指令pip install fvcore==0.1.1.dev200512