论文笔记 《Fast R-CNN》

论文出处见:http://arxiv.org/abs/1504.08083
项目见:https://github.com/rbgirshick/fast-rcnn

R-CNN的进化版,0.3s一张图片,VOC07有70的mAP,可谓又快又强。
而且rbg的代码一般写得很好看,应该会是个很值得学习的项目。

动机

为何有了R-CNN和SPP-Net之后还要提出Fast RCNN(简称FRCN)?因为前者有三个缺点

  • 训练的时候,pipeline是隔离的,先提proposal,然后CNN提取特征,之后用SVM分类器,最后再做bbox regression。FRCN实现了end-to-end的joint training(提proposal阶段除外)。
  • 训练时间和空间开销大。RCNN中ROI-centric的运算开销大,所以FRCN用了image-centric的训练方式来通过卷积的share特性来降低运算开销;RCNN提取特征给SVM训练时候需要中间要大量的磁盘空间存放特征,FRCN去掉了SVM这一步,所有的特征都暂存在显存中,就不需要额外的磁盘空间了。
  • 测试时间开销大。依然是因为ROI-centric的原因,这点SPP-Net已经改进,然后FRCN进一步通过single scale testing和SVD分解全连接来提速。

整体框架

整体框架如Figure 1,如果以AlexNet(5个卷积和3个全连接)为例,大致的训练过程可以理解为:

  1. selective search在一张图片中得到约2k个object proposal(这里称为RoI)
  2. 缩放图片的scale得到图片金字塔,FP得到conv5的特征金字塔。
  3. 对于每个scale的每个ROI,求取映射关系,在conv5中crop出对应的patch。并用一个单层的SPP layer(这里称为Rol pooling layer)来统一到一样的尺度(对于AlexNet是6x6)。
  4. 继续经过两个全连接得到特征,这特征有分别share到两个新的全连接,连接上两个优化目标。第一个优化目标是分类,使用softmax,第二个优化目标是bbox regression,使用了一个smooth的L1-loss.

除了1,上面的2-4是joint training的。
测试时候,在4之后做一个NMS即可。

整体框架大致如上述所示了,对比回来SPP-Net,可以看出FRCN大致就是一个joint training版本的SPP-Net,改进如下:

  1. SPP-Net在实现上无法同时tuning在SPP layer两边的卷积层和全连接层。
  2. SPP-Net后面的需要将第二层FC的特征放到硬盘上训练SVM,之后再额外训练bbox regressor。

接下来会介绍FRCN里面的一些细节的motivation和效果。

Rol pooling layer

Rol pooling layer的作用主要有两个,一个是将image中的rol定位到feature map中对应patch,另一个是用一个单层的SPP layer将这个feature map patch下采样为大小固定的feature再传入全连接层。
这里有几个细节。

  1. 对于某个rol,怎么求取对应的feature map patch?这个论文没有提及,笔者也还没有仔细去抠,觉得这个问题可以到代码中寻找。:)
  2. 为何只是一层的SPP layer?多层的SPP layer不会更好吗?对于这个问题,笔者认为是因为需要读取pretrain model来finetuning的原因,比如VGG就release了一个19层的model,如果是使用多层的SPP layer就不能够直接使用这个model的parameters,而需要重新训练了。

Multi-task loss

FRCN有两个loss,以下分别介绍。
对于分类loss,是一个N+1路的softmax输出,其中的N是类别个数,1是背景。为何不用SVM做分类器了?在5.4作者讨论了softmax效果比SVM好,因为它引入了类间竞争。(笔者觉得这个理由略牵强,估计还是实验效果验证了softmax的performance好吧 ^_^)
对于回归loss,是一个4xN路输出的regressor,也就是说对于每个类别都会训练一个单独的regressor的意思,比较有意思的是,这里regressor的loss不是L2的,而是一个平滑的L1,形式如下:

作者这样设置的目的是想让loss对于离群点更加鲁棒,控制梯度的量级使得训练时不容易跑飞。
最后在5.1的讨论中,作者说明了Multitask loss是有助于网络的performance的。

Scale invariance

这里讨论object的scale问题,就是网络对于object的scale应该是要不敏感的。这里还是引用了SPP的方法,有两种。

  1. brute force (single scale),也就是简单认为object不需要预先resize到类似的scale再传入网络,直接将image定死为某种scale,直接输入网络来训练就好了,然后期望网络自己能够学习到scale-invariance的表达。
  2. image pyramids (multi scale),也就是要生成一个金字塔,然后对于object,在金字塔上找到一个大小比较接近227x227的投影版本,然后用这个版本去训练网络。

可以看出,2应该比1更加好,作者也在5.2讨论了,2的表现确实比1好,但是好的不算太多,大概是1个mAP左右,但是时间要慢不少,所以作者实际采用的是第一个策略,也就是single scale。
这里,FRCN测试之所以比SPP快,很大原因是因为这里,因为SPP用了2,而FRCN用了1。

SVD on fc layers

对应文中3.1,这段笔者没细看。大致意思是说全连接层耗时很多,如果能够简化全连接层的计算,那么能够提升速度。
具体来说,作者对全连接层的矩阵做了一个SVD分解,mAP几乎不怎么降(0.3%),但速度提速30%

Which layers to finetune?

对应文中4.5,作者的观察有2点

  1. 对于较深的网络,比如VGG,卷积层和全连接层是否一起tuning有很大的差别(66.9 vs 61.4)
  2. 有没有必要tuning所有的卷积层?答案是没有。如果留着浅层的卷积层不tuning,可以减少训练时间,而且mAP基本没有差别。

Data augment

在训练期间,作者做过的唯一一个数据增量的方式是水平翻转。
作者也试过将VOC12的数据也作为拓展数据加入到finetune的数据中,结果VOC07的mAP从66.9到了70.0,说明对于网络来说,数据越多就是越好的。

Are more proposals always better?

对应文章的5.5,答案是NO。
作者将proposal的方法粗略地分成了sparse(比如selective search)和dense(sliding windows)。
如Figure 3所示,不管是哪种方法,盲目增加proposal个数反而会损害到mAP的。

作者引用了文献11的一句话来说明:““[sparse proposals] may improve detection quality by reducing spurious false positives.”
然后笔者搜索了一下,发现文献11被TPAMI15录取了,看来也是要看一下啊。。

很久没有更新网站,发现多了不少评论和问题,无法一一回复,如果现在仍有问题请再次留言 :) 2016.03.29