深度学习之目标检测:R-CNN、Fast R-CNN、Faster R-CNN

object detection 就是在给定的图片中精确找到物体所在位置,并标注出物体的类别。object detection 要解决的问题就是物体在哪里,是什么这整个流程的问题。然而,这个问题不是容易解决的,物体的尺寸变化范围很大,摆放物体的角度,姿态不定,可以出现在图片的任何地方,而且物体还可以是多个类别。

object detection技术的演进:RCNN->SppNET->Fast-RCNN->Faster-RCNN

传统的目标检测方法

传统的目标检测方法一般分为三个阶段:首先在给定的图像上选择一些候选的区域,然后对这些区域提取特征,最后使用训练的分类器进行分类。

1. 区域选择

这一步是为了对目标进行定位。传统方法是采用穷举策略。由于目标可能在图片上的任意位置,大小不定,因此使用滑动窗口的策略对整幅图像进行遍历,而且需要设置不同的长宽。这种策略虽然可以检测到所有可能出现的位置,但是时间复杂度太高,产生的冗余窗口太多,严重影响后续特征的提取和分类速度的性能。

2. 特征提取

提取特征的好坏会直接影响到分类的准确性,但又由于目标的形态多样性,提取一个鲁棒的特征并不是一个简单的事。这个阶段常用的特征有SIFT(尺度不变特征变换 ,Scale-invariant feature transform)和HOG( 方向梯度直方图特征,Histogram of Oriented Gradient)等。

3. 分类器

主要有SVM,Adaboost等

综上所述,传统目标检测存在两个主要问题:一个是基于滑动窗口的区域选择策略没有针对性,时间复杂度高,窗口冗余;二是手工设计的特征对于多样性没有很好的鲁棒性。

Region proposal+CNN(RCNN)

文章链接:Region-based Convolution Networks for Accurate Object detection and Segmentation

针对滑动窗口问题,region proposal(候选区域)是预先找出图中目标可能出现的位置,这可以保证在选取较少窗口(几千个甚至几百个)的情况下保持较高的召回率。并且获取的候选窗口要比滑动窗口的质量更高(滑动窗口固定长宽比)。针对特征选取,卷积神经网络(convolution neural network: CNN) 的特征比传统手工特征效果更好。因此在2014年,RBG(Ross B. Girshick )使用 Region proposal+CNN(RCNN)代替传统目标检测使用的滑动窗口+手工设计特征,设计了RCNN框架,使得目标检测取得巨大突破,并开启了基于深度学习的目标检测热潮。

1 检测流程

RCNN主要分为3个大部分,第一部分产生候选区域,第二部分对每个候选区域使用CNN提取长度固定的特征;第三个部分使用一系列的SVM进行分类。

下图是RCNN的整体检测流程:

深度学习之目标检测:R-CNN、Fast R-CNN、Faster R-CNN_第1张图片

  1. 首先输入一张自然图像;
  2. 使用Selective Search提取大约2000个候选区域(proposal);
  3. 对每个候选区域的图像进行拉伸形变,使之成为固定大小的正方形图像,并将该图像输入到CNN中提取特征;
  4. 使用线性的SVM对提取的特征进行分类。

下面我们来分布介绍这几个步骤。

1.1 候选区域的产生

RCNN使用Selective Search算法提取图像中的候选区域。

大牛们发明好多选定候选框的方法,比如EdgeBoxes和Selective Search。以下是各种选定候选框的方法的性能对比。

深度学习之目标检测:R-CNN、Fast R-CNN、Faster R-CNN_第2张图片

1.2 CNN特征提取

作者用 AlexNet 对得到的候选区域的图像进行特征提取,最终生成的是一个4096维的特征向量。注意 AlexNet 输入的是227x227大小的图像,因此在输入到 AlexNet 之前,作者把候选区域的图像首先进行了一小部分的边缘扩展(16像素),然后进行了拉伸操作,使得输入的候选区域图像满足AlexNet的输入要求(即227x227)。

作者在这里其实进行了一部分实验,考虑怎样使候选区域图像满足AlexNet的输入要求,在文章的附录A中进行了介绍,以下是附录A中实验的三种方法:最终作者选择的是D中的直接拉伸的方法。

