**
Faster RCNN
**
Content
- Introduction
- Conv layers
2.1 VGG
2.2 Google InceptionNet-Inception Module
2.3 ResNet:VGG - Region Proposal Networks(RPN)
- RoI pooling
- Classification
- Test Result
1 Introduction
Ross B. Girshick在2016年提出了新的Faster RCNN,在结构上,Faster RCNN已经将特征抽取(feature extraction),proposal提取,bounding box regression(rect refine),classification都整合在了一个网络中,使得综合性能有较大提高,在检测速度方面尤为明显。

Conv layers:作为一种CNN网络目标检测方法,Faster RCNN首先使用一组基础的conv+relu+pooling层提取image的feature maps。该feature maps被共享用于后续RPN层和全连接层。
Region Proposal Networks:RPN网络用于生成region proposals。该层通过softmax判断anchors属于positive或者negative,再利用bounding box regression修正anchors获得精确的proposals。
Roi Pooling:该层收集输入的feature maps和proposals,综合这些信息后提取proposal feature maps,送入后续全连接层判定目标类别。
Classification:利用proposal feature maps计算proposal的类别,同时再次bounding box regression获得检测框最终的精确位置。

2 Conv layer
2.1 VGG
VGG是基于Alexnet网络的,VGG在Alexnet基础上对深度神经网络在深度和宽度上做了更多深入的研究,业界普遍认为,更深的网络具有比浅网络更强的表达能力,更能刻画现实,完成更复杂的任务。
首先,VGG与Alexnet相比,具有如下改进几点:
去掉了LRN层,作者发现深度网络中LRN的作用并不明显,干脆取消了
采用更小的卷积核-3x3,Alexnet中使用了更大的卷积核,比如有7x7的,因此VGG相对于Alexnet而言,参数量更少
池化核变小,VGG中的池化核是2x2,stride为2,Alexnet池化核是3x3,步长为2
这样做改进都是有一些原因的,首先为了更好的探究深度对网络的影响,必须要解决参数量的问题,更深的网络意味着更多的参数,训练更困难,使用大卷积核时尤其明显。作者通过分析,认为由于卷积神经网络的特性,3x3大小的卷积核足以捕捉到横、竖以及斜对角像素的变化。使用大卷积核会带来参数量的爆炸不说,而且图像中会存在一些部分被多次卷积,可能会给特征提取带来困难,所以在VGG中,普遍使用3x3的卷积。
Conv layers包含了conv,pooling,relu三种层。以python版本中的VGG16模型中的faster_rcnn_test.pt的网络结构为例。Conv layers部分共有13个conv层,13个relu层,4个pooling层。在Conv layers中:
所有的conv层都是:kernel_size=3,pad=1,stride=1
所有的pooling层都是:kernel_size=2,pad=0,stride=2
在Faster RCNN Conv layers中对所有的卷积都做了扩边处理( pad=1,即填充一圈0),导致原图变为 (M+2)x(N+2)大小,再做3x3卷积后输出MxN 。正是这种设置,使得Conv layers中的conv层不改变输入和输出矩阵大小。如图:
Conv layers中的pooling层kernel_size=2,stride=2。这样每个经过pooling层的MxN矩阵,都会变为(M/2)x(N/2)大小。综上所述,在整个Conv layers中,conv和relu层不改变输入输出大小,只有pooling层使输出长宽都变为输入的1/2。
那么,一个MxN大小的矩阵经过Conv layers固定变为(M/16)x(N/16)。这样Conv layers生成的feature map中都可以和原图对应起来。
2.2 GoogleNet
Google InceptionNet出现在ILSVRC2014年的比赛中(和VGGNet同年),并以较大优势夺得了第一名的成绩,它的top5错误率为6.67%,VGGNet的错误率为7.3%。InceptionNet的最大特点是控制了计算量和参数量的同时提高了网络的性能,它的层数为22,比VGGNet19还深,但是只有15亿次浮点计算和500万的参数量。
InceptionNet精心设计的Inception Module很好的提升了模型的性能,同时降低了参数量。一般来说卷积网络要提升表达能力,主要依靠增加输出通道的数量,但是带来的副作用是计算量增大和过拟合。一般设计思路的情况下会出现缺陷
1.参数太多,容易过拟合,若训练数据集有限;
2.网络越大计算复杂度越大,难以应用;
3.网络越深,梯度越往后穿越容易消失,难以优化模型)。
googlenet的主要思想就是围绕这两个思路去做的:
1.深度,层数更深,文章采用了22层,为了避免上述提到的梯度消失问题,googlenet巧妙的在不同深度处增加了两个loss来保证梯度回传消失的现象。
2.宽度,增加了多种核 1x1,3x3,5x5,还有直接max pooling的,但是如果简单的将这些应用到feature map上的话,concat起来的feature map厚度将会很大,所以在googlenet中为了避免这一现象提出的inception具有如下结构,在3x3前,5x5前,max pooling后分别加上了1x1的卷积核起到了降低feature map厚度的作用。
综上googlent有两个最重要的创新点分别是为了解决深度和宽度受限来设计的,由于googlenet的两个辅助loss的限制,很多文章拿base model的时候比较偏向与vgg。因此InceptionNet采用分支网络堆叠在一起产生较大通道的输出。如下图所示,产生4个网络对前一层的输出做计算,然后将不同卷积大小的输出在通道上堆叠在一起。

