MMDetection学习系列(4)——Cascade R-CNN深度探索与实战指南
目录
引言
背景
模型介绍
Faster R-CNN
Iterative BBox
Integral Loss
Cascade R-CNN
Cascaded BBox Regression
Cascaded Detection
实验结果
Coovally AI模型训练与应用平台
总结
引言
Cascade R-CNN作为目前主流常用的高性能目标检测算法中最广为人知的算法之一。它基于经典的Faster R-CNN架构,通过引入级联式的多阶段检测器来逐层提升检测精度,从而显著提高了模型在困难样本上的表现。
-
参考论文:https://arxiv.org/pdf/1906.09756
背景
在Faster R-CNN算法中,RPN输出指定数量的RoI候选框,然后输入到R-CNN层进行分类和回归,一般R-CNN部分是设置IoU=0.5来进行正负样本划分。
直观上训练时设置IoU越大,检测的bbox越少,但是普遍质量更好,也就是说 IoU如果设置的比较小,那么在训练过程中可能会带来很多噪声,不利于训练,但是如果IoU太高,会导致正样本太少出现过拟合,结合如下曲线可以进一步验证。
针对不同IoU阈值的regressor和detector进行了实验。从图c可以看出,不同IoU阈值的detector对不同水平的bndbox的优化程度不同,bndbox IoU与detecor的训练阈值越接近,box regress提升越高。而在图c中,detector(u=0.5)在低IoU水平下比detector(u=0.6)表现优异,而在高IoU水平下则反之,而当u=0.7时,由于正样本的不足以及推理时输入的样本IoU较低,detector(u=0.7)的整体表现都降低了。只有输入proposal自身的 IoU分布和detector训练用的阈值IoU较为接近的时候,detector性能才最好,或者说阈值IoU设置应该和R-CNN训练的输入样本IoU分布接近的时候,性能最好,如果两个阈值相距比较远就是mismatch问题。但图 (c)又说明不能一味的提高IoU来达到输出高质量bbox的目的(对应匹配正样本数目不够,会出现过拟合)。
模型介绍
因此,提出了Cascade R-CNN来解决上面的问题。Cascade R-CNN是一个顺序的多阶段extension,利用前一个阶段的输出进行下一阶段的训练,阶段越往后使用更高的IoU阈值,产生更高质量的bndbox。Cascade R-CNN简单而有效,能直接添加到其它R-CNN型detector中,带来巨大的性能提升(2-4%)
既然在Faster R-CNN中不能一味的提高IoU来达到输出高质量bbox的目的,那一个很自然的想法是级联结构,在每个层级采用不同的 IoU 阈值来提升。
-
Faster R-CNN
目前经典的two-stage架构如上图(a)。第一阶段是一个提框的子网H0,用于生成初步的bndbox。第二阶段为特定区域处理的检测子网H1,给定bndbox最终的分类分数C和bndbox坐标B。
-
Iterative BBox
有的研究者认为单次的box regress是不足以产生准确的位置信息的,因此需要进行多次迭代来精调bndbox,这就是iterative bounding box regression:
单次回归(regression)对于边界框(BBox)的精度提升是不够的,因此通常采用多次迭代回归来逐步改进BBox。然而,在多次迭代过程中,不能使用同一个检测头(detection head)。这是因为,每次迭代后的BBox分布都会发生显著变化。即使在初始阶段回归器对BBox的分布最优,经过几次迭代后,它可能不再适用于新的分布,从而导致性能下降。
此外,训练时,IoU阈值设为0.5的回归器对具有更高IoU的假设(hypothesis)产生了次优的效果。图(c)展示了,当IoU阈值为0.5时,迭代回归对IoU大于0.5的假设造成了损害,相比于基准模型(baseline),效果更差。
因此,为了应对这种问题,迭代BBox回归通常需要进行提议积累(proposal accumulation)、框投票(box voting)等手工工程,且这种方法的增益(gain)并不稳定。研究表明,当迭代次数超过两次时,性能改进趋于平稳,甚至可能没有任何好处。
-
Integral Loss
IoU阈值(u)决定了正样本(positive)和负样本(negative)的划分。如果一个假设(hypothesis)与真实框(GT)的IoU高于u,则视为正样本;否则视为负样本。当u值较高时,正样本的数量较少,但背景区域(background)较少;而当u值较低时,可以获得更多样化的正样本,但这会导致检测器难以抑制接近的假阳性(close false positives)。因此,很难找到一个适用于所有IoU水平的分类器。
在推理阶段,RPN等提议生成器生成的假设大多质量较低,因此检测器需要具备更强的辨别能力,尤其是对低质量假设的辨识能力。
一种折衷方案是将IoU阈值设置为0.5,这虽然能提供较多的正样本,但也带来了较低质量的检测结果,通常被认为是接近的假阳性(如图(a)所示)。一种简单的解决思路是使用多个分类器,每个分类器在训练时使用不同的IoU阈值,并在推理时对这些分类器进行集成。在训练过程中,通过使用积分损失(integral loss),来优化多个质量层级。
然而,这种方法存在问题:它未能解决公式(14)中不同损失对正样本数量操作的差异。此外,随着IoU阈值增大,正样本数量迅速减少,这导致高质量分类器出现过拟合问题。而且,高质量分类器在推理时需要处理大量低质量提议,但它们并未针对这些低质量提议进行优化。因此,该方法在大多数质量层级上无法提高准确率,且相较于迭代边界框(Iterative BBox)方法,其增益有限。
因此,Integral loss在很多IoU水平难以表现出高的准确率。相对于原始的two-stage架构,Integral loss的架构收益相对较小
Cascade R-CNN
-
Cascaded BBox Regression
由于很难训练一个能应付所有IoU水平的regressor,可以把回归任务分解成一个级联的regression问题。
T是级联阶段数,每个regressor对于当前的级联输入都是最优的,随着阶段的深入,bndbox在不断的提升。cascade regression与iterative BBox有以下区别:
-
iteravtive BBox是后处理的方法,而cascaded regression是能够改变bndbox分布的重采样过程。
-
cascaded regression在训练和推理时是一致的,不存在区别。
-
cascaded regression的多个regressor对于对应阶段的输入分布是最优的,而iterative BBox仅对初始分布是最优的。
Bndbox在回归时,为了对scale和location有不变性,将对坐标的学习转移到对坐标差值的学习。由于坐标插值通常较小,因此将其进行归一化,以权衡定位与分类的loss。Cascade R-CNN在每一个stage结束后,都会马上进行计算这些均值/方差
-
Cascaded Detection
产生Cascade R-CNN的启发点主要有两个:
-
初始的bndbox分布大多落在低质量的区域,这对于高质量classifiers来说是无效的学习。
-
所有的曲线都高于对角线,即regressor都倾向于能够提升bndbox的IoU。
因此,以集合作为开始,通过级联regress来产生高IoU的集合。这种方法能在提升样本整体IoU水平的同时,使得样本的总数大致维持在一个水平,这会带来两个好处:
-
不会存在某个阈值的regressor过拟合
-
高阶段的detector对于高IoU阈值是最优的
随着阶段的深入,一些离群点会被过滤,这保证了特定阈值的detector的训练
在每一个阶段t,都独立一个对阈值最优的classifier 和regressor,是上一阶段的输出,是权重因子,是指示函数,表示背景的不加入计算。与integral loss不同,公式8保证了顺序地训练detectors来逐步提高bndbox质量。在推理时,bndbox的质量是顺序提高的,高质量的detectors只需要面对高质量的bndbox。
Cascade R-CNN训练流程相比Faster R-CNN, Cascade R-CNN训练流程只是多了一个循环而已。
def forward_train(self,
x,
img_metas,
proposal_list,
gt_bboxes,
gt_labels,
gt_bboxes_ignore=None,
gt_masks=None):
losses = dict()
# 对每个 R-CNN 阶段单独操作( 相比 Faster R-CNN 多了这一层循环)
for i in range(self.num_stages):
self.current_stage = i
# 注意每个 stage 的训练参数不一样,典型的例如 Iou 阈值
rcnn_train_cfg = self.train_cfg[i]
lw = self.stage_loss_weights[i]
sampling_results = []
# n 个 stage, 就会有 n 个 bbox_assigner 和 bbox_sampler
if self.with_bbox
bbox_assigner = self.bbox_assigner[i]
bbox_sampler = self.bbox_sampler[i]
num_imgs = len(img_metas)
# 对每张图片单独分配正负样本和采样
for j in range(num_imgs):
assign_result = bbox_assigner.assign(
proposal_list[j], gt_bboxes[j], gt_bboxes_ignore[j],
gt_labels[j])
sampling_result = bbox_sampler.sample(
assign_result,
proposal_list[j],
gt_bboxes[j],
gt_labels[j],
feats=[lvl_feat[j][None] for lvl_feat in x])
sampling_results.append(sampling_result)
# 按顺序,对每个 stage 进行 train
# 相比 Faster R-CNN,不仅仅要输出当前 stage 的 loss,还需要额外输出
# 预测后分类和 bbox 值,方便用于后续 stage refine
bbox_results = self._bbox_forward_train(i, x, sampling_results,
gt_bboxes, gt_labels,
rcnn_train_cfg)
# 记录当前 stage 输出的 loss
for name, value in bbox_results['loss_bbox'].items():
losses[f's{i}.{name}'] = (
value * lw if 'loss' in name else value)
# 如果不是最后一个 stage,则表示需要进行迭代训练
if i < self.num_stages - 1:
# pos_is_gts 表示哪些正样本是 gt bbox ( 因为在 R-CNN 阶段会注入 gt bbox 当做额外的
# RoI 以加速收敛和防止训练不稳定),在 refine 阶段要把这部分正样本剔除
pos_is_gts = [res.pos_is_gt for res in sampling_results]
# roi_labels 是在当前 stage 中定义的每个 proposal 的 label, 背景类别是 num_classes
roi_labels = bbox_results['bbox_targets'][0]
with torch.no_grad():
# 对于 label 为背景的 proposal 可能预测后依然是背景,也可能不是背景
# 为了能够保证一致性,需要将标注为背景的 roi_labels 替换为网络真正预测类别值
roi_labels = torch.where(
roi_labels == self.bbox_head[i].num_classes,
bbox_results['cls_score'][:, :-1].argmax(1),
roi_labels)
# 利用 rois bbox_pred 可以得到新的 proposals,用于下个 stage 训练
proposal_list = self.bbox_head[i].refine_bboxes(
bbox_results['rois'], roi_labels,
bbox_results['bbox_pred'], pos_is_gts, img_metas)
return losses
实验结果
作者在通用目标检测、实例分割数据集COCO上进行了实验,换上骨干网ResNeXt-152的Cascade R-CNN又刷出了新高度!AP达到50.9。如下图:
使用不同的检测器和骨干网,级联后都能获得大幅度的精度提升,如下图:
同时可见,级联后推断速度有少许变慢,但在可接受的范围内。
下图是将Cascade Mask R-CNN与基线版本比较的结果,在实例分割任务中,也取得了明显的精度提升。
作者还在一些特殊目标类、不同数据集上做了实验。
均表明该算法能一致性的提高精度。
Coovally AI模型训练与应用平台
Coovally AI模型训练与应用平台,它整合了整合30+国内外开源社区1000+模型算法。
在Coovally平台上,无需配置环境、修改配置文件等繁琐操作,可一键另存为我的模型,上传数据集,即可使用Cascade R-CNN等热门模型进行训练与结果预测,全程高速零代码!而且模型还可分享与下载,满足你的实验研究与产业应用。
总结
Cascade R-CNN通过引入多阶段级联结构,成功突破了传统目标检测方法在复杂样本处理上的局限性。它在小物体、遮挡物体和复杂背景下的表现尤为突出,成为了一种具有重要意义的目标检测算法。随着技术的不断发展,Cascade R-CNN也为后来的模型算法提供了非常好的创新思路。
如果您有兴趣了解更多关于模型算法的使用方法等,欢迎关注我们,我们将继续为大家带来更多干货内容!
别忘了点赞、留言、收藏哦!