R-FCN: Object Detection via Region-based Fully Convolutional Networks
论文链接:https://arxiv.org/abs/1605.06409
代码链接:https://github.com/daijifeng001/r-fcn
CVPR2016的文章,和上周的FPN一样是非常经典的文章。友情提醒下,FCN最早是用在分割上的,只搜FCN很容易出现分割方面的论文,如果想要搜检测方面的应用,最好搜R-FCN。那么,下面开始本次的内容。
1. 问题介绍
如图所示,我们都知道,Faster RCNN在RPN阶段通过共享特征的方式节省了大量的计算量,但是到第二个阶段,通过RoI pooling后获得的每个RoI的特征又要经过一个含有fc的子网络来对其进行分类和回归。fc层本身其实就有参数多计算量大的特点,RoI后的每个feature map要经过两个fc层一个class softmax(也是fc),无形中加大了计算量、浪费了时间。因此,一个自然而然的想法就产生了,能不能想办法消除这种浪费,进一步提高检测速度?
实际上,类似ResNet这种网络都是在最后才加个fc层用于分类的,参考这种思路再结合RPN的特征共享,能不能直接在卷积层共享特征后,直接抽出RoI然后接个fc层一步到位地分类和回归而不是再经过一个子网络?放在Faster RCNN中,可以考虑用ResNet来做BackBone,提取出用于共享的特征,然后RoI后直接进行分类回归,这种思路就是Naive Faster RCNN……但是实验发现了,这种思路的实验结果很差,一个最明显的特征是检测的精度和分类的精度差距很大。
那么,原因是什么呢?一方面,分类任务是有translation invariance特点的,就是说图像中物体的移动并没有太大的差别;但是另一方面,检测任务却是translation variant的,例如预测出的box就必须对它是否较好地覆盖了object做出反馈,否则位置偏差就没办法修正。 ResNet文章就探讨过这个问题,并通过强行在卷积层之间插入了RoI这种位置敏感层的方法来破坏分类的transalation invariance。
作者在本文中提出了另一种更为自然的思路来解决这种差异性,关键就是作者称之为position-sensitive score maps的东西。具体来说,就是对RoI划分网格,每个网格分别来预测物体的种类,并通过所有网格的结果来确定物体的种类。因为引入了网格位置的原因,物体的位移将使得每个网格的结果产生较大的不同,所以分类任务就会开始对位移敏感。
这里有一个比较清晰的对比图:
这里每个RoI用的是3x3的网格。可以看到,随着RoI位置的变化,每个网格在position-sensitive score maps中覆盖的内容将会产生较大的变化,例如右上的网格就从原来正好覆盖强响应区域(全白)的情况变成覆盖没有响应区域(全黑)的情况,因此3网格内的值完全不同,直接影响了最终分类结果,这就是大致的思路。下面来看怎么得到这个score maps和具体的网络。
2. 实现
关键思路
position-sensitive scores maps的关键思路如下图所示:
如图所示,网络在经过常见的特征提取网络后,会在最后的卷积层生成一个k^2(C+1)个通道数的网络,其中C代表的是类别个数,+1是因为还有个BG类。平摊下来,每个类别对应k^2的通道,这里的kxk就是划分网格的(例如我们在上面图中举出的例子就是3x3的网格,也就是k=3的情况)。换句话说,每个通道会生成一个网格数据,那么在每个类别下的kxk个通道就会生成kxk个网格,组成一个变长为k的正方形作为position-sensitive scores maps.
具体细节
- BackBone:作者选用的是ResNet,为了实现fully convolutional的效果,做了一些改变,移除了平均池化层和fc层,添加了一个1x1的卷积层用于减少通道数量和一个用于生成k^2(C+1)通道数的卷积层
- positive-sensitive roi pooling:这个主要解决的是如何从k^2(C+1)个通道中的一个获取roi的区域,来pooling成kxk中对应的网格值的问题。具体公式可以到论文中计算,主要用的还是平均值池化
- 从position-sensitive scores maps到类别预测:在得到每个类别的kxk的scores maps后,求它们的平均值,得到的数作为该类别的分数,这样可以得到C+1个类别的C+1个分数,然后用softmax就可以求出置信度
- 如何进行边框回归:和类别预测非常相似,在生产k^2(C+1)个类别通道的同时,也生产4k^2个通道,然后用类似的思路进行边框回归。注意到这里是没有类别信息的,因此预测出来的框是class-agnostic的。
按照上面的思路,我们可以发现,这个网络实际上在RoI层之后就没有需要学习的层了,这也体现出了R-FCN要精简网络、加快运行的思路。最后放一个整体网络图:
其它
除了上述细节外,还需要提的有两点,一个是作者训练时采用了改变的OHEM策略(online hard example mining),即会对所有的RoI按照Loss排序,选择其中loss最大的若干个进行训练。
另一个就是作者除了改变ResNet-101的网络结构,似乎也改变了一些细节,比如conv5 block的stride。
3. 实验结果
作者做的对比实验比较多,来看其中比较关键的几个。先是之前提到的naive faster rcnn,结果如下:
可以看到,正如之前所说,naive faster rcnn的效果并不好;而R-FCN的kxk是1x1怎么没有办法收敛?因为1x1本质上是没有位置信息的,也就是说k=1的情况并没有很好地反映位置的变化,完全背离了R-FCN的设计思路。
接下来是和Faster rcnn的全方位对比:
收益于RoI之后没有需要学习的层,RoI数量的增加不会影响R-FCN的训练时间,但是对于Faster RCNN则并非如此,甚至在RoI数量饱和后容易不收敛……而R-FCN的效果也是最好的。
最终的比较结果:
R-FCN使用了multi-sc train(也就是在训练时会随机选择训练图片的尺度)后,取得了很可观的效果。虽然不如Faster R-CNN+++,但是全面优于Faster RCNN,最重要的是速度非常快。
(以上数据均为在PASCAL VOC上的结果)
4. 总结
R-FCN感觉受FCN启发还是挺大的。虽然作者提到了提高检测速度的因素,但是我认为这篇文章最大的亮点还是在对分类位置变化不敏感性和检测位置变化敏感性的分析,有点深入剖析任务本质的味道。