Expanding Low-Density Latent Regions for Open-Set Object Detection
CVPR2022
Code: https://github.com/csuhan/opendet2
这篇文章认为,CVPR2021oral(OWOD)中的方法需要未知类的额外开放集数据,违反了OSOD的原始定义。 我认为是OWOD是一个增量学习+OSOD的过程。
- OWOD:Open world object detection
- OSOD:Open set object detection
目录
摘要
基于未知目标经常分布在low-density latent regions,作者通过latent space的高/低密度区域分开的方式来识别未知目标。传统的基于阈值划分高低密度的区域的方式,不能包含全部的未知目标。
我们提出Open-set Detector来扩展低密度区域。 框架包含:Contrastive Feature Learner (CFL)和 Unknown Probability Learner (UPL)
- CFL执行实例级对比学习,使已知类的特征更加紧凑,为未知类留下更多可能的低密度区域
- UPL基于预测的不确定性对未知概率进行优化,给为未知类留下更多可能的低密度区域
1. 介绍
1.1 大背景
尽管过去十年在目标检测方面取得了长足的进步,但现代目标检测器通常以封闭集的方式开发,认为测试过程中出现的目标类别包含在训练集中,因此在在处理在训练中从未见过的真实目标时表现不好。例如…
1.2 小背景
- consensus : unknown objects are usually distributed in low-density latent regions
- Traditional threshold-based methods only maintain limited low-density regions, which cannot cover all unknown objects
OSOD 可以看作是开放集识别 (OSR)的扩展。 尽管 OSR 已被广泛研究 [2, 7, 16, 43, 55, 57],但很少有作品试图解决具有挑战性的 OSOD。 Dhamija 等人首先对一些代表性方法的开集性能进行了基准测试,这表明大多数检测器在开集条件下被高估了。 米勒等人采用 dropout 采样来提高检测器在开集条件下的鲁棒性。 Joseph等人通过拟合已知和未知类别的能量分布,提出了一种基于能量的未知标识符。 总而言之,先前的工作通常利用预训练模型的hidden evidence (例如,输出标签)作为未知指标,代价是额外的训练步骤和复杂的后处理。 本方法是否可以只用闭集数据训练开集检测器,并将其直接应用于开集环境而无需复杂的后处理?
一个已知的共识:即已知对象通常聚集在潜在空间中形成高密度区域,而未知对象(或新图案)分布在低密度区域[5,18,41]。从这个角度来看,高密度潜伏区和低密度潜伏区的适当分离对于未知的识别是至关重要的。
然而,传统的方法,例如硬阈值(图1(a)),只能保持有限的低密度区域,因为较高的阈值将阻碍闭集精度。在这项工作中,本方法建议通过扩展低密度区域来识别未知对象(图1(b))。首先,本方法学习已知类的紧凑特征,为未知类留下更多的低密度区域。然后,本方法在每个实例中学习一个未知概率,作为一个阈值来划分已知类簇周围更多的低密度区域,最终可以很容易地识别分布在这些区域中的未知对象。
图1:在密集图像上,(a)基于阈值的方法,例如更快的R-CNN,由于有限的低密度区域(灰色),通常将未知对象(黑色三角形,例如斑马)错误地分类为已知类别(有色点,例如马匹)。(b)本方法通过扩展低密度区域来识别未知对象。本方法鼓励紧凑的提案功能,并学习明确区分已知和未知的类。
1.3 解决问题的方法
latent space表示为 Ω = Ω K ∪ Ω U \Omega=\Omega_{\mathcal{K}} \cup \Omega_{\mathcal{U}} Ω=ΩK∪ΩU ,其中 Ω K \Omega_{\mathcal{K}} ΩK 表示已知类的latend space, Ω U \Omega_{\mathcal{U}} ΩU 表示未知类的latent space 。
OpenDet有两个学习其组成:
- Contrastive Feature Learner (CFL)执行实例级对比学习,以鼓励类内紧致性和类间分离,通过缩小 Ω K \Omega_{\mathcal{K}} ΩK来扩展 Ω U \Omega_{\mathcal{U}} ΩU。
- Unknown Probability Learner (UPL)根据预测的不确定性学到每个实例的未知概率。当我们仔细优化UPL以保持闭集精度时,可以以未知类的可能性作为阈值划分 Ω K \Omega_{\mathcal{K}} ΩK和 Ω U \Omega_{\mathcal{U}} ΩU。
- 在测试阶段,如果一个实例的未知概率是所有类中最大的,我们直接将其归入未知类。
总结贡献:
- 据我们所知,我们是第一个通过模拟低密度潜伏区来解决OSOD(之前CVPR2021oral称之为OWOD)问题的人。
- 我们提出了一种新的开放集检测器(OpenDet),它有两个设计良好的学习器,CFL和UPL,它可以端到端的方式训练,并直接应用于开放集环境。
- 我们引入了一个新的OSOD基准。与以前的方法相比,OpenDet在所有开集度量上都有显著的改进,例如,OpenDet将绝对开集误差降低了25%-35%
2. 具体方法
2.1 Preliminary
We formalize OSOD based on prior works [ 12 , 25 ] [12,25] [12,25]. Let us denote with D = { ( x , y ) , x ∈ X , y ∈ Y } D=\{(x, y), x \in X, y \in Y\} D={(x,y),x∈X,y∈Y} an object detection dataset, where x x x is an input image and y = { ( c i , b i ) } i = 1 N y=\left\{\left(c_{i}, \mathbf{b}_{i}\right)\right\}_{i=1}^{N} y={(ci,bi)}i=1N denotes a set of objects with corresponding class label c c c and bounding box b. We train the detector on the training set D t r D_{t r} Dtr with K K K known classes C K = { 1 , … , K } C_{\mathcal{K}}=\{1, \ldots, K\} CK={1,…,K}, and test it on the testing set D t e D_{t e} Dte with objects from both known classes C K C_{\mathcal{K}} CK and unknown classes C U C_{\mathcal{U}} CU. The goal is to detect all known objects (objects ∈ C K \in C_{\mathcal{K}} ∈CK ), and identify unknown objects (objects ∈ C U \in C_{\mathcal{U}} ∈CU ) so that they will not be misclassified to C K C_{\mathcal{K}} CK. As it is impossible to list infinite unknown classes, we denote them with C U = K + 1 C_{\mathcal{U}}=K+1 CU=K+1.
和Open-set Recognition不同点在于:
- OSR的一张图片只包含已知或者未知的目标
- OSOD的一张图像可能既包含已知也包含未知目标。未知目标没有标签。
2.2 Baseline setup
2.3 Contrastive Feature Learner
图3.提出的的方法概述。左图:OpenDet是一个两级检测器,具有(a)对比特征学习器(CFL)和(b)未知概率学习器(UPL)。CFL首先利用对比头Ccontrast head将建议特征编码为低维嵌入。然后通过实例对比损失
L
I
C
\mathcal{L}_{I C}
LIC对小批量和内存库之间的嵌入进行了优化。UPL学习已知类$ C_{\mathcal{K}}
和
未
知
类
和未知类
和未知类 C_{\mathcal{U}}
的
概
率
,
具
有
交
叉
熵
损
失
的概率,具有交叉熵损失
的概率,具有交叉熵损失\mathcal{L}{CE}
和
未
知
概
率
损
失
和未知概率损失
和未知概率损失\mathcal{L}{UP}$。右图:一个插图,展示了不同组件的工作原理。彩色圆点和三角形分别表示不同已知和未知类别的建议特征。我们的方法通过扩展低密度latent space(灰色)来识别未知对象。
- 流行的对比表示学习通常采用大容量小批次[27]或记忆库[20]来增加样本的多样性。
- 虽然未知对象在训练中不知道,但已知类别的分离有利于未知识别;优化 L I C \mathcal{L}_{I C} LIC相当于将已知类的簇从低密度潜在区域中推开,如图2所示。从图中看,其实没有分得太开,这个可视化的方法倒是挺好,注意看看在这个分布中未知目标是怎么定义的,应该是通过UPL区分出来然后再画的这个图。但是文中没有介绍T-SNE这个方法的计算过程
图2.潜在特征的T-SNE可视化。我们将VOC类视为已知类(有色点),将非VOC类INCOCO视为未知类(黑色三角形)。我们的方法学习了已知类和未知类之间的清晰区分。
lass-Balanced Memory Bank
流行的对比表示学习通常采用大容量小批次[27]或记忆库[20]来增加样本的多样性,我们构建了一种新颖的类平衡记忆库来增加对象候选框的多样性。
具体地说,对于每个类 c ∈ C K c \in C_{\mathcal{K}} c∈CK,我们初始化大小为 Q Q Q的记忆库 M ( c ) M(c) M(c)。
然后,我们从一个mini-Batch中抽取具有代表性的候选框,分两步进行:
- (a)抽样 I o U > T m IoU>T_m IoU>Tm的候选框, T m T_m Tm是确保候选框包含相关语义的IoU阈值。
- (b)对于每个小批次,我们抽样与
M
(
c
)
M(c)
M(c)中现有样本最不相似(即最小余弦相似)的
q
(
q
≤
Q
)
q(q≤Q)
q(q≤Q)。这一步骤使我们的内存库存储了更多不同的样本。
然后重复以上步骤。
实例级对比学习损失
损失函数为:
L I C = 1 N ∑ i = 1 N L I C ( z i ) \mathcal{L}_{I C}=\frac{1}{N} \sum_{i=1}^{N} \mathcal{L}_{I C}\left(\mathbf{z}_{i}\right) LIC=N1i=1∑NLIC(zi)
L I C ( z i ) = 1 ∣ M ( c i ) ∣ ∑ z j ∈ M ( c i ) log exp ( z i ⋅ z j / τ ) ∑ z k ∈ A ( c i ) exp ( z i ⋅ z k / τ ) \mathcal{L}_{I C}\left(\mathbf{z}_{i}\right)=\frac{1}{\left|M\left(\mathbf{c}_{i}\right)\right|} \sum_{\mathbf{z}_{j} \in M\left(\mathbf{c}_{i}\right)} \log \frac{\exp \left(\mathbf{z}_{i} \cdot \mathbf{z}_{j} / \tau\right)}{\sum_{\mathbf{z}_{k} \in A\left(c_{i}\right)} \exp \left(\mathbf{z}_{i} \cdot \mathbf{z}_{k} / \tau\right)} LIC(zi)=∣M(ci)∣1zj∈M(ci)∑log∑zk∈A(ci)exp(zi⋅zk/τ)exp(zi⋅zj/τ)
where c i \mathbf{c}_{i} ci is the class label of i i i-the proposal, τ \tau τ is a temperature hyper-parameter, M ( c i ) M\left(\mathbf{c}_{i}\right) M(ci) denotes the memory bank of class c i \mathbf{c}_{i} ci, and A ( c i ) = M \ M ( c i ) A\left(c_{i}\right)=M \backslash M\left(c_{i}\right) A(ci)=M\M(ci). Note that we only optimize proposals with IoU > T b >T_{b} >Tb where T b T_{b} Tb is an IoU threshold similar to T m T_{m} Tm.
虽然未知对象在训练中不可用,但已知类别的分离有利于未知对象的识别。优化 L I C \mathcal{L}_{I C} LIC相当于将已知类的簇推离低密度潜在区域。如图2(b)所示,我们的方法只用闭集的训练数据就能学习已知和未知类之间的明显区分。
2.4 Unknown Probability Learner
CFL通过缩小已知类别的集群(即,高密度区域)来扩展低密度区域。然而,我们仍然缺乏明确的边界来区分高密度/低密度区域。传统的基于阈值的方法具有较小的阈值(例如,0.05),仅保持有限的低密度区域,不能覆盖所有未知对象。在这里,我们提出了未知概率学习器(UPL)来划分已知类簇周围的更多低密度潜在区域。
我们首先用K+1路分类器来扩充K路分类器,其中K+1表示未知类。
现在,我们只有闭集数据;为了训练分类器,我们放松了最大距离的原则,只确保所有已知对象都被正确分类,即保持闭集精度。在此前提下,我们将介绍如何学习未知概率。
回忆一下softmax Cross-Entropy (CE) Loss:
将类 c c c的softmax概率 p p p定义为:
p c = softmax ( s c ) = exp ( s c ) ∑ j ∈ C exp ( s j ) , p_{c}=\operatorname{softmax}\left(s_{c}\right)=\frac{\exp \left(s_{c}\right)}{\sum_{j \in C} \exp \left(s_{j}\right)}, pc=softmax(sc)=∑j∈Cexp(sj)exp(sc),
where C = C K ∪ U ∪ b g C=C_{\mathcal{K} \cup \mathcal{U} \cup b g} C=CK∪U∪bg denotes all known classes C K C_{\mathcal{K}} CK, unknown class C U C_{\mathcal{U}} CU and background C b g C_{b g} Cbg. 那么softmax交叉熵损失 L C E \mathcal{L}_{C E} LCE 公式为:
L C E = − ∑ c ∈ C y c log ( p c ) , y c = { 1 , c = c ∗ 0 , c ≠ c ∗ , \mathcal{L}_{C E}=-\sum_{c \in C} y_{c} \log \left(p_{c}\right), \quad y_{c}=\left\{\begin{array}{l} 1, c=c^{*} \\ 0, c \neq c^{*} \end{array},\right. LCE=−c∈C∑yclog(pc),yc={1,c=c∗0,c=c∗,
其中, c ∗ c^{*} c∗是有ground truth类别, y y y是one-hot类别。
简化表示为:
L C E = − log ( p c ∗ ) \mathcal{L}_{C E}=-\log \left(p_{c^{*}}\right) LCE=−log(pc∗)
学习未知类的概率
Since there is no supervision for the unknown probability
p
u
p_{u}
pu, we consider a conditional probability
p
u
′
p_{u}^{\prime}
pu′ under the ground truth probability
p
c
∗
p_{c^{*}}
pc∗. Formally, we define
p
u
′
p_{u}^{\prime}
pu′ as a softmax probability without the logit of ground truth class
c
∗
c^{*}
c∗ :
由于未知概率
p
u
p_{u}
pu没有监督,我们考虑在不是ground truth概率
p
c
∗
p_{c}^{*}
pc∗下的条件概率
p
u
′
p_{u}^{\prime}
pu′:
p u ′ = exp ( s u ) ∑ j ∈ C , j ≠ c ∗ exp ( s j ) , p_{u}^{\prime}=\frac{\exp \left(s_{u}\right)}{\sum_{j \in C, j \neq c^{*}} \exp \left(s_{j}\right)}, pu′=∑j∈C,j=c∗exp(sj)exp(su),
然后根据 p u ′ p_{u}^{\prime} pu′定义交叉熵损失 L U P \mathcal{L}_{UP} LUP
简化表示为:
L U P = − log ( p u ′ ) \mathcal{L}_{U P}=-\log \left(p_{u}^{\prime}\right) LUP=−log(pu′)
之后,我们联合优化 L U P \mathcal{L}_{UP} LUP和 L C E \mathcal{L}_{CE} LCE(如图3(b)所示), L C E \mathcal{L}_{CE} LCE保持闭集的准确性, L U P \mathcal{L}_{UP} LUP学习未知的概率。以图3(右下角)为例,优化 L U P \mathcal{L}_{UP} LUP相当于从已知类中划分出更多的低密度潜在区域(灰色),一旦我们完成训练,学习的未知概率就成为在这些低密度区域中识别未知对象的指标。
不确定性加权优化
虽然我们优化了条件概率 p u ′ p_{u}^{\prime} pu′而不是 p u p_{u} pu,但 L U P \mathcal{L}_{UP} LUP仍然会损害 L C E \mathcal{L}_{CE} LCE的收敛,导致已知类别的精度下降。受不确定度估计[11,45] 的启发,我们在 L U P \mathcal{L}_{UP} LUP中增加了一个加权因子 w ( ⋅ ) w(·) w(⋅),它被定义为 p c ∗ p_{c}^{*} pc∗的函数:
w ( p c ∗ ) = ( 1 − p c ∗ ) α p c ∗ w\left(p_{c^{*}}\right)=\left(1-p_{c^{*}}\right)^{\alpha} p_{c^{*}} w(pc∗)=(1−pc∗)αpc∗
[11] Terrance DeVries and Graham W Taylor. Learning confidence for out-of-distribution detection in neural networks.arXiv preprint arXiv:1802.04865, 2018. 3, 5
[45] Murat Sensoy, Lance Kaplan, and Melih Kandemir. Eviden-tial deep learning to quantify classification uncertainty. arXivpreprint arXiv:1806.01768, 2018. 3, 5
其中,
α
\alpha
α是超参数(默认情况下,
α
=
1
\alpha=1
α=1)。尽管有许多
w
(
⋅
)
w(·)
w(⋅)的设计选择,我们选择了一个简单而有效的公式。我们受到了流行的不确定性信号的启发:熵
w
(
p
)
=
−
p
log
(
p
)
w(\mathbf{p})=-\mathbf{p} \log (\mathbf{p})
w(p)=−plog(p)。上式具有类似于熵的曲线形状(见ourappendex),它也可以反映不确定性。但我们的实验结果表明,上式比熵更容易优化。
最终:
L U P = − w ( p c ∗ ) log ( p u ′ ) \mathcal{L}_{U P}=-w\left(p_{c^{*}}\right) \log \left(p_{u}^{\prime}\right) LUP=−w(pc∗)log(pu′)
此外,由于背景候选框通常会overwhelm小批量,因此我们采样相同数量的前景和背景候选,使我们的模型能够从背景类中召回未知对象。
furthermore, since background proposals usually overwhelm the mini-batch, we sample the same number of fore-ground and background proposals, enabling our model to recall unknown objects from the background class.
Hard Example Mining
让所有的未知对象学习未知的概率是不合理的,因为他们不属于未知类。因此,我们提出了不确定性引导的难例挖掘来优化高不确定性建议的 L U P \mathcal{L}_{UP} LUP,其可能与潜在空间中的实际未知对象重叠。
因此考虑两种确定性指导的挖掘方法:
- Max entropy. Entropy is a popular uncertainty measure [ 29 , 34 ] [29,34] [29,34] defined as: H ( p ) = − ∑ c ∈ C p c log ( p c ) H(\mathbf{p})=-\sum_{c \in C} p_{c} \log \left(p_{c}\right) H(p)=−∑c∈Cpclog(pc). For a mini-batch, We sort them in descending entropy order, and select top- k k k examples.
- Min max-probability. Max-probability, i.e., the maximum probability of all classes: max ( p ) \max (\mathbf{p}) max(p), is another uncertainty signal. We select top- k k k examples with minimum maxprobability.
UPL损失的代码:
class UPLoss(nn.Module):
"""Unknown Probability Loss
"""
def __init__(self,
num_classes: int,
sampling_metric: str = "min_score",
topk: int = 3,
alpha: float = 1.0):
super().__init__()
self.num_classes = num_classes
assert sampling_metric in ["min_score", "max_entropy", "random"]
self.sampling_metric = sampling_metric
# if topk==-1, sample len(fg)*2 examples
self.topk = topk
self.alpha = alpha
def _soft_cross_entropy(self, input: Tensor, target: Tensor):
logprobs = F.log_softmax(input, dim=1)
return -(target * logprobs).sum() / input.shape[0]
def _sampling(self, scores: Tensor, labels: Tensor):
fg_inds = labels != self.num_classes
fg_scores, fg_labels = scores[fg_inds], labels[fg_inds]
bg_scores, bg_labels = scores[~fg_inds], labels[~fg_inds]
# remove unknown classes
_fg_scores = torch.cat(
[fg_scores[:, :self.num_classes-1], fg_scores[:, -1:]], dim=1)
_bg_scores = torch.cat(
[bg_scores[:, :self.num_classes-1], bg_scores[:, -1:]], dim=1)
num_fg = fg_scores.size(0)
topk = num_fg if (self.topk == -1) or (num_fg <
self.topk) else self.topk
# use maximum entropy as a metric for uncertainty
# we select topk proposals with maximum entropy
if self.sampling_metric == "max_entropy":
pos_metric = dists.Categorical(
_fg_scores.softmax(dim=1)).entropy()
neg_metric = dists.Categorical(
_bg_scores.softmax(dim=1)).entropy()
# use minimum score as a metric for uncertainty
# we select topk proposals with minimum max-score
elif self.sampling_metric == "min_score":
pos_metric = -_fg_scores.max(dim=1)[0]
neg_metric = -_bg_scores.max(dim=1)[0]
# we randomly select topk proposals
elif self.sampling_metric == "random":
pos_metric = torch.rand(_fg_scores.size(0),).to(scores.device)
neg_metric = torch.rand(_bg_scores.size(0),).to(scores.device)
_, pos_inds = pos_metric.topk(topk)
_, neg_inds = neg_metric.topk(topk)
fg_scores, fg_labels = fg_scores[pos_inds], fg_labels[pos_inds]
bg_scores, bg_labels = bg_scores[neg_inds], bg_labels[neg_inds]
return fg_scores, bg_scores, fg_labels, bg_labels
def forward(self, scores: Tensor, labels: Tensor):
fg_scores, bg_scores, fg_labels, bg_labels = self._sampling(
scores, labels)
# sample both fg and bg
scores = torch.cat([fg_scores, bg_scores])
labels = torch.cat([fg_labels, bg_labels])
num_sample, num_classes = scores.shape
mask = torch.arange(num_classes).repeat(
num_sample, 1).to(scores.device)
inds = mask != labels[:, None].repeat(1, num_classes)
mask = mask[inds].reshape(num_sample, num_classes-1)
gt_scores = torch.gather(
F.softmax(scores, dim=1), 1, labels[:, None]).squeeze(1)
mask_scores = torch.gather(scores, 1, mask)
gt_scores[gt_scores < 0] = 0.0
targets = torch.zeros_like(mask_scores)
num_fg = fg_scores.size(0)
targets[:num_fg, self.num_classes-2] = gt_scores[:num_fg] * \
(1-gt_scores[:num_fg]).pow(self.alpha)
targets[num_fg:, self.num_classes-1] = gt_scores[num_fg:] * \
(1-gt_scores[num_fg:]).pow(self.alpha)
return self._soft_cross_entropy(mask_scores, targets.detach())
3. 实验
3.1 数据集
数据集。我们使用流行的Pascal VOC[14]和MS Coco[32]构建了一个OSD基准。我们使用VOC trainval进行闭集训练。同时,我们在COCO中选取了20个VOC类和60个非VOC类,在不同的开集条件下对我们的方法进行了评估。
这里我们定义了两个设置:VOC-COCO-{T1,T2} { T 1 , T 2 } \left\{\mathbf{T}_{1}, \mathbf{T}_{2}\right\} {T1,T2}.
- For setting T 1 \mathbf{T}_{1} T1, we gradually increase openset classes to build three joint datasets with n = 5000 V O C n=5000 \mathrm{VOC} n=5000VOC testing images and { n , 2 n , 3 n } \{n, 2 n, 3 n\} {n,2n,3n} COCO images containing { 20 , 40 , 60 } \{20,40,60\} {20,40,60} non-VOC classes, respectively.
- For setting T 2 \mathbf{T}_{2} T2, we gradually increase the Wilderness Ratio (WR) 2 [ 12 ] { }^{2}[12] 2[12] to construct four joint datasets with n n n VOC testing images and { 0.5 n , n , 2 n , 4 n } \{0.5 n, n, 2 n, 4 n\} {0.5n,n,2n,4n} COCO images disjointing with VOC classes. See our appendix for more details.
3.2 结果
表格
ORE[25]是之前的OWOD,能看出实验结果还行。
图像
此外,我们还给出了两个失败案例。图(a)我们发现OpenDet在一些对象密集的场景中表现不佳,例如,包含大量人的图像。(b)OpenDet将“真实”背景归类为未知类别。