导读
Region CNN(RCNN)可以说是利用深度学习进行目标检测的开山之作。作者Ross Girshick多次在PASCAL VOC的目标检测竞赛中折桂,2010年更带领团队获得终身成就奖,如今供职于Facebook旗下的FAIR。
paper:《Rich feature hierarchies for Accurate Object Detection and Segmentation 》
RG大神的(Ross Girshick)这篇paper,改变了图像领域检测物体的实现思路,R-CNN是以深度学习为基础的物体检测的模型,以R-CNN为基点,后续的SPPNet、Fast R-CNN、Faster R-CNN模型都是照着这个思路,下面就来细致学习R-CNN模型。
在R-CNN模型出现之前,较好的物体检测模型DPM使用了一堆传统的算法模型,在VOC数据集上表现大约在30mAP左右。R-CNN开创性的提出了用深度神经网络来做物体检测。并且提出了一系列在较少标注集下的训练模型方法。
Introduction
R-CNN在物体检测上的解决方案
如上,RCNN算法分为4个步骤
- 1.候选区域生成: 一张图像生成1K~2K个候选区域 (采用Selective Search 方法)
- 2.特征提取: 对每个候选区域,使用深度卷积网络提取特征 (CNN)
- 3.类别判断: 特征送入每一类的SVM 分类器,判别是否属于该类
- 4.位置精修: 使用回归器精细修正候选框位置
【论文主要特点】(相对传统方法的改进)
- 速度: 经典的目标检测算法使用滑动窗法依次判断所有可能的区域。本文则(采用Selective Search方法)预先提取一系列较可能是物体的候选区域,之后仅在这些候选区域上(采用CNN)提取特征,进行判断。
- 训练集: 经典的目标检测算法在区域中提取人工设定的特征。本文则采用深度网络进行特征提取。使用两个数据库: 一个较大的识别库(ImageNet ILSVC 2012):标定每张图片中物体的类别。一千万图像,1000类。 一个较小的检测库(PASCAL VOC 2007):标定每张图片中,物体的类别和位置,一万图像,20类。 本文使用识别库进行预训练得到CNN(有监督预训练),而后用检测库调优参数,最后在检测库上评测。
本文解决了目标检测中的两个关键问题。
问题一:速度
经典的目标检测算法使用滑动窗法依次判断所有可能的区域。本文则预先提取一系列较可能是物体的候选区域,之后仅在这些候选区域上提取特征,进行判断。
问题二:训练集
经典的目标检测算法在区域中提取人工设定的特征(Haar,HOG)。本文则需要训练深度网络进行特征提取。可供使用的有两个数据库:
一个较大的识别库(ImageNet ILSVC 2012):标定每张图片中物体的类别。一千万图像,1000类。
一个较小的检测库(PASCAL VOC 2007):标定每张图片中,物体的类别和位置。一万图像,20类。
本文使用识别库进行预训练,而后用检测库调优参数。最后在检测库上评测。
创新点
采用CNN网络提取图像特征,从经验驱动的人造特征范式HOG、SIFT到数据驱动的表示学习范式,提高特征对样本的表示能力;
采用大样本下有监督预训练+小样本微调的方式解决小样本难以训练甚至过拟合等问题。
问题是什么
近10年以来,以人工经验特征为主导的物体检测任务mAP【物体类别和位置的平均精度】提升缓慢;
随着ReLu激励函数、dropout正则化手段和大规模图像样本集ILSVRC的出现,在2012年ImageNet大规模视觉识别挑战赛中,Hinton及他的学生采用CNN特征获得了最高的图像识别精确度;
上述比赛后,引发了一股“是否可以采用CNN特征来提高当前一直停滞不前的物体检测准确率“的热潮。
如何解决问题
测试过程
输入一张多目标图像,采用selective search算法提取约2000个建议框;
先在每个建议框周围加上16个像素值为建议框像素平均值的边框,再直接变形为227×227的大小;
先将所有建议框像素减去该建议框像素平均值后【预处理操作】,再依次将每个227×227的建议框输入AlexNet CNN网络获取4096维的特征【比以前的人工经验特征低两个数量级】,2000个建议框的CNN特征组合成2000×4096维矩阵;
将2000×4096维特征与20个SVM组成的权值矩阵4096×20相乘【20种分类,SVM是二分类器,则有20个SVM】,获得2000×20维矩阵表示每个建议框是某个物体类别的得分;
分别对上述2000×20维矩阵中每一列即每一类进行非极大值抑制剔除重叠建议框,得到该列即该类中得分最高的一些建议框;
分别用20个回归器对上述20个类别中剩余的建议框进行回归操作,最终得到每个类别的修正后的得分最高的bounding box。
阶段详解
总体思路再回顾:
首先对每一个输入的图片产生近2000个不分种类的候选区域(region proposals),然后使用CNNs从每个候选框中提取一个固定长度的特征向量(4096维度),接着对每个取出的特征向量使用特定种类的线性SVM进行分类。也就是总个过程分为三个程序:a、找出候选框;b、利用CNN提取特征向量;c、利用SVM进行特征向量分类。
R-CNN模型的处理流程:
- 找出图片中可能存在目标的侯选区域
- 通过CNN对候选区域提取特征向量
- 在候选区域的特征向量上训练分类器,分类器用于判别物体并得到bbox
- 修正bbox,对bbox做回归微调
候选框搜索阶段(找出图片中可能存在目标的侯选区域):
一张图片上存在的物体,大小/位置不固定,如果我们用滑窗的方法去寻找可能存在物体,工作量非常大,且很难实现。R-CNN模型使用的方法是先使用“传统成熟”的方法找出一组图像中可能存在目标的侯选区域(region proposals),产生侯选区域的方案可减少在一张图片上寻找物体的复杂度,且很大可能的保存了图片上所有存在物体的区域,这一方案发展的较为成熟,实现起来较为简便。
常用的产生侯选区域的方法:

