从R-CNN到Faster-RCNN(上)

本篇博客梳理一下深度学习在目标检测这一领域其中最重要的一条主线:RCNN>SPPNet>Fast-RCNN>Faster-RCNN。

当然Faster-RCNN之后还有R-FCN,但是因为R-FCN中位置敏感图这个概念我一直觉得很神奇,所以后面准备单独再写一篇博客来讲R-FCN。

R-CNN

论文《Rich feature hierarchies for accurate object detection and semantic segmentation》

RBG大佬将CNN应用到目标检测领域的开山之作,效果拔群,一下子就把传统目标检测方法远远甩在身后。下面我们简单来看一下RCNN整个算法的流程。

从R-CNN到Faster-RCNN(上)

对于目标检测来说,通常我们要做的第一步就是选择候选框(region proposals),最粗暴简单的做法当然是滑窗啦!不过正常情况下我们肯定不会用滑窗,因为效率实在是太低了,在论文中,作者采用的是一种叫selective search的方法来选择候选框,对于一张图片,选出2000个候选框。

选出候选框后,下一步是要提取出每一个候选框的特征,这里就是RCNN有别于传统检测方法地方,作者使用预训练好的CNN网络来提取特征。但是这里就有一个问题,预训练好的CNN模型如VGG等要求输入的图片尺度是一样的,而selective search获得的2000个候选框尺度各异,因此需要cropping一个图像区域,或者warp一下,使输入的图片大小一致。

从R-CNN到Faster-RCNN(上)

我们选择跟ground-truth框IoU0.5的区域作为正样本,其它的作为负样本,在预训练的CNN模型上进行fine-tuning。

训练完之后,我们以fine-tuning之后的模型作为特征提取器,就可以获得2000个候选区域的相同维度的特征了。

但是现在又有一个问题了,那就是2000个候选区域的特征内存放不下,怎么办呢?只好存到硬盘下了,并且另外训练一个SVM分类器用于分类。

在这里,作者根据实际效果,把跟ground-truth的IoU0.3的区域作为正样本。初读论文的同学,可能会对这里感到疑惑,为什么一会是0.5,一会是0.3?实际上,0.5是fine-tuning阶段的取值,0.3是训练SVM的取值,并不冲突。

至于为什么两个阶段的取值不一样,以及为什么不直接用CNN最后的softmax层分类而要另外训练一个SVM分类器,作者在论文附录B中讨论了,有兴趣的同学可以自己去读一读。

最后就是训练一个bounding-box的回归器了,用于回归候选框。另外test阶段还有一个非极大值抑制(nms)的过程,来进行检测框的合并。

总的来说,RCNN分为这么几步:

从R-CNN到Faster-RCNN(上)

其中,提取特征这一步是十分耗时的,2000个候选区域需要计算2000次特征,而且需要大量的硬盘容量来存储这些特征,这都是RCNN需要改进的地方,也是下面的SPPNet所做的事情。

SPPNet

论文《Spatial Pyramid Pooling in Deep Convolutional Networks for Visual Recognition》

又是Kaiming男神的大作,在这篇论文中提出了空间金字塔池化的概念。

前面我们说了预训练CNN模型有一个缺点,就是需要输入固定大小的图片,原因在于在ImageNet上表现优秀的模型如VGG,GoogLeNet,resNet等,最后一个特征层的尺度大小都是7x7,因此后面一般都会跟一个7x7的卷积层或者池化层以便后面跟全链接层做推断,而这一层的核的大小往往就限定了输入图片的大小。

而Kaiming大佬是怎么解决这个问题的呢?就是在最后一个卷积层之后跟一个空间金字塔池化层

从R-CNN到Faster-RCNN(上)

如上图,黑色的表示最后一个卷积层conv5层,我们分别把它按(12,22,42)划分,每一个格子内再进行池化,我们就能够得到1+4+16=21维的特征(这里256表示的是通道数)。这样,不管conv5层的大小是多少,我们总能够获得固定维度的特征了,而当我们不在意最后一个卷积层的大小后,也就可以接收任意大小的图片了。

接下来我们讨论一个问题,feature maps是什么?在Kaiming大佬看来,feature maps = features and their locations。

从R-CNN到Faster-RCNN(上)

feature maps中的响应点对应了原图中目标的位置。因此,在RCNN中,我们只需要一次把原图输入到CNN中,得到conv5层的feature maps,而对2000个候选区域来说,我们只需要计算出它们在feature maps上对应的区域即可,尽管对应区域大小各异,但是通过一个空间金字塔池化层就可以得到相同维度的特征了。

从R-CNN到Faster-RCNN(上)

而且,在spp之后的全链接层是可以进行fine-tuning的,可以让分类更准确一些。

另外,由于对图片的输入大小没有限制了,因此可以使用多尺度(multi-size)进行训练。论文中使用了224和180两种尺度来训练网络,这两个网络的参数一样,可以共享,最后的收敛效果跟单尺度差不多,说明SPPNent可以接收任意大小的输入图片。

最后看一下RCNN跟SPPNet的训练时间:

从R-CNN到Faster-RCNN(上)

可以看到,主要的提升效率在于特征提取这一步,RCNN要计算2000次,而SPPNet计算一次就行了,速度大大提升了。

然而,SPPNet依然还是有缺陷的,主要是因为spp层无法进行反向传播,这就导致了spp层之前的卷积层没法进行fine-tuning,所以整个网络并不是end-to-end的,依然需要将特征写到硬盘进行分类和回归操作。

为了避免这个问题,rbg大佬单枪匹马在RCNN上更进一步,提出了Fast-RCNN,决解了整个网络的fine-tuning问题。那么,rbg大佬究竟是怎么做的呢?我们下回分解。