可以看到每个分支都采用了1*1的卷积网络,可以跨通道组织信息,提高网络的表达能力,提供更多的非线性变换,性价比很高。同时网络中的卷积和大小也不一样,可以增加网络对不同尺度的适应性。所以,InceptionNet通过分支的方式增大网络的宽度和深度能够很好的提高网络的性能,避免过拟合。
提出并采用了BatchNormalization(BN)。BN就是神经网络在训练的时候对每个Batch数据的内部进行标准化,使输出规范化到N(0,1)的正态分布,可以让卷积网络的训练速度加快,同时收敛后的分类准确率也可以提高很多。BN在某种程度上还起到正则的作用,所以可以减小或者取消Dropout,优化网络结构。可
而GoogleNet可以看做多个inception的叠加:
旁边的两个softmax,是训练时为了避免上述梯度消失问题,模型训练好后就拿掉。
2.3 ResNet
深度网络的退化问题
从经验来看,网络的深度对模型的性能至关重要,当增加网络层数后,网络可以进行更加复杂的特征模式的提取,所以当模型更深时理论上可以取得更好的结果。但是实验发现深度网络出现了退化问题(Degradation problem):网络深度增加时,网络准确度出现饱和,甚至出现下降。这个现象可以在图中直观看出来:56层的网络比20层网络效果还要差。这不会是过拟合问题,因为56层网络的训练误差同样高。深层网络存在着梯度消失或者爆炸等问题,这使得深度学习模型很难训练。

ResNet采用了一种“短路”的结构来解决这个问题:

假定原来的网络结构需要学习得到函数 H(x),那么让原始信号 x 接到输出部分,并修改需要学习的函数为F(x)=H(x)-x,便可得到同样的效果。
通过这样的方式,原始信号可以跳过一部分网络层,直接在更深的网络层传递。从直觉上来看,深层神经网络之所以难以训练,就是因为原始信号x在网络层中传递时,越来越失真(即梯度不稳定),而这种“短路”结构使得原始信号直接传入神经网络的深层,避免了信号失真,这样一来便极大地加快了神经网络训练时的效率。
ResNet使用两种残差单元,如下图所示。左图对应的是浅层网络,而右图对应的是深层网络。对于短路连接,当输入和输出维度一致时,可以直接将输入加到输出上。但是当维度不一致时(对应的是维度增加一倍),这就不能直接相加。有两种策略:(1)采用zero-padding增加维度,此时一般要先做一个downsamp,可以采用stride=2的pooling,这样不会增加参数;(2)采用新的映射(projection shortcut),一般采用1x1的卷积,这样会增加参数,也会增加计算量。短路连接除了直接使用恒等映射,当然都可以采用projection shortcut。