R-CNN最终选择的产生候选区域产生的方法是selective search,
selective search的实现过程详情参考论文Selective Search for Object Recognition。
主要思想:
- 1)使用一种过分割手段,将图像分割成小区域 (1k~2k 个)
- 2)查看现有小区域,按照合并规则合并可能性最高的相邻两个区域。重复直到整张图像合并成一个区域位置
- 3)输出所有曾经存在过的区域,所谓候选区域
其中合并规则如下: 优先合并以下四种区域:
- A.颜色(颜色直方图)相近的
- B.纹理(梯度直方图)相近的
- C.合并后总面积小的: 保证合并操作的尺度较为均匀,避免一个大区域陆续“吃掉”其他小区域 (例:设有区域a-b-c-d-e-f-g-h。较好的合并方式是:ab-cd-ef-gh -> abcd-efgh -> abcdefgh。 不好的合并方法是:ab-c-d-e-f-g-h ->abcd-e-f-g-h ->abcdef-gh -> abcdefgh)
- D.合并后,总面积在其BBOX中所占比例大的: 保证合并后形状规则。
上述四条规则只涉及区域的颜色直方图、梯度直方图、面积和位置。合并后的区域特征可以直接由子区域特征计算而来,速度较快。
下图是selective search在图片上提取侯选区域的过程:
Selective Search在一张图片上提取出来大概2000个侯选区域,需要注意的是这些候选区域的长宽不固定。而在下一层使用CNN提取特征向量时,需要接受固定长度的输入,故我们需要对候选区域做一些长度上的修改。
论文对图片做了两种方法的比较:
- 各向异性缩放,即直接缩放到指定大小,这可能会造成不必要的图像失真
- 各向同性缩放,在原图上出裁剪侯选区域,在边界用固定的背景颜色(采用侯选区域的像素颜色均值)填充到指定大小
2.为什么要将建议框变形为227×227?怎么做?
本文采用AlexNet CNN网络进行CNN特征提取,为了适应AlexNet网络的输入图像大小:227×227,故将所有建议框变形为227×227。
那么问题来了,如何进行变形操作呢?作者在补充材料中给出了四种变形方式:
① 考虑context【图像中context指RoI周边像素】的各向同性变形,建议框像周围像素扩充到227×227,若遇到图像边界则用建议框像素均值填充,下图第二列;
② 不考虑context的各向同性变形,直接用建议框像素均值填充至227×227,下图第三列;
③ 各向异性变形,简单粗暴对图像就行缩放至227×227,下图第四列;
④ 变形前先进行边界像素填充【padding】处理,即向外扩展建议框边界,以上三种方法中分别采用padding=0下图第一行,padding=16下图第二行进行处理;
经过作者一系列实验表明采用padding=16的各向异性变形即下图第二行第三列效果最好,能使mAP提升3-5%。
经过一系列的实验,作者发现采用各向异性缩放的实验精度最高.
CNN特征提取阶段(通过CNN对候选区域提取特征向量):
用CNN的作用是在侯选区域的基础上提取出更高级、更抽象的特征,高级特征的作用是为下一步的分类器作为输入数据,分类器依据高级特征回归出物品的位置和种类。
在讲到CNN用作分类问题时,CNN的多个卷积层可以宽泛的认为是对原图像的特征提取,并且这样的特征提取具有平移不变性。我们把CNN当做特征提取的模板,把需要提取特征的图片塞给它,训练好我们需要的CNN,就可以获取到我们想要的特征向量。
网络的训练
知识补充:
有监督预训练与无监督预训练:
(1)无监督预训练(Unsupervised pre-training)
预训练阶段的样本不需要人工标注数据,所以就叫做无监督预训练。
(2)有监督预训练(Supervised pre-training)
所谓的有监督预训练也可以把它称之为迁移学习。比如你已经有一大堆标注好的人脸年龄分类的图片数据,训练了一个CNN,用于人脸的年龄识别。然后当你遇到新的项目任务时:人脸性别识别,那么这个时候你可以利用已经训练好的年龄识别CNN模型,去掉最后一层,然后其它的网络层参数就直接复制过来,继续进行训练,让它输出性别。这就是所谓的迁移学习,说的简单一点就是把一个任务训练好的参数,拿到另外一个任务,作为神经网络的初始参数值,这样相比于你直接采用随机初始化的方法,精度可以有很大的提高。
对于目标检测问题: 图片分类标注好的训练数据非常多,但是物体检测的标注数据却很少,如何用少量的标注数据,训练高质量的模型,这就是文献最大的特点,这篇论文采用了迁移学习的思想: 先用了ILSVRC2012这个训练数据库(这是一个图片分类训练数据库),先进行网络图片分类训练。这个数据库有大量的标注数据,共包含了1000种类别物体,因此预训练阶段CNN模型的输出是1000个神经元(当然也直接可以采用Alexnet训练好的模型参数)。
重叠度(IOU):
物体检测需要定位出物体的bounding box,就像下面的图片一样,我们不仅要定位出车辆的bounding box 我们还要识别出bounding box 里面的物体就是车辆。