深度学习之目标检测:R-CNN、Fast R-CNN、Faster R-CNN_第3张图片

1.3 SVM特征分类

作者论文里并没有介绍怎么进行SVM的特征分类,不过要注意的是作者为每个类都训练了一个SVM分类器,在训练/检测的过程中使用这些分类器为每一类进行分类。

CNN表面是在分类,但真正目的其实只是提取特征,提取特征之后,每个候选框可以得到一个4096维的特征向量,使用得到的CNN特征再输入线性SVM中训练分类器。

SVM支持向量机其实是可以支持多分类的,即SVMs分类器。但是论文不是对21个类(别漏了background类)使用一个SVM,而是使用了One-Versu-All的方法,对每个类别都使用个SVM(这里只需要20个SVM)。方法很简单,对于每个类别来说,一个Region如果不是该类别,那就是背景。由于负样本很多,使用 hard negative mining 方法。每个SVM判断候选框是否属于这一类。对于2000个候选框,将属于第i类的所有候选框进行分类,并按照得分进行降序排列,然后使用 MNS 去除重叠的候选框。

为什么不直接使用CNN的分类结果,而还要继续训练若干个SVM分类器呢?

作者也直接使用CNN分类结果进行了实验,发现效果相比SVM有所降低,他发现使用CNN直接分类结果并不注重于精确定位(我觉得这个情况很合理,因为CNN识别能力非常强大,非常的鲁棒,所以不是那么精确的定位也可以得到比较好的结果,所以不注重精确定位)第二个原因在于SVM 训练时采用的 hard negative mining 选择的样本比 CNN 中随机选择的样本要好,所以结果会更好。作者也提出,可能通过更改 fine-tuning 的一些细节可以提升效果(他们也是这么做的,Fast RCNN中他们改变了loss函数)。

因为CNN容易过拟合,想要期望样本数目多一些,所以在判断正样本的时候条件比较松,IoU>0.5就认为是正样本,而SVM本身是结构风险最小,以SVM为分类器时改变了正负样本的判定条件:候选框完全包含 GoundTruth 的定位框才是正样本,当IoU<0.3时是负样本。

2 训练与测试

2.1 训练

  1. 预训练 AlexNet 网络。将训练好的模型保存。
  2. fine-tuning 。这种方法也是当数据量不够的时候,常用的一种训练方式,即先用别的数据库训练网络,然后再用自己的数据库微调训练(fine-tuning)。 首先会逐步读入图片,然后采用 seletive search 对读入的图片生成候选区域,再计算每个候选区域和 ground truth (代码中的fine_turn_list)的IOU。当IOU大于阈值时,则认为是当前的候选区域属于正确类。并且将其标定为相应的类别(label)。这样每一个候选区域就会产生相应的label即(image, label), (image, label)就是Fineturn训练的训练集。然后利用这些数据训练 AlexNet 网络,这时候参数的初始化即为步骤1中与训练的结果,将训练好的 fine-tuning 模型保存。
  3. SVM训练。采用与2相同的方法生成 SVM 训练集。首先会逐步读入图片,然后采用 seletive search 对读入的图片生成候选区域,这时候会生成候选区域候选框的坐标信息, 再计算每个候选区域和 ground truth (代码中的fine_turn_list)的IOU。当IOU大于阈值时,则认为是当前的候选区域属于正确类,并且将其标定为相应的类别(label), 并将这个label对应的候选区域图(image)的候选框坐标信息与ground truth的位置信息作对比,保留相对位置(平移和缩放)信息保留下来(label_bbox),作为训练数据。这样整个训练数据则为(image, label, label_bbox)对。但是在训练 SVM 时不会用到label_bbox信息,SVM 还只是用来分类。而且需要对每种类型都单独训练一个分类器, 并保存训练好的模型,备用。另外 SVM 分类器的输入是 AlexNet 网络 softmax 链接层之前的全连接层的输出结果。
  4. 候选框回归(Reg_box)。这个模型的训练集就是3中方法生成的(image, label_bbox)对。模型会计算出候选框相对于 ground truth 的平移缩放结果。

2.2 测试