作者设计了实验来证明自己的观点。首先构建了一个18层和一个34层的plain网络,即将所有层进行简单的铺叠,然后构建了一个18层和一个34层的residual网络,仅仅是在plain上插入了shortcut,而且这两个网络的参数量、计算量相同,并且和之前有很好效果的VGG-19相比,计算量要小很多。(36亿FLOPs VS 196亿FLOPs,FLOPs即每秒浮点运算次数。)

不同结构的实验结果:

模型构建好后进行实验,在plain上观测到明显的退化现象,而且ResNet上不仅没有退化,34层网络的效果反而比18层的更好,而且不仅如此,ResNet的收敛速度比plain的要快得多。
3 Region Proposal Networks(RPN)
RPN网络实际分为2条线,上面一条通过softmax分类anchors获得positive和negative分类,下面一条用于计算对于anchors的bounding box regression偏移量,以获得精确的proposal。而最后的Proposal层则负责综合positive anchors和对应bounding box regression偏移量获取proposals,同时剔除太小和超出边界的proposals。
3.1 Anchors
所谓anchors,实际上就是一组由rpn/generate_anchors.py生成的矩形。anchors size,是根据检测图像设置的。在python demo中,会把任意大小的输入图像reshape成800x600(即图2中的M=800,N=600)。再回头来看anchors的大小,anchors中长宽1:2中最大为352x704,长宽2:1中最大736x384,基本是cover了800x600的各个尺度和形状。
其实RPN最终就是在原图尺度上,设置了密密麻麻的候选Anchor。然后用cnn去判断哪些Anchor是里面有目标的positive anchor,哪些是没目标的negative anchor。

那么Anchor一共有多少个?原图800x600,VGG下采样16倍,feature map每个点设置9个Anchor,所以:
ceil(800/16)∗ceil(600/16)∗9=17100
ceil(800/16) * ceil(600/16) * 9 = 17100
ceil(800/16)∗ceil(600/16)∗9=17100
其中ceil()表示向上取整,是因为VGG输出的feature map size= 50*38。
3.2 多通道图像卷积

