目标检测三
参考:https://www.cnblogs.com/skyfsm/p/6806246.html
Fast R-CNN
原理
论文地址: Fast R-CNN
代码地址: 代码地址:rbgirshick/fast-rcnn
相对于R-CNN,Fast R-CNN主要有三点改进:
提出了RoIPooling,避免了对提取的region proposals进行缩放到224x224,然后经过pre-trained CNN进行检测的步骤,加速了整个网络的learning与inference过程,这个是巨大的改进,并且RoIPooling是可导的,因此使得整个网络可以实现end-to-end learning,这个可以认为是Fast R-CNN相对于R-CNN最大的改进之处。将R-CNN中三个模块(CNN, SVM, Regression)整合, 极大了减少了计算量和加快了速度
采用了Multi-task loss进行边框回归,这个在R-CNN中也有这方面的实验。
利用了截断的奇异值分解(Truncated SVD for faster detection)加速了网络。
网络结构
流程图
步骤
- 预训练一个分类CNN
- 修改CNN, 将最后一个flatten层以及后面的层删掉, 换成ROI Pooling层
- 将图像经过CNN, 得到特征图, 使用selective search选出2k个候选区域
- 在ROI Pooling层后跟几个FC, 最后输出2个分支:
- 第一个分支是softmax层, 输出k+1个分类
- 第二个分支是regression, 预测输出k个类别的box参数
Multi-task Loss
R-CNN中在获取到最终的CNN特征后先采用SVM进行类别判断,再进行bounding-box的回归得到位置信息。整个过程是个串行的流程。这极大地影响了网络的检测速度。Fast R-CNN中则将Classification和regression的任务合二为一,变成一个multi-task的模型,实现了特征的共享与速度的进一步提升。
使用Smooth L1的优点:
- 0点可导
- loss减小时,梯度随之下降,有助于收敛
ROI Pooling
Fast R-CNN中借鉴了SPP-Net的金字塔池化思想,在此基础上进行改进。 将sppnet中多尺度的池化简化为单尺度,只输出固定尺寸为(w, h)的feature map。
ROI Pooling时,将输入的h w大小的feature map分割成H W大小的子窗口(每个子窗口的大小约为h/H,w/W,其中H、W为超参数,如设定为7 x 7),对每个子窗口进行max-pooling操作,得到固定输出大小的feature map。而后进行后续的全连接层操作。
ROI Pooling的实现可以参考github上Caffe版本的代码:roi_pooling_layer.cpp
Faster R-CNN
代码地址:https://github.com/rbgirshick/py-faster-rcnn
由于Fast R-CNN仍然采用ss产生候选框,非常耗时,Faster R-CNN提出使用神经网络来产生候选框, Region Proposal Network(RPN) 。
网络结构
1)卷积层(conv layers),用于提取图片的特征,输入为整张图片,输出为提取出的特征称为feature maps
2)RPN网络(Region Proposal Network),用于推荐候选区域,这个网络是用来代替之前的search selective的。输入为图片为featrue maps,输出为多个候选区域。
3)RoI pooling,和Fast R-CNN一样,将不同大小的输入转换为固定长度的输出,输入输出和Fast R-CNN中RoI pooling一样。
4)分类和回归,这一层的输出是最终目的,输出候选区域所属的类,和候选区域在图像中的精确位置。
RPN网络
首先作者自己设想原图上或者说featuremap上每个位置可能会产生k种可能的区域,下图所示,每个位置三种面积可能,三种长宽表示样式。三种面积分别是128×128,256×256,512×512,每种面积又分成3种长宽比,分别是2:1,1:2,1:1 ,k=9。
一个锚点框被标记为正样本的条件:
- 这个框与ground-trueth box有着最大重叠率
- 这个框与ground-trueth box重叠率大于0.7
如果一个锚点框与所有ground-trueth的重合率都小于0.3,那么被标记为负样本
训练时一个batch中,正负样本的比例控制在50%:50%
RPN网络直接放在最后一个卷积层的后面,经过训练直接得到候选区域。
先将一幅图片经过CNN网络得到第五个卷积层,然后将第五个卷积层用3*3卷积核卷积得到一个256通道的特征图,之后再分为两路,一路用1*1卷积降维到原尺寸下2*k个通道(这2*k个分别对应是/否为对的候选区域,总共有k个框,所以是2k个,由于RPN是提取候选框,并不需要区分类别,所以两个分数是指物体的分数和背景的分数 ),另一路用1\1的卷积降维到原尺寸下4*k个通道(这个就是左上角坐标,右下角坐标,k种)
注意:这里尺寸没有变,因为每个位置都要输出这么个得分情况,我们最后确定比较好的中心位置还有它的尺寸。
由于对每个向量都进行同样的全连接操作,等同于对整个特征图做1X1的卷积.训练程序会在合适的anchors中随机选取128个positive anchors+128个negative anchors进行训练
训练
要将RPN网络和Fast R-CNN网络组合起来,实现权值共享。
Faster R-CNN的训练过程如下所示:
- 先在imagenet上预训练一个CNN模型,得到一个初始的RPN网络
- 另外训练一个imagenet模型CNN2,然后把在步骤1得到的Region proposals用来训练Fast R-CNN模型。
- 有了一个比较好的Fast R-CNN模型也就是步骤2的模型,我们把这个CNN部分固定再去矫正RPN网络,会产生新的proposal ,此时CNN部分就用CNN2(把CNN1直接丢掉了!)然后去调参RPN后面那一部分,调好了这时的RPN模型基本可以了。
完事候选区域又变了,回去在调FastR-CNN模型,此时CNN部分不动了,这两个网络已经共享了!我们去调后面的全连接。
训练中有四种损失:
区域生成网络的前后景分类损失(Object or not object)
区域生成网络的区域位置损失(Bounding box proposal)
Fast RCNN物体分类损失(Normal object classification)
Fast RCNN区域位置损失(Improve previous Bounding box proposal)
整体结构
FPN
卷积神经网络中越靠近分类器的层,提取的语义信息越强,但是分辨率越小。
为了兼顾分辨率和语义信息,FPN将高层提取到的语义信息自上而下进行融合。
借用Resnet的思想,使用跨层连接,上层进行2倍上采样。
RFCN
代码:https://github.com/daijifeng001/r-fcn
参考:https://blog.csdn.net/baidu_32173921/article/details/71741970
出发点:图片分类的平移不变性与物体检测之间的平移变换性之间的矛盾
- 一方面,图像级别的分类任务侧重于平移不变性(在一幅图片中平移一个物体而不改变它的判别结果),因此深度全卷积网络结构很适合处理这类图片分类的问题。
- 另一方面,物体检测任务需要定义物体的具体位置,因此需要平移变换特性。为了解决这矛盾,在检测方法中插入了ROI pooling layer到卷积层。然而,这个设计牺牲了训练和测试的效率,因为它引入了大量的region-wise layers。
RCNN:由于直接在图片上生成proposal,所以没有共享的卷积层
网络结构
- Backbone architecture: ResNet 101——去掉原始ResNet101的最后一层全连接层,保留前100层,再接一个1*1*1024的全卷积层(100层输出是2048,为了降维,再引入了一个1*1的卷积层)
- k^2(C+1)的conv: ResNet101的输出是W*H*1024,用K\^2(C+1)个1024*1*1的卷积核去卷积即可得到K^2(C+1)个大小为W*H的position sensitive的score map。这步的卷积操作就是在做prediction。k = 3,表示把一个ROI划分成3*3,对应的9个位置分别是:上左(左上角),上中,上右,中左,中中,中右,下左,下中,下右(右下角)。
- k^2(C+1)个feature map的物理意义: 共有k*k = 9个颜色,每个颜色的立体块(W*H*(C+1))表示的是不同位置存在目标的概率值(第一块黄色表示的是左上角位置,最后一块淡蓝色表示的是右下角位置)。共有k^2*(C+1)个feature map。每个feature map,z(i,j,c)是第i+k(j-1)个立体块上的第c个map(1<= i,j <=3)。(i,j)决定了9种位置的某一种位置,假设为左上角位置(i=j=1),c决定了哪一类,假设为person类。在z(i,j,c)这个feature map上的某一个像素的位置是(x,y),像素值是value,则value表示的是原图对应的(x,y)这个位置上可能是人(c=‘person’)且是人的左上部位(i=j=1)的概率值。
原始图片经过conv卷积得到feature map1,其中一个subnetwork如同FastRCNN:使用RPN在featuremap1上滑动产生region proposal备用;另一个subnetwork则继续卷积,得到k^2(k=3)深度的featuremap2,根据RPN产生的RoI(region proposal)在这些featuremap2上进行池化和打分分类操作,得到最终的检测结果。
ROI pooling: 就是faster RCNN中的ROI pooling,也就是一层的SPP结构。主要用来将不同大小的ROI对应的feature map映射成同样维度的特征,思路是不论对多大的ROI,规定在上面画一个n*n 个bin的网格,每个网格里的所有像素值做一个pooling(平均),这样不论图像多大,pooling后的ROI特征维度都是n*n。注意一点ROI pooling是每个feature map单独做,不是多个channel一起的。
ROI pooling的输入和输出:ROI pooling操作的输入(对于C+1个类)是k^2*(C+1)*W’ *H’(W’和H’是ROI的宽度和高度)的score map上某ROI对应的那个立体块,且该立体块组成一个新的k^2(C+1)\W’ *H’的立体块:每个颜色的立体块(C+1)都只抠出对应位置的一个bin,把这k*k个bin组成新的立体块,大小为(C+1)*W’*H’。例如,下图中的第一块黄色只取左上角的bin,最后一块淡蓝色只取右下角的bin。所有的bin重新组合后就变成了类似右图的那个薄的立体块(图中的这个是池化后的输出,即每个面上的每个bin上已经是一个像素。池化前这个bin对应的是一个区域,是多个像素)。ROI pooling的输出为为一个(C+1)*k*k的立体块,如下图中的右图
识别结果
- 识别成功的情况:
下面这张figure3描述了一次成功的位置敏感性识别,figure3中间的九张featuremap实际上就是位置敏感结构图左侧的九层featuremap,每一层分别对应物体的一个感兴趣部位,就比如[2,2]这张图上中位置代表人体的头部。因而所有位置的响应经过一次池化都保存在figure3右侧33(C+1)的对应位置了(原来是上中现在还是上中,原来是左下现在还是左下),如此位置敏感性得到保留。
当poolingmap九个方框得分都超过一定阈值,我们可以相信这个region proposal中是存在物体的。
识别失败的情况:
优点
- 比Faster R-CNN更快
- 思路更简单
- 考虑了位置敏感区域信息,更适合目标检测
总结
RCNN
1. 在图像中确定约1000-2000个候选框 (使用选择性搜索)2. 每个候选框内图像块缩放至相同大小,并输入到CNN内进行特征提取 3. 对候选框中提取出的特征,使用分类器判别是否属于一个特定类 4. 对于属于某一特征的候选框,用回归器进一步调整其位置
Fast RCNN
- 在图像中确定约1000-2000个候选框 (使用选择性搜索)
- 对整张图片输进CNN,得到feature map
- 找到每个候选框在feature map上的映射patch,将此patch作为每个候选框的卷积特征输入到SPP layer和之后的层
- 对候选框中提取出的特征,使用分类器判别是否属于一个特定类
- 对于属于某一特征的候选框,用回归器进一步调整其位置
Faster RCNN
- 对整张图片输进CNN,得到feature map
- 卷积特征输入到RPN,得到候选框的特征信息
- 对候选框中提取出的特征,使用分类器判别是否属于一个特定类
- 对于属于某一特征的候选框,用回归器进一步调整其位置