CNN特征如何可视化?
文中采用了巧妙的方式将AlexNet CNN网络中Pool5层特征进行了可视化。该层的size是6×6×256,即有256种表示不同的特征,这相当于原始227×227图片中有256种195×195的感受视野【相当于对227×227的输入图像,卷积核大小为195×195,padding=4,step=8,输出大小(227-195+2×4)/8+1=6×6】;
文中将这些特征视为”物体检测器”,输入10million的Region Proposal集合,计算每种6×6特征即“物体检测器”的激活量,之后进行非极大值抑制【下面解释】,最后展示出每种6×6特征即“物体检测器”前几个得分最高的Region Proposal,从而给出了这种6×6的特征图表示了什么纹理、结构,很有意思。
非极大值抑制(NMS):
RCNN会从一张图片中找出n个可能是物体的矩形框,然后为每个矩形框为做类别分类概率:

就像上面的图片一样,定位一个车辆,最后算法就找出了一堆的方框,我们需要判别哪些矩形框是没用的。非极大值抑制的方法是:先假设有6个矩形框,根据分类器的类别分类概率做排序,假设从小到大属于车辆的概率 分别为A、B、C、D、E、F。
(1)从最大概率矩形框F开始,分别判断A~E与F的重叠度IOU是否大于某个设定的阈值;
(2)假设B、D与F的重叠度超过阈值,那么就扔掉B、D;并标记第一个矩形框F,是我们保留下来的。
(3)从剩下的矩形框A、C、E中,选择概率最大的E,然后判断E与A、C的重叠度,重叠度大于一定的阈值,那么就扔掉;并标记E是我们保留下来的第二个矩形框。
就这样一直重复,找到所有被保留下来的矩形框。
非极大值抑制(NMS)顾名思义就是抑制不是极大值的元素,搜索局部的极大值。这个局部代表的是一个邻域,邻域有两个参数可变,一是邻域的维数,二是邻域的大小。这里不讨论通用的NMS算法,而是用于在目标检测中用于提取分数最高的窗口的。例如在行人检测中,滑动窗口经提取特征,经分类器分类识别后,每个窗口都会得到一个分数。但是滑动窗口会导致很多窗口与其他窗口存在包含或者大部分交叉的情况。这时就需要用到NMS来选取那些邻域里分数最高(是行人的概率最大),并且抑制那些分数低的窗口。
在测试过程完成到第4步之后,获得2000×20维矩阵表示每个建议框是某个物体类别的得分情况,此时会遇到下图所示情况,同一个车辆目标会被多个建议框包围,这时需要非极大值抑制操作去除得分较低的候选框以减少重叠框。
具体怎么做呢?
① 对2000×20维矩阵中每列按从大到小进行排序;
② 从每列最大的得分建议框开始,分别与该列后面的得分建议框进行IoU计算,若IoU>阈值,则剔除得分较小的建议框,否则认为图像中存在多个同一类物体;
③ 从每列次大的得分建议框开始,重复步骤②;
④ 重复步骤③直到遍历完该列所有建议框;
⑤ 遍历完2000×20维矩阵所有列,即所有物体种类都做一遍非极大值抑制;
⑥ 最后剔除各个类别中剩余建议框得分少于该类别阈值的建议框。【文中没有讲,博主觉得有必要做】
VOC物体检测任务:
相当于一个竞赛,里面包含了20个物体类别:PASCAL VOC2011 Example Images 还有一个背景,总共就相当于21个类别,因此一会设计fine-tuning CNN的时候,我们softmax分类输出层为21个神经元。
CNN的训练分为以下几个过程:
1)有监督的预训练
一般的CNN模型层数多,模型的容量大,在标定数据少的情况下,这样的数据量是不够从新训练一个CNN模型的。故我们采用已训练好的AlexNet/VGG16模型的卷积层参数,使用这样已训练好的网络参数,可以较好的提取图片的特征。这样的操作有一个专业的名词-迁移学习(这里不做讨论)。