在测试阶段,首先使用selective search提取测试图像的2000个proposals,然后将所有proposal图像拉伸到合适的大小并用CNN进行特征提取,得到固定长度的特征向量。最终对于每个类别,使用为该类别训练的SVM分类器对得到的所有特征向量(对应每个proposal图像)进行打分(代表的是这个proposal是该类的概率)。如果不是背景,用Reg_box生成平移缩放值, 然后对生成的候选区域进行调整。最后应用了一次NMS(非最大值抑制)

作者对测试阶段的时间进行了分析,认为RCNN的优势在于:(1)CNN中共享网络参数(CNN本身特性);(2)CNN提取后的特征维度较低(相比之前的方法),计算更快。

作者在各阶段的一些细节

ImageNet预训练阶段

作者首先在ImageNet上进行了CNN的预训练,由于VOC 2012中训练数据较少(相对而言),所以使用ImageNet预训练然后再fine tune效果会更好。

Fine-tuning(微调)阶段

在微调阶段,作者把ImageNet上预训练的网络从1000个输出改为21个输出(VOC的20类+1类background),然后将所有与groundtruth的包围框的IoU>= 0.5的proposal看作正类(20类之一),其他的全部看作背景类。在训练时使用随机梯度下降(SGD),学习率为0.001,在训练的过程中随机选取32个postive样本和96个negative样本,这样选择是因为在提取的proposal中background样本要远远多于postive样本。

SVM分类器训练阶段

在训练SVMs的过程中,作者把IoU低于0.3的proposal设置为negative样本,对于postive则是groundtruth的包围盒图像。作者对每个类别都训练了一个线性的SVM分类器,由于训练图像过多,同时为了保证训练的效果,所以作者在训练的过程中采用了hard negative mining方法(hard negative mining训练方法在我看来就是通过训练挑出训练集中那些总是被识别错误的负样本作为训练集)。

为什么fine-tuning时采用的IoU阈值和SVM训练时采用的阈值不同呢?

首先作者承认,在实验开始他们并没有fine-tuning的过程,而最开始使用SVM训练时阈值就是0.3,在训练SVM时,正样本为groundtruth,负样本定义为与ground truth的IoU小于0.3的候选区域为负样本,介于0.3与0.7之间的样本忽略。

在后面的实验中加入fine-tuing 以后,采用相同的阈值效果比使用现在的0.5阈值要差很多。作者的猜想是阈值的设置并不是很重要,而是微调时数据量的问题,在微调时采用0.5阈值的话会出现很多所谓的“抖动”的样本,这些样本于groundtruth的IoU在0.5到1之间,采用0.5的阈值以后正样本增加了30倍,所以fine-tuning时训练数据增多,效果会更好。 
而且 fine-tuning 时担心过拟合的原因,要扩大正样本的样本量,所以定义比较宽松,但是SVM是最终用于分类的分类器,而且SVM原理就是最小的距离最大化,越难分的数据越有利于SVM的训练,所以对样本的定义比较严格。

Bounding-box回归

作者在完成了前面提到的“生成候选区域——CNN提取特征——SVM进行分类”以后,为了进一步的提高定位效果,在文章的附录C中介绍了Bounding-box Regression的处理。可以参考:深度学习之边框回归(Bounding Box Regression)。

小结:R-CNN在 PASCAL VOC2007上的检测结果从 DPM HSC的34.3%直接提升到了66%(mAP)。如此大的提升使我们看到了region proposal+CNN的巨大优势。 但是R-CNN框架也存在着很多问题:

  1. 训练分为多个阶段,步骤繁琐: 微调网络+训练SVM+训练边框回归器
  2. 训练耗时,占用磁盘空间大:5000张图像产生几百G的特征文件
  3. 速度慢: 使用GPU, VGG16模型处理一张图像需要47s。

针对速度慢的这个问题,SPP-NET给出了很好的解决方案。

SPP-NET (ECCV2014, TPAMI2015) (Spatial Pyramid Pooling)

它的特点有两个:

