论文:Cascade R-CNN: Delving into High Quality Object Detection
代码: https://github.com/zhaoweicai/cascade-rcnn
1. Motivation
两阶段目标检测的过程是:RPN提取proposal, 即第一阶段;然后检测的head对这些proposal精修,输出类别(得分)和物体boundingbox边界框,即第二阶段。而所谓一阶段目标检测就是没有RPN过程。
那有多阶段可以吗?当然可以,比如CascadeRCNN
多阶段平白无故出现吗?当然不是
有什么用呢?
回到两阶段检测的缺点,目标检测检测的好不好是看预测的bb和真实bb的IoU重合程度,那RPN提的这些proposal的IoU怎么样呢?答案是有好有差,甚至有的是背景,那如何滤除坏的呢?常见做法是设置一个IoU阈值,大于这个阈值的proposal送给后面的检测head精修,小的就不要了。
(注:NMS是把对某一个object提的所有proposal中不是IoU最大的排除掉,每个object都走这么一遭。)
这样带来一个问题,阈值怎么选择呢?靠经验吗?是的,确实是靠经验+多轮实验验证,但同时又带来一个问题,可能一个数据集上选0.5阈值,下一个选0.7,那再来一个数据集怎么办呢?
所以能不能不需要那么复杂的阈值选择方法呢?佛系一点?当然有,Cascade就是干这事的。
回到上一个问题,阈值选不好咋了,不允许我乱选是有什么危害吗?
是的,选不好模型就废了。具体地:阈值太小就将RPN中太多的proposal放给后面的head,自然其中包含了很多噪声,而这样训练后的网络在测试时RPN提的proposal质量就不怎么样了(IoU阈值默认为0);如果阈值太大,就没多少proposal能保留,送给Head训练的proposal太少,造成正负样本严重类别失衡(TP太少,FPN为啥提出,不就是想在提高阈值的情况下解决这个问题吗),造成过拟合。
2. How
作者怎么做的呢?作者观看到:不管阈值是多少,输入head的proposal的IoU比从head精修输出后的bb的IoU小。
即proposal经过head得到bb, bb的总是比proposal的IoU大;
那能否多整几个head,放给第一个head的IoU阈值设置小点,这些proposal的输出结果的IoU变高了,送给下一个head时也可以把IoU阈值抬高了,然后依次变难,跟升级打怪一样,关卡的越来越难(IoU阈值),但每过一关会升级(IoU变大),这样会淘汰一部分FP(多轮验证,不是真金运气不会那么好能连过好几关的),同时那些真金的TP都能过关斩将,而一开始IoU阈值还比较小的FN也能给放进来,说不定就修成了TP,提高了精度。
具体模型呢?
其中:a是普通的Faster RCNN,H0其实就是RPN网络提取出B0即为proposal,然后送给H1进行精修,即所谓的two-stage;bcd区分开,c是并行,本质还是two-stage。b注意head是一样的,都是H1,进行不断迭代更新,显然没有d灵活(d是CascadeRCNN, 参数更多,能调的自然也更充足)。bd都是相当于4-stage, 也就是multi-stage。而最重要的,给H1~H3放行proposal的IoU阈值分别设置为0.5,0.6,0.7
3. 效果
提点利器,各大比赛凡是刷点的都是CascadeRCNN,而且大家貌似这个阈值也从来没变过(因此其最大贡献就是解放了IoU阈值参数的调节)。
基本上是:无论什么数据集,无论什么backbone,无论什么trick(比如FPN),加上Cascade总能给你暴涨好几个点,本身已经成为非常work的trick了,或者说baseline了。当然,和R101 vs R152一样,不要贪多,多了容易过拟合,反而对性能不利。