2) fine-tuning
关于fine-tuning的训练细节
原本ImageNet的输出类别有1000个,这里把1000个替换为21个(N=20,1为背景).
使用的SGD,每个mini-batch取128.
样本 | 数量 | 描述 |
---|---|---|
正样本 | 32 | 候选区域与ground-truth(图片物体标注区域)的IoU>0.5 |
负样本 | 96 | 候选区域与ground-truth(图片物体标注区域)的IoU<0.5 |
这里取IoU的阈值为0.5是因为CNN模型容量大,需要的数据多,故放宽限制,获取到更多的数据,防止模型过拟合。
需要注意的是,我们在训练CNN的时候会在网络的后面加上一个分类层,在训练完毕后,我们会移除最后的分类层,直接提取到前面的FC层,AlexNet的FC层为4096维。
对于一张图片,使用训练好的CNN基础上,将所有的图片的所有侯选区域塞到CNN里面,把得到的pool5 feature存到硬盘里面(这里一存,后面训练一取,非常耗费时间)

算法设计:
a、网络结构设计阶段
网络架构两个可选方案:第一选择经典的Alexnet;第二选择VGG16。经过测试Alexnet精度为58.5%,VGG16精度为66%。VGG这个模型的特点是选择比较小的卷积核、选择较小的跨步,这个网络的精度高,不过计算量是Alexnet的7倍。后面为了简单起见,我们就直接选用Alexnet,并进行讲解;Alexnet特征提取部分包含了5个卷积层、2个全连接层,在Alexnet中p5层神经元个数为9216、 f6、f7的神经元个数都是4096,通过这个网络训练完毕后,最后提取特征每个输入候选框图片都能得到一个4096维的特征向量。
b、网络有监督预训练阶段 (图片数据库:ImageNet ILSVC )
参数初始化部分:物体检测的一个难点在于,物体标签训练数据少,如果要直接采用随机初始化CNN参数的方法,那么目前的训练数据量是远远不够的。这种情况下,最好的是采用某些方法,把参数初始化了,然后在进行有监督的参数微调,这里文献采用的是有监督的预训练。所以paper在设计网络结构的时候,是直接用Alexnet的网络,然后连参数也是直接采用它的参数,作为初始的参数值,然后再fine-tuning训练。网络优化求解时采用随机梯度下降法,学习率大小为0.001;

C、fine-tuning阶段 (图片数据库: PASCAL VOC)
我们接着采用 selective search 搜索出来的候选框 (PASCAL VOC 数据库中的图片) 继续对上面预训练的CNN模型进行fine-tuning训练。假设要检测的物体类别有N类,那么我们就需要把上面预训练阶段的CNN模型的最后一层给替换掉,替换成N+1个输出的神经元(加1,表示还有一个背景) (20 + 1bg = 21),然后这一层直接采用参数随机初始化的方法,其它网络层的参数不变;接着就可以开始继续SGD训练了。开始的时候,SGD学习率选择0.001,在每次训练的时候,我们batch size大小选择128,其中32个事正样本、96个事负样本。