1.结合空间金字塔方法实现CNNs的对尺度输入。一般CNN后接全连接层或者分类器,他们都需要固定的输入尺寸,因此不得不对输入数据进行crop或者warp,这些预处理会造成数据的丢失或几何的失真。SPP Net的第一个贡献就是将金字塔思想加入到CNN,实现了数据的多尺度输入。如下图所示,在卷积层和全连接层之间加入了SPP layer。此时网络的输入可以是任意尺度的,在SPP layer中每一个pooling的filter会根据输入调整大小,而SPP的输出尺度始终是固定的。

2.只对原图提取一次卷积特征。在 R-CNN 中,每个候选框先 resize 到统一大小,然后分别作为CNN的输入,这样是很低效的。所以SPP Net根据这个缺点做了优化:只对原图进行一次卷积得到整张图的 feature map,然后找到每个候选框在 feature map 上的映射 patch,将此 patch 作为每个候选框的卷积特征输入到 SPP layer 和之后的层。节省了大量的计算时间,比 R-CNN 有一百倍左右的提速。

深度学习之目标检测:R-CNN、Fast R-CNN、Faster R-CNN_第4张图片

小结:使用SPP-NET相比于R-CNN可以大大加快目标检测的速度,但是依然存在着很多问题:

  1. 训练分为多个阶段,步骤繁琐: 微调网络+训练SVM+训练训练边框回归器
  2. SPP-NET在微调网络的时候固定了卷积层,只对全连接层进行微调,而对于一个新的任务,有必要对卷积层也进行微调。(分类的模型提取的特征更注重高层语义,而目标检测任务除了语义信息还需要目标的位置信息)

针对这两个问题,RBG又提出Fast R-CNN, 一个精简而快速的目标检测框架。

深度学习目标检测:FAST RCNN (ICCV2015)

SPP Net 真是个好方法,R-CNN 的进阶版 Fast R-CNN 就是在 RCNN 的基础上采纳了 SPP Net方法,对RCNN作了改进,使得性能进一步提高。

深度学习之目标检测:R-CNN、Fast R-CNN、Faster R-CNN_第5张图片

FAST RCNN 提出了一个可以看做单层 spp-net 的网络层,叫做 ROI Pooling,这个网络层可以把不同大小的输入映射到一个固定尺度的特征向量,而我们知道,conv、pooling、relu 等操作都不需要固定size的输入,因此,在原始图片上执行这些操作后,虽然输入图片size不同导致得到的feature map 尺寸也不同,不能直接接到一个全连接层进行分类,但是可以加入这个神奇的 ROI Pooling 层,对每个 region 都提取一个固定维度的特征表示,再通过正常的 softmax 进行类型识别。

FAST RCNN框架图如下:

深度学习之目标检测:R-CNN、Fast R-CNN、Faster R-CNN_第6张图片

与R-CNN框架图对比,可以发现主要有两处不同:

  • 一是最后一个卷积层后加了一个 ROI pooling layer,ROI pooling layer实际上是 SPP-NET 的一个精简版。同时加入了候选框映射功能,使得网络能够反向传播,解决了SPP的整体网络训练问题;  
  • 二是损失函数使用了多任务损失函数(multi-task loss),将边框回归直接加入到CNN网络中训练。 R-CNN 训练过程分为了三个阶段,而 Fast R-CNN 直接使用 softmax 替代 SVM 分类,同时利用多任务损失函数把边框回归也加入到了网络中,这样整个的训练过程是端到端的(除去 region proposal 提取阶段)。Fast R-CNN在网络微调的过程中,将部分卷积层也进行了微调,取得了更好的检测效果。
  • SmoothL1Loss取代Bouding box回归。    

小结:Fast R-CNN融合了R-CNN和SPP-NET的精髓,并且引入多任务损失函数,使整个网络的训练和测试变得十分方便。

缺点:region proposal 的提取使用 selective search,目标检测时间大多消耗在这上面(提取region proposal 2~3s,而提取特征分类只需0.32s),无法满足实时应用,而且并没有实现真正意义上的端到端训练测试(region proposal 使用 selective search 先提取出来)。

深度学习目标检测:FASTER RCNN (NIPS2015)

网络结构如下:

深度学习之目标检测:R-CNN、Fast R-CNN、Faster R-CNN_第7张图片