如图,输入有3个通道,同时有2个卷积核。对于每个卷积核,先在输入3个通道分别作卷积,再将3个通道结果加起来得到卷积输出。所以对于某个卷积层,无论输入图像有多少个通道,输出图像通道数总是等于卷积核数量。
对多通道图像做1x1卷积,其实就是将输入图像于每个通道乘以卷积系数后加在一起,即相当于把原图像中本来各个独立的通道“联通”在了一起,那么就可以达到降维的效果。比如,一张500 * 500且厚度depth为100 的图片在20个filter上做1*1的卷积,那么结果的大小为500 * 500 * 20。
一副MxN大小的矩阵送入Faster RCNN网络后,到RPN网络变为(M/16)x(N/16),设 W=M/16,H=N/16。在进入reshape与softmax之前,先做了1x1卷积。该1x1卷积的caffe prototxt定义如下:
layer {
name: "rpn_cls_score"
type: "Convolution"
bottom: "rpn/output"
top: "rpn_cls_score"
convolution_param {
num_output: 18 # 2(positive/negative) * 9(anchors)
kernel_size: 1 pad: 0 stride: 1
}
}
可以看到其num_output=18,也就是经过该卷积的输出图像为WxHx18大小。刚好对应了feature maps每一个点都有9个anchors,同时每个anchors又有可能是positive和negative,所有这些信息都保存WxHx(9*2)大小的矩阵。后面接softmax分类获得positive anchors,也就相当于初步提取了检测目标候选区域box(一般认为目标在positive anchors中)。
3.3 Reshape & Softmax
Reshape:
对于cls层后又接了一个reshape层,其实只是为了便于softmax分类。在caffe基本数据结构blob中以如下形式保存数据:
blob=[batch_size, channel,height,width]
对应至上面的保存positive/negative anchors的矩阵,其在caffe blob中的存储形式为[1, 2x9, H, W]。而在softmax分类时需要进行positive/negative二分类,所以reshape layer会将其变为[1, 2, 9xH, W]大小,即单独“腾空”出来一个维度以便softmax分类,之后再reshape回复原状。
Softmax:
计算每个像素256-d的9个尺度下的值,得到9个anchor,我们给每个anchor分配一个二进制的标签(P/N or fg/bg)。分配正标签前景给两类anchor:
1)与某个ground truth(GT)包围盒有最高的IoU重叠的anchor(也许不到0.7),
2)与任意GT包围盒有大于0.7的IoU交叠的anchor。注意到一个GT包围盒可能分配正标签给多个anchor。
分配负标签给与所有GT包围盒的IoU比率都低于0.3的anchor。
非正非负的anchor对训练目标没有任何作用,由此输出维度为(2*9)18,一共18维。
IoU 的全称为交并比(Intersection over Union),通过这个名称我们大概可以猜到 IoU 的计算方法。IoU 计算的是 “预测的边框” 和 “真实的边框” 的交集和并集的比值。
训练程序会在合适的anchors中随机选取128个postive anchors+128个negative anchors进行训练。
3.4 bounding box regression & proposal layer
1 * 1 conv:
可以看到第二条分支中cov层的 num_output=36,即经过该卷积输出图像为WxHx36,在caffe blob存储为[1, 4x9, H, W],这里相当于feature maps每个点都有9个anchors,每个anchors又都有4个用于回归的变换量。
VGG输出50 * 38 * 512的特征,对应设置50 * 38 * k个anchors,而RPN输出:
1 大小为50 * 38 * 2k的positive/negative softmax分类特征
2 矩阵大小为 50 * 38 * 4k的regression坐标回归特征矩阵
恰好满足RPN完成positive/negative分类+bounding box regression坐标回归.
bounding box regression:

