图像理解之物体检测object detection,模型rcnn/fastrcnn/fasterrcnn原理及概念
A,https://www.cnblogs.com/zhengzhe/p/7783270.html
RCNN选择性搜索(Selective Search)
基于:
1)图片大小
2)颜色
3)纹理
4)附件
算法一:分组分类算法
输入:(图层颜色)图片
输出:对象位置假设集L
Obtain initial regions R = {r1,··· ,rn} using [13]
Initialise similarity set S = 空集
foreach Neighbouring region pair (ri,rj) do //遍历所有临近的像素对
Calculate similarity s(ri,rj) //计算所有像素对之间的相似度
S= S∪s(ri,rj) //把相应的相似度保存在集合S中
while S≠空集 do
Get highest similarity s(ri,rj) = max(S) //从集合S中取出相似度最高的像素对
Merge corresponding regions rt = ri ∪rj //把两个像素进行合并
Remove similarities regarding ri : S = S \ s(ri,r∗) //从集合S中除去和ri有关的相似度
Remove similarities regarding rj : S = S \ s(r∗,rj) //从集合S中除去和rj有关的相似度
Calculate similarity set St between rt and its neighbours //计算rt和临近像素点的相似度
S = S∪St //将相似度存入集合S中
R = R∪rt //将rt存入集合R中
Extract object location boxes L from all regions in R
优先合并以下四种区域:
- 颜色(颜色直方图)相近的
- 纹理(梯度直方图)相近的
- 合并后总面积小的
- 合并后,总面积在其BBOX中所占比例大的
第三条,保证合并操作的尺度较为均匀,避免一个大区域陆续“吃掉”其他小区域。(Get highest similarity s(ri,rj) = max(S)通过此处实现)
例:设有区域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。
第四条,保证合并后形状规则。
例:左图适于合并,右图不适于合并。
上述四条规则只涉及区域的颜色直方图、纹理直方图、面积和位置。合并后的区域特征可以直接由子区域特征计算而来,速度较快。
B,https://www.cnblogs.com/dudumiaomiao/p/6560841.html
R-CNN --> FAST-RCNN --> FASTER-RCNN
R-CNN:
(1)输入测试图像;
(2)利用selective search 算法在图像中从上到下提取2000个左右的Region Proposal;
(3)将每个Region Proposal缩放(warp)成227*227的大小并输入到CNN,将CNN的fc7层的输出作为特征;
(4)将每个Region Proposal提取的CNN特征输入到SVM进行分类;
(5)对于SVM分好类的Region Proposal做边框回归,用Bounding box回归值校正原来的建议窗口,生成预测窗口坐标.
缺陷:
(1) 训练分为多个阶段,步骤繁琐:微调网络+训练SVM+训练边框回归器;
(2) 训练耗时,占用磁盘空间大;5000张图像产生几百G的特征文件;
(3) 速度慢:使用GPU,VGG16模型处理一张图像需要47s;
(4) 测试速度慢:每个候选区域需要运行整个前向CNN计算;
(5) SVM和回归是事后操作,在SVM和回归过程中CNN特征没有被学习更新.
FAST-RCNN:
(1)输入测试图像;
(2)利用selective search 算法在图像中从上到下提取2000个左右的建议窗口(Region Proposal);
(3)将整张图片输入CNN,进行特征提取;
(4)把建议窗口映射到CNN的最后一层卷积feature map上;
(5)通过RoI pooling层使每个建议窗口生成固定尺寸的feature map;
(6)利用Softmax Loss(探测分类概率) 和Smooth L1 Loss(探测边框回归)对分类概率和边框回归(Bounding box regression)联合训练.
相比R-CNN,主要两处不同:
(1)最后一层卷积层后加了一个ROI pooling layer;
(2)损失函数使用了多任务损失函数(multi-task loss),将边框回归直接加入到CNN网络中训练
改进:
(1) 测试时速度慢:R-CNN把一张图像分解成大量的建议框,每个建议框拉伸形成的图像都会单独通过CNN提取特征.实际上这些建议框之间大量重叠,特征值之间完全可以共享,造成了运算能力的浪费.
FAST-RCNN将整张图像归一化后直接送入CNN,在最后的卷积层输出的feature map上,加入建议框信息,使得在此之前的CNN运算得以共享.
(2) 训练时速度慢:R-CNN在训练时,是在采用SVM分类之前,把通过CNN提取的特征存储在硬盘上.这种方法造成了训练性能低下,因为在硬盘上大量的读写数据会造成训练速度缓慢.
FAST-RCNN在训练时,只需要将一张图像送入网络,每张图像一次性地提取CNN特征和建议区域,训练数据在GPU内存里直接进Loss层,这样候选区域的前几层特征不需要再重复计算且不再需要把大量数据存储在硬盘上.
(3) 训练所需空间大:R-CNN中独立的SVM分类器和回归器需要大量特征作为训练样本,需要大量的硬盘空间.FAST-RCNN把类别判断和位置回归统一用深度网络实现,不再需要额外存储.
FASTER -RCNN:
(1)输入测试图像;
(2)将整张图片输入CNN,进行特征提取;
(3)用RPN生成建议窗口(proposals),每张图片生成300个建议窗口;
(4)把建议窗口映射到CNN的最后一层卷积feature map上;
(5)通过RoI pooling层使每个RoI生成固定尺寸的feature map;
(6)利用Softmax Loss(探测分类概率) 和Smooth L1 Loss(探测边框回归)对分类概率和边框回归(Bounding box regression)联合训练.
相比FASTER-RCNN,主要两处不同:
(1)使用RPN(Region Proposal Network)代替原来的Selective Search方法产生建议窗口;
(2)产生建议窗口的CNN和目标检测的CNN共享
改进:
(1) 如何高效快速产生建议框?
FASTER-RCNN创造性地采用卷积网络自行产生建议框,并且和目标检测网络共享卷积网络,使得建议框数目从原有的约2000个减少为300个,且建议框的质量也有本质的提高.
概念解释:
1、常用的Region Proposal有:
-Selective Search
-Edge Boxes
2、softmax-loss
softmax-loss 层和 softmax 层计算大致是相同的. softmax 是一个分类器,计算的是类别的概率(Likelihood),是
Logistic Regression 的一种推广. Logistic
Regression 只能用于二分类,
而 softmax 可以用于多分类.
softmax 与 softmax-loss 的区别:
softmax 计算公式:
关于两者的区别更加具体的介绍,可参考: softmax vs. softmax-loss
用户可能最终目的就是得到各个类别的概率似然值,这个时候就只需要一个 Softmax 层,而不一定要进行
softmax-Loss 操作;或者是用户有通过其他什么方式已经得到了某种概率似然值,然后要做最大似然估计,此时则只需要后面的
softmax-Loss 而不需要前面的 Softmax操作.因此提供两个不同的 Layer 结构比只提供一个合在一起的
Softmax-Loss Layer 要灵活许多.不管是 softmax layer 还是 softmax-loss
layer,都是没有参数的,只是层类型不同而已
softmax-loss layer:输出 loss 值
layer {
name: "loss"
type: "SoftmaxWithLoss"
bottom: "ip1"
bottom: "label"
top: "loss"
}
softmax layer: 输出似然值
layers {
bottom: "cls3_fc"
top: "prob"
name: "prob"
type: “Softmax"
}
3、Selective Search
这个策略其实是借助了层次聚类的思想(可以搜索了解一下"层次聚类算法"),将层次聚类的思想应用到区域的合并上面;
总体思路:
l 假设现在图像上有n个预分割的区域(Efficient Graph-Based Image Segmentation),表示为R={R1, R2, ..., Rn},
l 计算每个region与它相邻region(注意是相邻的区域)的相似度,这样会得到一个n*n的相似度矩阵(同一个区域之间和一个区域与不相邻区域之间的相似度可设为NaN),从矩阵中找出最大相似度值对应的两个区域,将这两个区域合二为一,这时候图像上还剩下n-1个区域;
l 重复上面的过程(只需要计算新的区域与它相邻区域的新相似度,其他的不用重复计算),重复一次,区域的总数目就少1,知道最后所有的区域都合并称为了同一个区域(即此过程进行了n-1次,区域总数目最后变成了1).算法的流程图如下图所示:
4、SPP-NET
SSP-Net:Spatial Pyramid Pooling in Deep Convolutional Networks for Visual Recognition
先看一下R-CNN为什么检测速度这么慢,一张图都需要47s!仔细看下R-CNN框架发现,对图像提完Region Proposal(2000个左右)之后将每个Proposal当成一张图像进行后续处理(CNN提特征+SVM分类),实际上对一张图像进行了2000次提特征和分类的过程!这2000个Region Proposal不都是图像的一部分吗,那么我们完全可以对图像提一次卷积层特征,然后只需要将Region Proposal在原图的位置映射到卷积层特征图上,这样对于一张图像我们只需要提一次卷积层特征,然后将每个Region Proposal的卷积层特征输入到全连接层做后续操作.(对于CNN来说,大部分运算都耗在卷积操作上,这样做可以节省大量时间).
现在的问题是每个Region Proposal的尺度不一样,直接这样输入全连接层肯定是不行的,因为全连接层输入必须是固定的长度.SPP-NET恰好可以解决这个问题.
由于传统的CNN限制了输入必须固定大小(比如AlexNet是224x224),所以在实际使用中往往需要对原图片进行crop或者warp的操作:
- crop:截取原图片的一个固定大小的patch
- warp:将原图片的ROI缩放到一个固定大小的patch
无论是crop还是warp,都无法保证在不失真的情况下将图片传入到CNN当中:
- crop:物体可能会产生截断,尤其是长宽比大的图片.
- warp:物体被拉伸,失去“原形”,尤其是长宽比大的图片
SPP为的就是解决上述的问题,做到的效果为:不管输入的图片是什么尺度,都能够正确的传入网络.
具体思路为:CNN的卷积层是可以处理任意尺度的输入的,只是在全连接层处有限制尺度——换句话说,如果找到一个方法,在全连接层之前将其输入限制到等长,那么就解决了这个问题.
具体方案如下图所示:
如果原图输入是224x224,对于conv5出来后的输出,是13x13x256的,可以理解成有256个这样的filter,每个filter对应一张13x13的activation map.如果像上图那样将activation map pooling成4x4 2x2 1x1三张子图,做max pooling后,出来的特征就是固定长度的(16+4+1)x256那么多的维度了.如果原图的输入不是224x224,出来的特征依然是(16+4+1)x256;直觉地说,可以理解成将原来固定大小为(3x3)窗口的pool5改成了自适应窗口大小,窗口的大小和activation map成比例,保证了经过pooling后出来的feature的长度是一致的.
5、Bounding box regression
R-CNN中的bounding box回归
下面先介绍R-CNN和Fast R-CNN中所用到的边框回归方法.
(1)
什么是IOU
(2)
为什么要做Bounding-box
regression?
如上图所示,绿色的框为飞机的Ground Truth,红色的框是提取的Region
Proposal.那么即便红色的框被分类器识别为飞机,但是由于红色的框定位不准(IoU<0.5),那么这张图相当于没有正确的检测出飞机.如果我们能对红色的框进行微调,使得经过微调后的窗口跟Ground
Truth更接近,这样岂不是定位会更准确.确实,Bounding-box regression 就是用来微调这个窗口的.
(3)
回归/微调的对象是什么?
(4) Bounding-box regression(边框回归)
那么经过何种变换才能从图11中的窗口P变为窗口呢?比较简单的思路就是:
注意:只有当Proposal和Ground
Truth比较接近时(线性问题),我们才能将其作为训练样本训练我们的线性回归模型,否则会导致训练的回归模型不work(当Proposal跟GT离得较远,就是复杂的非线性问题了,此时用线性回归建模显然不合理).这个也是G-CNN:
an Iterative Grid Based Object
Detector多次迭代实现目标准确定位的关键.
线性回归就是给定输入的特征向量X,学习一组参数W,使得经过线性回归后的值跟真实值Y(Ground Truth)非常接近.即.那么Bounding-box中我们的输入以及输出分别是什么呢?
6、Region Proposal Network
RPN的实现方式:在conv5-3的卷积feature map上用一个n*n的滑窗(论文中作者选用了n=3,即3*3的滑窗)生成一个长度为256(对应于ZF网络)或512(对应于VGG网络)维长度的全连接特征.然后在这个256维或512维的特征后产生两个分支的全连接层:
(1)reg-layer,用于预测proposal的中心锚点对应的proposal的坐标x,y和宽高w,h;
(2)cls-layer,用于判定该proposal是前景还是背景.sliding window的处理方式保证reg-layer和cls-layer关联了conv5-3的全部特征空间.事实上,作者用全连接层实现方式介绍RPN层实现容易帮助我们理解这一过程,但在实现时作者选用了卷积层实现全连接层的功能.
(3)个人理解:全连接层本来就是特殊的卷积层,如果产生256或512维的fc特征,事实上可以用Num_out=256或512, kernel_size=3*3, stride=1的卷积层实现conv5-3到第一个全连接特征的映射.然后再用两个Num_out分别为2*9=18和4*9=36,kernel_size=1*1,stride=1的卷积层实现上一层特征到两个分支cls层和reg层的特征映射.
(4)注意:这里2*9中的2指cls层的分类结果包括前后背景两类,4*9的4表示一个Proposal的中心点坐标x,y和宽高w,h四个参数.采用卷积的方式实现全连接处理并不会减少参数的数量,但是使得输入图像的尺寸可以更加灵活.在RPN网络中,我们需要重点理解其中的anchors概念,Loss fucntions计算方式和RPN层训练数据生成的具体细节.
Anchors:字面上可以理解为锚点,位于之前提到的n*n的sliding window的中心处.对于一个sliding window,我们可以同时预测多个proposal,假定有k个.k个proposal即k个reference boxes,每一个reference box又可以用一个scale,一个aspect_ratio和sliding window中的锚点唯一确定.所以,我们在后面说一个anchor,你就理解成一个anchor box 或一个reference box.作者在论文中定义k=9,即3种scales和3种aspect_ratio确定出当前sliding window位置处对应的9个reference boxes, 4*k个reg-layer的输出和2*k个cls-layer的score输出.对于一幅W*H的feature map,对应W*H*k个锚点.所有的锚点都具有尺度不变性.
Loss functions:
在计算Loss值之前,作者设置了anchors的标定方法.正样本标定规则:
1) 如果Anchor对应的reference box与ground truth的IoU值最大,标记为正样本;
2) 如果Anchor对应的reference box与ground truth的IoU>0.7,标记为正样本.事实上,采用第2个规则基本上可以找到足够的正样本,但是对于一些极端情况,例如所有的Anchor对应的reference box与groud truth的IoU不大于0.7,可以采用第一种规则生成.
3) 负样本标定规则:如果Anchor对应的reference box与ground truth的IoU<0.3,标记为负样本.
4) 剩下的既不是正样本也不是负样本,不用于最终训练.
5) 训练RPN的Loss是有classification loss (即softmax loss)和regression loss (即L1 loss)按一定比重组成的.
计算softmax loss需要的是anchors对应的groundtruth标定结果和预测结果,计算regression loss需要三组信息:
i. 预测框,即RPN网络预测出的proposal的中心位置坐标x,y和宽高w,h;
ii. 锚点reference box:
之前的9个锚点对应9个不同scale和aspect_ratio的reference boxes,每一个reference boxes都有一个中心点位置坐标x_a,y_a和宽高w_a,h_a;
iii. ground truth:标定的框也对应一个中心点位置坐标x*,y*和宽高w*,h*.因此计算regression loss和总Loss方式如下:
RPN训练设置:
(1)在训练RPN时,一个Mini-batch是由一幅图像中任意选取的256个proposal组成的,其中正负样本的比例为1:1.
(2)如果正样本不足128,则多用一些负样本以满足有256个Proposal可以用于训练,反之亦然.
(3)训练RPN时,与VGG共有的层参数可以直接拷贝经ImageNet训练得到的模型中的参数;剩下没有的层参数用标准差=0.01的高斯分布初始化.
7、RoI Pooling
ROI pooling layer实际上是SPP-NET的一个精简版,SPP-NET对每个proposal使用了不同大小的金字塔映射,而ROI pooling layer只需要下采样到一个7x7的特征图.对于VGG16网络conv5_3有512个特征图,这样所有region proposal对应了一个7*7*512维度的特征向量作为全连接层的输入.
RoI Pooling就是实现从原图区域映射到conv5区域最后pooling到固定大小的功能.
8、smooth L1 Loss
为了处理不可导的惩罚,Faster RCNN提出来的计算距离loss的smooth_L1_Loss.smooth L1近似理解见http://pages.cs.wisc.edu/~gfung/GeneralL1/L1_approx_bounds.pdf
C,https://www.cnblogs.com/wangyong/p/8513563.html
Faster RCNN 学习笔记
下面的介绍都是基于VGG16 的Faster RCNN网络,各网络的差异在于Conv layers层提取特征时有细微差异,至于后续的RPN层、Pooling层及全连接的分类和目标定位基本相同.
一)、整体框架
我们先整体的介绍下上图中各层主要的功能
1)、Conv layers提取特征图:
作为一种CNN网络目标检测方法,Faster RCNN首先使用一组基础的conv+relu+pooling层提取input image的feature maps,该feature maps会用于后续的RPN层和全连接层
2)、RPN(Region Proposal Networks):
RPN网络主要用于生成region proposals,首先生成一堆Anchor box,对其进行裁剪过滤后通过softmax判断anchors属于前景(foreground)或者后景(background),即是物体or不是物体,所以这是一个二分类;同时,另一分支bounding box regression修正anchor box,形成较精确的proposal(注:这里的较精确是相对于后面全连接层的再一次box regression而言)
3)、Roi Pooling:
该层利用RPN生成的proposals和VGG16最后一层得到的feature map,得到固定大小的proposal feature map,进入到后面可利用全连接操作来进行目标识别和定位
4)、Classifier:
会将Roi Pooling层形成固定大小的feature map进行全连接操作,利用Softmax进行具体类别的分类,同时,利用L1 Loss完成bounding box regression回归操作获得物体的精确位置.
二)、网络结构
现在,通过上图开始逐层分析
1)、Conv layers
Faster RCNN首先是支持输入任意大小的图片的,比如上图中输入的P*Q,进入网络之前对图片进行了规整化尺度的设定,如可设定图像短边不超过600,图像长边不超过1000,我们可以假定M*N=1000*600(如果图片少于该尺寸,可以边缘补0,即图像会有黑色边缘)
① 13个conv层:kernel_size=3,pad=1,stride=1;
卷积公式:
所以,conv层不会改变图片大小(即:输入的图片大小=输出的图片大小)
② 13个relu层:激活函数,不改变图片大小
③ 4个pooling层:kernel_size=2,stride=2;pooling层会让输出图片是输入图片的1/2
经过Conv layers,图片大小变成(M/16)*(N/16),即:60*40(1000/16≈60,600/16≈40);则,Feature Map就是60*40*512-d(注:VGG16是512-d,ZF是256-d),表示特征图的大小为60*40,数量为512
2)、RPN(Region Proposal Networks):
Feature Map进入RPN后,先经过一次3*3的卷积,同样,特征图大小依然是60*40,数量512,这样做的目的应该是进一步集中特征信息,接着看到两个全卷积,即kernel_size=1*1,p=0,stride=1;
如上图中标识:
① rpn_cls:60*40*512-d ⊕ 1*1*512*18 ==> 60*40*9*2
逐像素对其9个Anchor box进行二分类
② rpn_bbox:60*40*512-d ⊕ 1*1*512*36==>60*40*9*4
逐像素得到其9个Anchor box四个坐标信息(其实是偏移量,后面介绍)
如下图所示:
(2.1)、Anchors的生成规则
前面提到经过Conv layers后,图片大小变成了原来的1/16,令feat_stride=16,在生成Anchors时,我们先定义一个base_anchor,大小为16*16的box(因为特征图(60*40)上的一个点,可以对应到原图(1000*600)上一个16*16大小的区域),源码中转化为[0,0,15,15]的数组,参数ratios=[0.5, 1, 2]scales=[8, 16, 32]
先看[0,0,15,15],面积保持不变,长、宽比分别为[0.5, 1, 2]是产生的Anchors box
如果经过scales变化,即长、宽分别均为 (16*8=128)、(16*16=256)、(16*32=512),对应anchor box如图
综合以上两种变换,最后生成9个Anchor box
所以,最终base_anchor=[0,0,15,15]生成的9个Anchor box坐标如下:
1 [[ -84. -40. 99. 55.] 2 [-176. -88. 191. 103.] 3 [-360. -184. 375. 199.] 4 [ -56. -56. 71. 71.] 5 [-120. -120. 135. 135.] 6 [-248. -248. 263. 263.] 7 [ -36. -80. 51. 95.] 8 [ -80. -168. 95. 183.] 9 [-168. -344. 183. 359.]]
特征图大小为60*40,所以会一共生成60*40*9=21600个Anchor box
源码中,通过width:(0~60)*16,height(0~40)*16建立shift偏移量数组,再和base_ancho基准坐标数组累加,得到特征图上所有像素对应的Anchors的坐标值,是一个[216000,4]的数组
(2.2)、RPN工作原理解析
为了进一步更清楚的看懂RPN的工作原理,将Caffe版本下的网络图贴出来,对照网络图进行讲解会更清楚
主要看上图中框住的‘RPN’部分的网络图,其中‘rpn_conv/3*3’是3*3的卷积,上面有提到过,接着是两个1*1的全卷积,分别是图中的‘rpn_cls_score’和‘rpn_bbox_pred’,在上面同样有提到过。接下来,分析网络图中其他各部分的含义
2.2.1)、rpn-data
1. layer { 2. name: 'rpn-data' 3. type: 'Python' 4. bottom: 'rpn_cls_score' #仅提供特征图的height和width的参数大小 5. bottom: 'gt_boxes' #ground truth box 6. bottom: 'im_info' #包含图片大小和缩放比例,可供过滤anchor box 7. bottom: 'data' 8. top: 'rpn_labels' 9. top: 'rpn_bbox_targets' 10. top: 'rpn_bbox_inside_weights' 11. top: 'rpn_bbox_outside_weights' 12. python_param { 13. module: 'rpn.anchor_target_layer' 14. layer: 'AnchorTargetLayer' 15. param_str: "'feat_stride': 16 \n'scales': !!python/tuple [8, 16, 32]" 16. } 17. }
这一层主要是为特征图60*40上的每个像素生成9个Anchor box,并且对生成的Anchor box进行过滤和标记,参照源码,过滤和标记规则如下:
① 去除掉超过1000*600这原图的边界的anchor box
② 如果anchor box与ground truth的IoU值最大,标记为正样本,label=1
③ 如果anchor box与ground truth的IoU>0.7,标记为正样本,label=1
④ 如果anchor box与ground truth的IoU<0.3,标记为负样本,label=0
剩下的既不是正样本也不是负样本,不用于最终训练,label=-1
什么是IoU:
除了对anchor box进行标记外,另一件事情就是计算anchor box与ground truth之间的偏移量
令:ground truth:标定的框也对应一个中心点位置坐标x*,y*和宽高w*,h*
anchor box: 中心点位置坐标x_a,y_a和宽高w_a,h_a
所以,偏移量:
△x=(x*-x_a)/w_a △y=(y*-y_a)/h_a
△w=log(w*/w_a) △h=log(h*/h_a)
通过ground truth box与预测的anchor box之间的差异来进行学习,从而是RPN网络中的权重能够学习到预测box的能力
2.2.2) 、rpn_loss_cls、rpn_loss_bbox、rpn_cls_prob
下面集体看下这三个,其中‘rpn_loss_cls’、‘rpn_loss_bbox’是分别对应softmax,smooth L1计算损失函数,‘rpn_cls_prob’计算概率值(可用于下一层的nms非最大值抑制操作)
补充:
① Softmax公式,计算各分类的概率值
② Softmax Loss公式,RPN进行分类时,即寻找最小Loss值
在’rpn-data’中已经为预测框anchor box进行了标记,并且计算出与gt_boxes之间的偏移量,利用RPN网络进行训练。
RPN训练设置:在训练RPN时,一个Mini-batch是由一幅图像中任意选取的256个proposal组成的,其中正负样本的比例为1:1。如果正样本不足128,则多用一些负样本以满足有256个Proposal可以用于训练,反之亦然
2.2.3)、proposal
1. layer { 2. name: 'proposal' 3. type: 'Python' 4. bottom: 'rpn_cls_prob_reshape' #[1,18,40,60]==> [batch_size, channel,height,width]Caffe的数据格式,anchor box分类的概率 5. bottom: 'rpn_bbox_pred' # 记录训练好的四个回归值△x, △y, △w, △h 6. bottom: 'im_info' 7. top: 'rpn_rois' 8. python_param { 9. module: 'rpn.proposal_layer' 10. layer: 'ProposalLayer' 11. param_str: "'feat_stride': 16 \n'scales': !!python/tuple [4, 8, 16, 32]" 12. } 13. }
在输入中我们看到’rpn_bbox_pred’,记录着训练好的四个回归值△x, △y, △w, △h。
源码中,会重新生成60*40*9个anchor box,然后累加上训练好的△x, △y, △w, △h,从而得到了相较于之前更加准确的预测框region proposal,进一步对预测框进行越界剔除和使用nms非最大值抑制,剔除掉重叠的框;比如,设定IoU为0.7的阈值,即仅保留覆盖率不超过0.7的局部最大分数的box(粗筛)。最后留下大约2000个anchor,然后再取前N个box(比如300个);这样,进入到下一层ROI Pooling时region proposal大约只有300个
用下图一个案例来对NMS算法进行简单介绍
如上图所示,一共有6个识别为人的框,每一个框有一个置信率。
现在需要消除多余的:
- 按置信率排序: 0.95, 0.9, 0.9, 0.8, 0.7, 0.7
- 取最大0.95的框为一个物体框
- 剩余5个框中,去掉与0.95框重叠率IoU大于0.6(可以另行设置),则保留0.9, 0.8, 0.7三个框
- 重复上面的步骤,直到没有框了,0.9为一个框
- 选出来的为: 0.95, 0.9
所以,整个过程,可以用下图形象的表示出来
其中,红色的A框是生成的anchor box,而蓝色的G’框就是经过RPN网络训练后得到的较精确的预测框,绿色的G是ground truth box
2.2.4)、roi_data
1. layer { 2. name: 'roi-data' 3. type: 'Python' 4. bottom: 'rpn_rois' 5. bottom: 'gt_boxes' 6. top: 'rois' 7. top: 'labels' 8. top: 'bbox_targets' 9. top: 'bbox_inside_weights' 10. top: 'bbox_outside_weights' 11. python_param { 12. module: 'rpn.proposal_target_layer' 13. layer: 'ProposalTargetLayer' 14. param_str: "'num_classes': 81" 15. } 16. }
为了避免定义上的误解,我们将经过‘proposal’后的预测框称为region proposal(其实,RPN层的任务其实已经完成,roi_data属于为下一层准备数据)
主要作用:
① RPN层只是来确定region proposal是否是物体(是/否),这里根据region proposal和ground truth box的最大重叠指定具体的标签(就不再是二分类问题了,参数中指定的是81类)
② 计算region proposal与ground truth boxes的偏移量,计算方法和之前的偏移量计算公式相同
经过这一步后的数据输入到ROI Pooling层进行进一步的分类和定位.
3)、ROI Pooling:
1. layer { 2. name: "roi_pool5" 3. type: "ROIPooling" 4. bottom: "conv5_3" #输入特征图大小 5. bottom: "rois" #输入region proposal 6. top: "pool5" #输出固定大小的feature map 7. roi_pooling_param { 8. pooled_w: 7 9. pooled_h: 7 10. spatial_scale: 0.0625 # 1/16 11. } 12. }
从上述的Caffe代码中可以看到,输入的是RPN层产生的region proposal(假定有300个region proposal box)和VGG16最后一层产生的特征图(60*40 512-d),遍历每个region proposal,将其坐标值缩小16倍,这样就可以将在原图(1000*600)基础上产生的region proposal映射到60*40的特征图上,从而将在feature map上确定一个区域(定义为RB*)。
在feature map上确定的区域RB*,根据参数pooled_w:7,pooled_h:7,将这个RB*区域划分为7*7,即49个相同大小的小区域,对于每个小区域,使用max pooling方式从中选取最大的像素点作为输出,这样,就形成了一个7*7的feature map
细节可查看:https://www.cnblogs.com/wangyong/p/8523814.html
以此,参照上述方法,300个region proposal遍历完后,会产生很多个7*7大小的feature map,故而输出的数组是:[300,512,7,7],作为下一层的全连接的输入
4)、全连接层:
经过roi pooling层之后,batch_size=300, proposal feature map的大小是7*7,512-d,对特征图进行全连接,参照下图,最后同样利用Softmax Loss和L1 Loss完成分类和定位
通过full connect层与softmax计算每个region proposal具体属于哪个类别(如人,马,车等),输出cls_prob概率向量;同时再次利用bounding box regression获得每个region proposal的位置偏移量bbox_pred,用于回归获得更加精确的目标检测框
即从PoI Pooling获取到7x7大小的proposal feature maps后,通过全连接主要做了:
4.1)通过全连接和softmax对region proposals进行具体类别的分类
4.2)再次对region proposals进行bounding box regression,获取更高精度的rectangle box
作为一枚技术小白,写这篇笔记的时候参考了很多博客论文,在这里表示感谢,同时,未经同意,请勿转载....