在候选区域的特征向量上训练分类器:
前面的CNN在侯选区域上提取出了特征向量,例如2000个侯选区域,那么提取出来的就是2000*4096这样的特征向量(AlexNet的第一个FC层维度为4096,故pool5的输出为4096)。用这些特征向量训练同时训练N个二分类的SVM,SVM的权重矩阵为4096xN(N为分类种类)。
这里你可能会问什么要使用SVM?而不是CNN过FC层直接softmax出来得了?
这是因为我们在训练CNN的时候选的数据比较宽泛(选择样本不够准确),直接使用softmax输出的效果不是很好,而这里在特征向量的基础上,再训练一组SVM效果会比较棒。但是需要注意的是,在训练SVM的时候,我们使用的样本是有变换的。
训练SVM时使用的样本
样本 | 描述 |
---|---|
正样本 | 候选区域与ground-truth(图片物体标注区域)的IoU>0.7 |
负样本 | 候选区域与ground-truth(图片物体标注区域)的IoU<0.3 |
这个0.7的阈值是做实验得出来的经验值。

在经过SVM分类后,会输出一堆的候选框得分(是一个2000x20的得分矩阵),这时候我们需要用的非极大值抑制得到想要的候选框了.大概步骤如下:
- 对矩阵按列从大到小排序
- 每列的最大值向下做非极大值抑制,遍历完所有列
- 依据阈值,得到候选区域的类型
注意到这里,我们得到的是一组预测好类别的候选区域了。
修正bbox,对bbox做回归微调
目标检测问题的衡量标准是重叠面积:许多看似准确的检测结果,往往因为候选框不够准确,重叠面积很小。故需要一个位置精修步骤。 回归器:对每一类目标,使用一个线性脊回归器进行精修。正则项λ=10000。 输入为深度网络pool5层的4096维特征,输出为xy方向的缩放和平移。 训练样本:判定为本类的候选框中和真值重叠面积大于0.6的候选框。
我们使用一个简单的bounding-box回归用于提高定位的表现。这个bbox回归应用在SVM分类器给每个候选区域打分后,bbox回归认为候选区域和ground-truth之间是线性关系(因为在最后从SVM内确定出来的区域比较接近ground-truth,这里近似认为可以线性关系)
-
样本 来源 正样本 与Ground Truth相交IoU最大的Region Proposal,并且IoU>0.6的Region Proposal
输入数据为某类型样本对N个:{(Pi,Gi)}i=1⋯N{(Pi,Gi)}i=1⋯N以及Pii=1⋯NPi=1⋯Ni所对应的AlexNet CNN网络Pool5层特征ϕ5(Pi)i=1⋯Nϕ5(Pi)i=1⋯N,输出回归后的建议框Bounding-box,训练的是dx(P)dx(P),dy(P)dy(P),dw(P)dw(P),dh(P)dh(P)四种变换操作的权重向量。具体见前面分析。
为什么微调时和训练SVM时所采用的正负样本阈值【0.5和0.3】不一致?
微调阶段是由于CNN对小样本容易过拟合,需要大量训练数据,故对IoU限制宽松:Ground Truth+与Ground Truth相交IoU>0.5的建议框为正样本,否则为负样本;
SVM这种机制是由于其适用于小样本训练,故对样本IoU限制严格:Ground Truth为正样本,与Ground Truth相交IoU<0.3的建议框为负样本。
结果
PASCAL VOC 2010测试集上实现了53.7%的mAP;
PASCAL VOC 2012测试集上实现了53.3%的mAP;
计算Region Proposals和features平均所花时间:13s/image on a GPU;53s/image on a CPU。
到这里,我们算是把R-CNN整个流程讲完了,后面还有一堆R-CNN的进化版~
R-CNN开山之作了不起,但是依然存在一些问题,后面进化版讲解的时候会详细探讨。
本文主要是整合一些RCNN相关资料,详见参考文献。在此感谢各位大神前辈的文章!
参考文献:
1.https://zhuanlan.zhihu.com/p/23006190
2.https://blog.csdn.net/u011974639/article/details/78053203#r-cnn
3.https://blog.csdn.net/wopawn/article/details/52133338
4.https://blog.csdn.net/u011534057/article/details/51218218