对于上图,绿色的框表示Ground Truth, 红色的框为Selective Search提取的Region Proposal。那么即便红色的框被分类器识别为飞机,但是由于红色的框定位不准(IoU<0.5), 那么这张图相当于没有正确的检测出飞机。 Bounding-box regression 就是用来微调这个窗口,使得经过微调后的窗口跟Ground Truth更接近。
先做平移G^x=Pwdx(P)+Px,(1)\hat G_x = P_w d_x(P) + P_x , \text(1)G^x=Pwdx(P)+Px,(1)G^y=Phdy(P)+Py,(2)\hat G_y= P_h d_y(P) + P_y , \text(2)G^y=Phdy(P)+Py,(2)再做缩放G^w=Pwexp(dw(P)),(3)\hat G_w= P_w exp(d_w(P) ), \text(3)G^w=Pwexp(dw(P)),(3)G^h=Phexp(dh(P)),(4)\hat G_h= P_h exp(d_h(P) ) , \text(4)G^h=Phexp(dh(P)),(4)
边框回归学习就是dx(P),dy(P),dw(P),dh(P)dx(P),dy(P),dw(P),dh(P)dx(P),dy(P),dw(P),dh(P)这四个变换。那么目标函数可以表示为 d∗(P)=wT∗Φ5(P)d∗(P)=wT∗Φ5(P)d∗(P)=wT∗Φ5(P),Φ5(P)Φ5(P)Φ5(P)是输入 Proposal 的特征向量,w∗w∗w∗ 是要学习的参数(*表示 x,y,w,h, 也就是每一个变换对应一个目标函数) , d∗(P)d∗(P)d∗(P) 是得到的预测值。 我们要让预测值跟真实值t∗=(tx,ty,tw,th)t∗=(tx,ty,tw,th)t∗=(tx,ty,tw,th)差距最小, 得到损失函数(一般使用soomth-L1损失)为:Loss=∑iN(ti∗−wT∗ϕ5(Pi))Loss=∑iN(ti∗−w^T∗ϕ5(Pi))Loss=∑iN(ti∗−wT∗ϕ5(Pi))函数优化目标为:W∗=argminw∗∑iN(ti∗−wT∗ϕ5(Pi))2+λ∣∣w∗∣∣24W∗=argminw∗∑iN(ti∗−w^T∗ϕ5(Pi))2+λ||w^∗||24W∗=argminw∗∑iN(ti∗−wT∗ϕ5(Pi))2+λ∣∣w∗∣∣24
对于训练bouding box regression网络回归分支,输入是cnn feature Φ窗口对应的 CNN 特征,以及Ground Truth t∗=(tx,ty,tw,th))t∗=(tx,ty,tw,th))t∗=(tx,ty,tw,th))。监督信号是Anchor与GT的差距 ,即训练目标是:输入 Φ的情况下使网络输出与监督信号尽可能接近。那么当bouding box regression工作时,再输入Φ时,回归网络分支的输出就是每个Anchor的平移量和变换尺度 ,即可用来修正Anchor位置了。
3.5 Proposal Layer
Proposal Layer负责综合所有变换量dx(P),dy(P),dw(P),dh(P)dx(P),dy(P),dw(P),dh(P)dx(P),dy(P),dw(P),dh(P)和positive anchors,计算出精准的proposal,送入后续RoI Pooling Layer。Proposal Layer的caffe prototxt定义:
layer {
name: 'proposal'
type: 'Python'
bottom: 'rpn_cls_prob_reshape'
bottom: 'rpn_bbox_pred'
bottom: 'im_info'
top: 'rois'
python_param {
module: 'rpn.proposal_layer'
layer: 'ProposalLayer'
param_str: "'feat_stride': 16"
}
}
Proposal Layer有3个输入:
1 positive vs negative anchors分类器结果rpn_cls_prob_reshape
2 对应的bbox reg的变换量rpn_bbox_pred,
3 以及im_info;另外还有参数feat_stride=16
首先解释im_info。对于一副任意大小PxQ图像,传入Faster RCNN前首先reshape到固定MxN,im_info=[M, N, scale_factor]则保存了此次缩放的所有信息。然后经过Conv Layers,经过4次pooling变为WxH=(M/16)x(N/16)大小,其中feature_stride=16则保存了该信息,用于计算anchor偏移量。
Proposal Layer forward(caffe layer的前传函数)按照以下顺序依次处理:
1 生成anchors,利用dx(P),dy(P),dw(P),dh(P)dx(P),dy(P),dw(P),dh(P)dx(P),dy(P),dw(P),dh(P)对所有的anchors做bbox regression回归(这里的anchors生成和训练时完全一致)
2 按照输入的positive softmax scores由大到小排序anchors,提取前pre_nms_topN(e.g. 6000)个anchors,即提取修正位置后的positive anchors
3 限定超出图像边界的positive anchors为图像边界,防止后续roi pooling时proposal超出图像边界
4 剔除尺寸非常小的positive anchors
5 对剩余的positive anchors进行NMS(nonmaximum suppression)由于锚点经常重叠,因此建议最终也会在同一个目标上重叠。为了解决重复建议的问题,我们使用一个简单的算法,称为非极大抑制(NMS)。NMS 获取按照分数排序的建议列表并对已排序的列表进行迭代,丢弃那些 IoU 值大于某个预定义阈值的建议,并提出一个具有更高分数的建议。
最终输出proposal=[x1, y1, x2, y2],由于在第三步中将anchors映射回原图判断是否超出边界,所以这里输出的proposal是对应MxN输入图像尺度的。
RPN网络结构总结起来就是:
生成anchors -> softmax分类器提取positvie anchors -> bbox reg回归positive anchors -> Proposal Layer生成proposals
4 ROI Pooling
对于传统的CNN(如AlexNet和VGG),当网络训练好后输入的图像尺寸必须是固定值,同时网络输出也是固定大小的vector or matrix。如果输入图像大小不定,这个问题就变得比较麻烦。有2种解决办法:
1 从图像中crop一部分传入网络
2 将图像warp成需要的大小后传入网络

