R-CNN系列:R-CNN,SPP-Net,Fast R-CNN,Faster R-CNN
学习的时候做的一些笔记,参考了b站up主霹雳吧啦Wz 对该系列的讲解视频, 链接:https://www.bilibili.com/video/BV1af4y1m7iL?spm_id_from=333.999.0.0 还参考了其他博客,下文有标注
论文地址:
R-CNN:https://arxiv.org/abs/1311.2524 SPP-Net:https://arxiv.org/abs/1406.4729 Fast R-CNN:https://arxiv.org/pdf/1504.08083.pdf Faster R-CNN:https://arxiv.org/abs/1506.01497
R-CNN
R-CNN:《Rich feature hierarchies for accurate object detection and semantic segmentation》
2014 发表于CVPR ,用深度学习进行目标检测的开山之作。
原理
R-CNN主要分为四个步骤:
1、候选区域生成: 一张图像生成1K~2K个候选区域 (采用Selective Search 方法) 2、特征提取: 对每个候选区域,使用卷积神经网络提取特征 (比如VGG) 3、类别判断: 将特征送入每一类的SVM 分类器,判别是否属于该类 4、位置精修: 使用回归器精细修正候选框位置
分开说一下:
区域候选(region proposal)
使用Selective Search(选择性搜索)方法在每张图像上生成1k~2k个候选区域。
Selective Search方法基本思路:
(1)使用一种过分割手段,将图像分割成小区域 (2)查看现有小区域,合并可能性最高的两个区域,重复直到整张图像合并成一个区域位置。
优先合并以下区域:
1、颜色(颜色直方图)相近的
2、纹理(梯度直方图)相近的
3、合并后总面积小的
4、合并后,总面积在其BBOX中所占比例大的。 在合并时须保证合并操作的尺度较为均匀,避免一个大区域陆续“吃掉”其它小区域,保证合并后形状规则。
(3)输出所有曾经存在过的区域,即所谓候选区域
特征提取(Feature extraction)
首先把所有的候选区域归一化为同一尺寸227*227。
(ps:搜索出来的候选框是大小不一的,归一化为同一尺寸,作者尝试了两种方法:各向异性缩放和各向同性缩放)
然后就输入到CNN里面去提取特征。网络架构有两个选择:Alexnet和VGG16
经过测试Alexnet精度为58.5%,VGG16精度为66%。
VGG这个模型的特点是选择比较小的卷积核、选择较小的跨步,这个网络的精度高,不过计算量是Alexnet的7倍。后面为了简单起见,我们就直接选用Alexnet进行讲解;Alexnet特征提取部分包含了5个卷积层、2个全连接层。通过这个网络训练完毕后,最后提取特征每个输入候选框图片都能得到一个4096维的特征向量。
类别判断
把得到的每一个特征向量都送入到SVM分类器里面,去判断类别。SVM分类器是二分类的,所以对于每一个类别,都要训练一个分类器。假设提取到了2000个候选框,就是2000x4096,然后有20个类别,所以就有20个分类器。计算过程如下图:(该图来源于b站up主:霹雳吧啦Wz)
这个SVM分类器不做过多介绍了,现在都用softmax分类。
补充说一下这个非极大值抑制:
非极大值抑制(NMS) 如图:预测一辆车,但是候选框有好多个。非极大值抑制,就是用来抑制那些冗余的框。 假设有有6个候选框,我们把这个6个框经过CNN提取特征后,输入SVM分类器里面会得到6个概率。 假设属于车辆的概率 从小到大分别为A、B、C、D、E、F。 (1)从最大概率矩形框F开始,分别判断A~E与F的重叠度IOU是否大于某个设定的阈值; (2)假设B、D与F的重叠度超过阈值,那么就扔掉B、D;并标记第一个矩形框F,是我们保留下来的。(超过了阈值就说明B、D这俩框跟F框的东西差不多,保留F就行了,这俩舍去) (3)从剩下的矩形框A、C、E中,选择概率最大的E,然后判断E与A、C的重叠度,重叠度大于一定的阈值,那么就扔掉;并标记E是我们保留下来的第二个矩形框。 就这样一直重复,找到所有被保留下来的矩形框。
边框回归(Bounding Box-Regression,BBR)
NMS处理后剩下的框,作者训练了一个回归器,用来修正预测框。
这个BBR过程,在网上看到一个解释,如下:
BBR分为两种,训练时的BBR和测试时候的BBR
训练时候的BBR:
在训练过程中,我们是有Ground Truth的(人工标注的),先把预测框与真实目标的框求一个IOU,大于0.6的才拿去修正。注意这里是训练过程,所以我们是有标注的真实框的,我们把预测的框,向着真实框修正,具体操作就是平移+缩放。我们把这里的操作记作回归参数。
测试时候的BBR:
测试的时候没有真实的框,但是我们经过多次训练,我们会给出一个预测的回归参数。就相当于,比如我训练的时候每次预测的框大概都要扩大1.5倍,那我实际测试的时候得到的预测框直接扩大1.5倍当作最终结果。
(ps:这块我也不是很清楚,可以看这几篇文章的解释
https://blog.csdn.net/v1_vivian/article/details/80292569
https://blog.csdn.net/qq_21033779/article/details/80536736)
总结
整个流程大概就是:
-
使用selective search在测试图片上提取1k~2k个region propasals 。 -
将每个region proposals归一化到227x227,然后再CNN中正向传播,将最后一层得到的特征提取出来。 -
然后对于每一个类别,使用为这一类训练的SVM分类器对提取的特征向量进行打分,得到测试图片中对于所有region proposals的对于这一类的分数,再使用贪心的非极大值抑制(NMS)去除相交的多余的框。 -
再使用训练好的回归器去修正候选框。
缺点:
1、检测速度慢。一张图片53s(多核cpu)
2、训练过程慢,很繁琐。
3、训练所需空间很大。
参考文章:
https://zhuanlan.zhihu.com/p/23006190
https://www.bilibili.com/video/BV1af4y1m7iL?p=1
https://blog.csdn.net/v1_vivian/article/details/78599229
https://my.oschina.net/u/876354/blog/1787921
SPP-Net
2015年发表在IEEE《Spatial Pyramid Pooling in Deep Convolutional Networks for Visual Recognition》
原理:
SPP-Net解决了R-CNN的两个痛点:
-
速度瓶颈:Selective Search对于每幅图片产生2K左右个region proposal,也就是说这幅图片的2K个region proposal都要送进CNN里面处理一遍得到对应的特征。但是如下图所示,有的框是有很大的重叠的,也就是说,同一部分的图像被重复提取特征了多次。所以计算量大,耗时久。 -
性能瓶颈:Selective Search对于每幅图片产生2K左右个region proposal是大小不一的。当然了,卷积神经网络是对输入图片大小没有要求的,卷积嘛,在图像上一直滑动计算而已,什么size的图像都可以进入卷积处理。但是卷积层后面还有全连接层,不同大小的图像经过相同的卷积层处理,再到全连接层,得到的特征向量是大小不一的。所以R-CNN里面是对所有的region proposal做了归一化处理,也就是放缩到相同大小。但是放缩一定会导致几何形变,而且由于速度上已经有瓶颈了,所以也不可能采用多尺度或者大量的数据增强去训练模型。所以这个形变也会影响到网络的性能。
SPP-Net就解决了这两个问题。
空间金字塔池化层
SPP-Net认为,既然只有全连接层需要固定的输入,那么我们在全连接层前加入一个网络层,让他对任意的输入产生固定的输出不就好了吗?一种常见的想法是对于最后一层卷积层的输出pooling一下,但是这个pooling窗口的尺寸及步伐设置为相对值,也就是输出尺寸的一个比例值,这样对于任意输入经过这层后都能得到一个固定的输出。
SPP-Net设计了一个空间金字塔池化层。如图:
黑色图片代表卷积之后的特征图,接着我们以不同大小的块来提取特征,分别是4x4,2x2,1x1,将这三张网格放到下面这张特征图上,就可以得到16+4+1=21种不同的块(Spatial bins),我们从这21个块中,每个块提取出一个特征,这样刚好就是我们要提取的21维特征向量。这种以不同的大小格子的组合方式来池化的过程就是空间金字塔池化(SPP)。比如,要进行空间金字塔最大池化,其实就是从这21个图片块中,分别计算每个块的最大值,从而得到一个输出单元,最终得到一个21维特征的输出。
使用这个,我们就可以实现:当网络输入的是一张任意大小的图片,我们可以一直进行卷积、池化,直到网络的倒数几层的时候,即将与全连接层连接的时候,使用空间金字塔池化层,使得任意大小的特征图都能够转换成固定大小的特征向量(多尺度特征提取出固定大小的特征向量)。
上面这个图可以看出SPPnet和RCNN的区别,首先是输入不需要放缩到指定大小。其次是增加了一个空间金字塔池化层。
这个方法解决了输入尺寸的问题,也就是解决了图片形变的问题。但是速度问题,没有解决。还是需要每一个候选框都进网络计算一变,这个怎么解决呢?
直接映射
SPP-Net让每幅图片只需要提取一次特征。
SPPnet的做法是首先通过选择性搜索,对待检测的图片进行搜索出2k个候选窗口。这一步和R-CNN一样。
然后把整张待检测的图片,输入CNN中,进行一次性特征提取,得到feature maps,然后在feature maps中通过映射关系找到各个候选框对应的区域,再对各个候选框采用金字塔空间池化,提取出固定长度的特征向量。
关键的操作就在这里,SPP-Net直接把整张图送进网络,得到feature maps,然后直接通过映射关系,再这个feature maps里面直接取候选框,然后用金字塔空间池化,提取出固定长度的特征向量。省去了每个候选框区域都进CNN计算的时间。
是怎么映射的呢?如图:
SPP-net解决了R-CNN重复提取候选区域特征的问题,同时允许各种尺寸图像作为输入,解决了图像畸变的问题,但R-CNN的其它问题,如训练步骤繁琐、磁盘空间开销大等依然有待解决。
参考文章:
https://blog.csdn.net/v1_vivian/article/details/73275259
https://zhuanlan.zhihu.com/p/58776814
https://blog.csdn.net/fengbingchun/article/details/87091740
Fast R-CNN
Fast R-CNN发表于2015年ICCV
同样使用VGG16作为网络backbone,比R-CNN训练时间快9倍,测试推理时间快213倍。比SPP-net快了10倍,在VOC2012上的mAP在66%左右。
原理:
Fast R-CNN的步骤:
1、候选区域生成: 一张图像生成1K~2K个候选区域 (采用Selective Search 方法) 2、将图像直接输入CNN得到整张图像的特征图(feature maps),将SS算法生成的候选框直接映射到feature maps上,得到每个候选框对应的特征矩阵(这里就是借鉴了SPP-Net的思想) 3、每个特征矩阵通过一个ROI pooling层缩放到7x7大小。(这个所谓的ROI pooling层其实就是借鉴了SSP-Net的思想金字塔池化层的思想)
4、将大小统一后的特征图通过一系列全连接层得到对候选框类别的预测和候选框回归参数的预测
ROI pooling层
解释一下这个,为啥叫ROI呢,其实是Region of Interest(感兴趣区域)英文的缩写。这个层就是把不同大小的特征图缩放成同一大小的特征图。使用的方法就是SSP-Net里面的思想,作者在论文里说了“RoI层只是SPP-nets中使用的空间金字塔池层的特例,ROI层相当于只有一个金字塔层。”。
他的做法就是将不同大小的特征图,划分成7x7块,也就是49块,对每一块进行下采样操作,也就会得到一个7x7的特征图。不论输入大小是多少,都给他分为7x7进行下采样,所以就不限制图像的输入尺寸了。他只进行7x7的划分,所以作者说“ROI层相当于只有一个金字塔层”
Multi-task Loss
Fast R-CNN统一了类别输出任务和候选框回归任务,将预测类别和预测候选框回归参数的任务都放到了网络里面处理。
分类采用softmax代替原来的SVM进行分类,共输出N(类别)+1(背景)类。
预测候选框这部分他根据对类别的预测,为每一个类别再预测一个候选框回归参数。具体设计可以看论文。
所以这里有俩loss
总结:
Fast RCNN将RCNN众多步骤整合在一起,不仅大大提高了检测速度,也提高了检测准确率。其中,对整张图像卷积而不是对每个region proposal卷积,ROI Pooling,分类和回归都放在网络一起训练的multi-task loss是算法的三个核心。 当然Fast RCNN的主要缺点在于region proposal的提取使用selective search,目标检测时间大多消耗在这上面(提region proposal 2~3s,而提特征分类只需0.32s),这也是后续Faster RCNN的改进方向之一。
Faster R-CNN
在Fast R-CNN提出的同年,2015年,Faster R-CNN发表在NIPS
原理:
其实R-CNN经过了SPP-Net和Fast R-CNN的改进后,剩下的问题很明显了,那就是使用Selective Search(选择性搜索)生成的候选区域:
1、这个生成的候选区域效果并不好,而候选区域对后面的预测影响很大,大量无效的候选区域会严重浪费算力
2、SS生成候选区域是在CPU上进行的,后面的训练在GPU上,跨结构交互也会造成损失
Faster R-CNN提出了RPN(Region Proposal Networks),使用神经网络来学习生成候选区域。
如图,Faster R-CNN流程如下
1、将图像输入网络,得到相应的特征图 2、使用RPN结构生成候选框,将候选框投影到特征图上,获得对应的特征矩阵 3、每个特征矩阵通过RIO pooling层缩放到7x7大小, 4、将大小统一后的特征图通过一系列全连接层得到预测结果
对比Fast R-CNN,Faster R-CNN把生成候选框和边界框回归预测的任务都交给了RPN结构实现,然后把RPN结果整合到了整个CNN中。
所以我们具体看下RPN是如何工作的:
首先RPN和ROI pooling共用前面的卷积神经网络,原文中使用的是ZF model中,其Conv Layers中最后的conv5层num_output=256,对应生成256张特征图,所以相当于feature map每个点都是256-dimensions。然后RPN结构首先做了一个3x3的卷积,维度不变还是256-d。
对每一个点做卷积的时候,都会生成k个anhcor。如图所示,特征图的每一个点,计算出它在原图对应的位置,然后画出k个anhcor。
anhcor怎么画,有三种尺度(面积):
12
8
2
128^2
1282、
25
6
2
256^2
2562、
51
2
2
512^2
5122
三种比例:1:1,1:2,2:1
那么组合起来就有9种anhcor,所以一般是画9个anhcor
对于这k个anhcor,RPN会得到2*k个预测值,每个anhcor会得到两个预测值,分别是预测其是前景和背景的概率
同时,还会得到4*k个coordinates,就是每个anhcor都会得到4个值,是预测的边界框回归参数。
对于一张1000x600x3的图像,大约有60x40x9(20k)个anchor,忽略跨越边界的anchor以后,剩下约6k个anchor。对于RPN生成的候选框之间存在大量重叠,基于候选框的cls得分,采用非极大值抑制,IoU设为0.7,这样每张图片只剩2k个候选框。
那么怎么训练呢?原论文中采用的方法是将RPN和预测目标的网络分开多次训练。但是后面经过改进后的代码,是可以直接采用RPN Loss+Fast R-CNN Loss联合训练的。
总结
三个放在一起对比:
|