今天给大家介绍一篇个人觉得对 detection 非常有 insight 的一篇文章:"Cascade R-CNN: Delving into High Quality Object Detection".
在这篇文章中, 作者对 detection 问题中的两个核心, 分类和定位做出了细致的分析和观察, 并从这样的观察中得到启发, 提出了一个非常简单易行, 但是效果十分显著的办法.
这篇文章的基础是 two-stage detector, 如 RCNN,RFCN 等, 在这些 two stage detector 中, 都会有一个 header 的结构来对每一个 proposal 同时做两件事情: classification 和 bounding box regression(bbox reg). 在 classification 中, 每个 proposal 会被根据一个指定的 IoU 值分为正样本和负样本; 在 bbox reg 中, 每个被标记为正样本的 bbox 会向其 assign 的 ground-truth 方向回归.
这里作者第一个关键的发现是在 classification 中, 指定不同的 IoU 划分正负样本, 会导致 bbox reg 的行为完全不一样. 如下图左, 横轴是输入的 proposal 的 IoU, 纵轴是经过 bbox reg 之后的 bbox 和 ground-truth 的 IoU. 可以看到, 低 IoU threshold 对于低 IoU 的样本有更好的改善, 但是对于高 IoU 的样本就不如高 threshold 的有用. 原因在于不同 threshold 下样本的分布会不一致, 也就导致同一个 threshold 很难对所有样本都有效.
一个直接的想法是, 为什么不可以直接使用高 IoU 呢? 这就会导致第二个问题, 也就是 proposal 的质量过差, 导致高 IoU 的正样本数太少. 如果强行这样训练的话, 就会导致严重的 overfitting 问题. 如上图右所示, threshold 从 0.5 到 0.6, 最终的 detection AP 有些许上升, 但是进一步提升到 0.7,AP 会急剧下降.
所以为了解决以上两个问题, 作者提出了一个 Cascade RCNN head 的办法 (上图 d). 即有多个 IoU threshold 递增的 header, 每一级使用上一级 refine 过后的 bbox 作为输入. 这样可以保证每一级的 header 都可以得到足够多的正样本, 且正样本的质量可以逐级提升. 在训练和测试时, 这个操作也都保持一致. 在测试中, 作者使用多个 header 输出的均值作为这个 proposal 最终的分数, 可以证明对结果会有进一步的提升.
不同于之前的工作, 像 Iterative bbox refinement, 每次 refine 使用的是同样 threshold 训练出来的 header, 这会导致 IoU 到一定值之后很难更进一步改善; 像 Integral loss, 只有一个 bbox reg, 但是有针对不同 threshold 的 classifier, 这本质上也并不能改善最终定位的精度.
在实验中, 作者在 COCO dataset 上做了细致的分析, 在多个不同 backbone 的网络上都可以持续性地提升 3~4 个点的 AP. 这对于 COCO 来说, 已经是非常显著的改进了. 同时, 这个结果对比其他 state-of-the-art 方法仍然也很有优势.
个人总结: Detection 其实并不是一个很合适的分类问题, 没有一个明确的离散的正负样本的定义, 而是通过 IoU 来连续定义的. 但是 IoU 这个指标很难通过 gradient descent 来优化, 虽然之前也有一些 IoU loss 的工作, 但是效果并不理想. Cascade RCNN 便是一个在这个方向上很好的尝试.
来源: http://www.tuicool.com/articles/go/R7ZZNzF