Fast R-CNN 存在的问题:存在瓶颈,Fast R-CNN 使用 selective search 找候选框,这个也非常耗时。那我们能不能找出一个更加高效的方法来求出这些候选框呢?当然可以,我们可以加入一个提取边缘的神经网络  Region Proposal Network(RPN)。也就是说找到候选框的工作也交给神经网络来做了。

具体做法:

  • 将RPN放在最后一个卷积层的后面
  • RPN直接训练得到候选区域

 深度学习之目标检测:R-CNN、Fast R-CNN、Faster R-CNN_第8张图片

NIPS2015 版本的 Faster R-CNN 使用的检测框架是 RPN网络+Fast R-CNN网络分离进行的目标检测,整体流程跟Fast R-CNN一样,只是region proposal现在是用RPN网络提取的(代替原来的selective search)。RPN的核心思想是使用卷积神经网络直接产生region proposal,使用的方法本质上就是滑动窗口。RPN的设计比较巧妙,只需在最后的卷积层上滑动一遍,因为anchor机制和边框回归可以得到多尺度多长宽比的 region proposal。 作者为了让 RPN 网络和 Fast R-CNN 网络实现卷积层的权值共享,训练 RPN 和 Fast R-CNN 的时候用了4阶段的训练方法:

  1. 使用在ImageNet上预训练的模型初始化网络参数,微调 RPN 网络;
  2. 使用(1)中 RPN 网络提取 region proposal 训练 Fast R-CNN 网络;
  3. 使用(2)的 Fast R-CNN 网络重新初始化 RPN, 固定卷积层进行微调;
  4. 固定(2)中 Fast R-CNN 的卷积层,使用(3)中 RPN 提取的 region proposal 微调网络。

权值共享后的RPN和Fast R-CNN用于目标检测精度会提高一些。

小结:Faster R-CNN 将一直以来分离的 region proposal 和 CNN 分类融合到了一起,使用端到端的网络进行目标检测,无论在速度上还是精度上都得到了不错的提高。然而 Faster R-CNN 还是达不到实时的目标检测,预先获取 region proposal,然后在对每个 proposal 分类计算量还是比较大。比较幸运的是YOLO这类目标检测方法的出现让实时性也变的成为可能。Faster R-CNN 可以达到每秒7帧,YOLO系列可以达到每秒40帧。

速度对比

深度学习之目标检测:R-CNN、Fast R-CNN、Faster R-CNN_第9张图片

Faster R-CNN的主要贡献是设计了提取候选区域的网络RPN,代替了费时的选择性搜索,使得检测速度大幅提高。

RCNN网络的演进

因为Faster-RCNN,这种基于CNN的 real-time 的目标检测方法看到了希望,在这个方向上有了进一步的研究思路。至此,我们来看一下RCNN网络的演进,如下图所示:

深度学习之目标检测:R-CNN、Fast R-CNN、Faster R-CNN_第10张图片

最后总结一下各大算法的步骤:

RCNN
  1. 在图像中确定约1000-2000个候选框 (使用选择性搜索)
  2. 每个候选框内图像块缩放至相同大小,并输入到CNN内进行特征提取 
  3. 对候选框中提取出的特征,使用分类器判别是否属于一个特定类
  4. 对于属于某一特征的候选框,用回归器进一步调整其位置

Fast RCNN
  1. 在图像中确定约1000-2000个候选框 (使用选择性搜索)
  2. 对整张图片输进CNN,得到feature map
  3. 找到每个候选框在feature map上的映射patch,将此patch作为每个候选框的卷积特征输入到SPP layer和之后的层
  4. 对候选框中提取出的特征,使用分类器判别是否属于一个特定类
  5. 对于属于某一特征的候选框,用回归器进一步调整其位置

Faster RCNN
  1. 对整张图片输进CNN,得到feature map
  2. 卷积特征输入到RPN,得到候选框的特征信息
  3. 对候选框中提取出的特征,使用分类器判别是否属于一个特定类
  4. 对于属于某一特征的候选框,用回归器进一步调整其位置

总的来说,从R-CNN, SPP-NET, Fast R-CNN, Faster R-CNN一路走来,基于深度学习目标检测的流程变得越来越精简,精度越来越高,速度也越来越快。可以说基于region proposal的R-CNN系列目标检测方法是当前目标检测技术领域最主要的一个分支。

你可能感兴趣的