无论采取那种办法都不好,要么crop后破坏了图像的完整结构,要么warp破坏了图像原始形状信息。回忆RPN网络生成的proposals的方法:对positive anchors进行bounding box regression,那么这样获得的proposals也是大小形状各不相同,即也存在上述问题。所以Faster R-CNN中提出了RoI Pooling解决这个问题。
RoI Pooling layer forward过程:
1 由于proposal是对应MxN尺度的,所以首先使用spatial_scale参数将其映射回(M/16)x(N/16)大小的feature map尺度;
2 再将每个proposal对应的feature map区域水平分为pooledw∗pooledhpooled_w * pooled_hpooledw∗pooledh的网格;
3 对网格的每一份都进行max pooling处理。
这样处理后,即使大小不同的proposal输出结果都是 pooledw∗pooledhpooled_w * pooled_hpooledw∗pooledh固定大小,实现了固定长度输出。
从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*)。
. layer {
. name: "roi_pool5"
. type: "ROIPooling"
. bottom: "conv5_3" #输入特征图大小
. bottom: "rois" #输入region proposal
. top: "pool5" #输出固定大小的feature map
. roi_pooling_param {
. pooled_w: 7
. pooled_h: 7
. spatial_scale: 0.0625 # 1/16
. }
. }
在feature map上确定的区域RB*,根据参数pooled_w:7,pooled_h:7,将这个RB*区域划分为7 * 7,即49个相同大小的小区域,对于每个小区域,使用max pooling方式从中选取最大的像素点作为输出,这样,就形成了一个7 * 7的feature map。以此,参照上述方法,300个region proposal遍历完后,会产生很多个7 * 7大小的feature map,故而输出的数组是:[300,512,7,7],作为下一层的全连接的输入。
5 Classification
Classification部分利用已经获得的proposal feature maps,通过full connect层与softmax计算每个proposal具体属于那个类别(如人,车,电视等),输出cls_prob概率向量;同时再次利用bounding box regression获得每个proposal的位置偏移量bbox_pred,用于回归更加精确的目标检测框。

从RoI Pooling获取到7x7=49大小的proposal feature maps后,送入后续网络,可以看到做了如下2件事:
1 通过全连接和softmax对proposals进行分类
2 再次对proposals进行bounding box regression,获取更高精度的rect box
6 Test result
使用PASCAL VOC (Pascal VOC的三个主要物体识别竞赛是:分类,检测和分割(classification, detection, and segmentation)。对于分割任务, VOC2012的trainval包含2007-2011年的所有对应图片, test只包含2008-2011。trainval有 2913张图片共6929个物体)的公开数据集和MS COCO数据集测试(COCO数据集是一个大型的、丰富的物体检测,分割和字幕数据集。这个数据集以scene understanding为目标,主要从复杂的日常场景中截取,图像中的目标通过精确的segmentation进行位置的标定。图像包括91类目标,328,000影像和2,500,000个label。目前为止有语义分割的最大数据集,提供的类别有80 类,有超过33 万张图片,其中20 万张有标注,整个数据集中个体的数目超过150 万个)。



优点:
●优化了建议区域的产生方式,使其真正实现了end-to-end训练
●在GPU上达到了实时(5fpsbased VGG & 17fps based ZF)
●精度更高
本文详细介绍了Faster RCNN目标检测算法,包括其结构、各模块功能及测试结果。该算法将特征抽取、proposal提取等整合在一个网络中,提高了综合性能。文中还阐述了Conv layers、Region Proposal Networks、RoI pooling和Classification等模块的工作原理,并使用公开数据集进行测试,展现出优化建议区域产生方式、实时性和高精度等优点。
3483

被折叠的 条评论
为什么被折叠?



