R CNN系列算法比较与Faster RCNN详解

    科技2022-07-15  126

    R CNN系列算法比较

    R-CNN:

    (1)image input; (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)image input; (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把类别判断和位置回归统一用深度网络实现,不再需要额外存储. (4) 由于ROI pooling的提出,不需要再input进行Corp和wrap操作,避免像素的损失,巧妙解决了尺度缩放的问题.

    FASTER -RCNN:

    (1)输入测试图像; (2)将整张图片输入CNN,进行特征提取; (3)先用RPN生成一堆Anchor box,对其进行裁剪过滤后通过softmax判断anchors属于前景(foreground)或者后景(background),即是物体or不是物体,所以这是一个二分类;同时,另一分支bounding box regression修正anchor box,形成较精确的proposal(注:这里的较精确是相对于后面全连接层的再一次box regression而言) (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个,且建议框的质量也有本质的提高.

    Faster RCNN详解

    如图1,Faster RCNN其实可以分为4个主要内容: 1.CNN:image经过conv+relu+pooling层得到feature map。该feature maps被共享用于后续RPN层和全连接层。 2.RPN(Region Proposal Network):该层通过softmax判断anchors属于positive或者negative,再利用bounding box regression修正anchors获得精确的proposals。 3.Roi Pooling:收集CNN层的feature map和RPN层的proposals。综合这些信息后提取proposal 和feature maps,送入后续全连接层判定目标类别。 4.Classification:利用proposal 和feature maps计算proposal的类别,同时再次bounding box regression获得检测框最终的精确位置。

    图2展示了python版本中的VGG16模型中的faster_rcnn_test.pt的网络结构,可以清晰的看到该网络对于一副任意大小PxQ的图像:

    1.首先缩放至固定大小MxN,然后将MxN图像送入网络;

    2.而Conv layers中包含了13个conv层+13个relu层+4个pooling层;

    3.RPN网络首先经过3x3卷积,再分别生成positive anchors和对应bounding box regression偏移量,然后计算出proposals;

    4.而Roi Pooling层则利用proposals从feature maps中提取proposal feature送入后续全连接和softmax网络作classification(即分类proposal到底是什么object)。

    1.CNN

    所有的conv层都是:kernel_size=3,pad=1,stride=1 所有的pooling层都是:kernel_size=2,pad=0,stride=2 即不改变输入和输出矩阵大小

    2.Region Proposal Networks(RPN)

    经典的检测方法生成检测框都非常耗时,如OpenCV adaboost使用滑动窗口+图像金字塔生成检测框;或如RCNN使用SS(Selective Search)方法生成检测框。而Faster RCNN则抛弃了传统的滑动窗口和SS方法,直接使用RPN生成检测框,这也是Faster RCNN的巨大优势,能极大提升检测框的生成速度。

    上图展示了RPN网络的具体结构。可以看到RPN网络实际分为2条线,上面一条通过softmax分类anchors获得foreground和background(检测目标是foreground),下面一条用于计算对于anchors的bounding box regression偏移量,以获得精确的proposal。而最后的Proposal层则负责综合foreground anchors和bounding box regression偏移量获取proposals,同时剔除太小和超出边界的proposals。其实整个网络到了Proposal Layer这里,就完成了相当于目标定位的功能。

    2.1 多通道图像卷积基础知识介绍

    如图,输入图像layer m-1有4个通道,同时有2个卷积核w1和w2。对于卷积核w1,先在输入图像4个通道分别作卷积,再将4个通道结果加起来得到w1的卷积输出;卷积核w2类似。所以对于某个卷积层, 无论输入图像有多少个通道,输出图像通道数总是等于卷积核数量! 缩进对多通道图像做1x1卷积,其实就是将输入图像于每个通道乘以卷积系数后加在一起,即相当于把原图像中本来各个独立的通道“联通”在了一起。

    2.2 anchors

    提到RPN网络,就不能不说anchors。所谓anchors,实际上就是一组由rpn/generate_anchors.py生成的矩形。直接运行作者demo中的generate_anchors.py可以得到以下输出: [[ -84. -40. 99. 55.] [-176. -88. 191. 103.] [-360. -184. 375. 199.] [ -56. -56. 71. 71.] [-120. -120. 135. 135.] [-248. -248. 263. 263.] [ -36. -80. 51. 95.] [ -80. -168. 95. 183.] [-168. -344. 183. 359.]] 其中每行的4个值[x1,y1,x2,y2]代表矩形左上和右下角点坐标。9个矩形共有3种形状,长宽比为大约为:width:height = [1:1, 1:2, 2:1]三种,如图6。实际上通过anchors就引入了检测中常用到的多尺度方法。 注:关于上面的anchors size,其实是根据检测图像设置的。在python demo中,会把任意大小的输入图像reshape成800x600(即图2中的M=800,N=600)。再回头来看anchors的大小,anchors中长宽1:2中最大为352x704,长宽2:1中最大736x384,基本是cover了800x600的各个尺度和形状。 那么这9个anchors是做什么的呢?借用Faster RCNN论文中的原图,如图7,遍历Conv layers计算获得的feature maps,为每一个点都配备这9种anchors作为初始的检测框。这样做获得检测框很不准确,不用担心,后面还有2次bounding box regression可以修正检测框位置。 解释一下上面这张图的数字。

    1.在原文中使用的是ZF model中,其Conv Layers中最后的conv5层num_output=256,对应生成256张特征图,所以相当于feature map每个点都是256-d 2.在conv5之后,做了rpn_conv/3x3卷积且num_output=256,相当于每个点又融合了周围3x3的空间信息(猜测这样做也许更鲁棒?反正我没测试),同时256-d不变(如图4和图7中的红框) 3.假设在conv5 feature map中每个点上有k个anchor(默认k=9),而每个anhcor要分foreground和background,所以每个点由256d feature转化为cls=2k scores;而每个anchor都有[x, y, w, h]对应4个偏移量,所以reg=4k coordinates 4.补充一点,全部anchors拿去训练太多了,训练程序会选取256个合适的anchors进行训练(什么是合适的anchors下文5.1有解释)

    注意,在本文讲解中使用的VGG conv5 num_output=512,所以是512d,其他类似…

    2.3 softmax判定foreground与background

    可以看到其num_output=18,也就是经过该卷积的输出图像为WxHx18大小(注意第二章开头提到的卷积计算方式)。这也就刚好对应了feature maps每一个点都有9个anchors,同时每个anchors又有可能是foreground和background,所有这些信息都保存WxHx(9x2)大小的矩阵。 为何这样做?后面接softmax分类获得foreground anchors,也就相当于初步提取了检测目标候选区域box(一般认为目标在foreground anchors中)。 那么为何要在softmax前后都接一个reshape layer?其实只是为了便于softmax分类,即 单独“腾空”出来一个维度以便softmax分类,之后再reshape回复原状。 综上所述,RPN网络中利用anchors和softmax初步提取出foreground anchors作为候选区域。

    2.4 bounding box regression原理

    对于窗口一般使用四维向量(x, y, w, h)表示,分别表示窗口的中心点坐标和宽高。对于图 10,红色的框A代表原始的Foreground Anchors,绿色的框G代表目标的GT,我们的目标是寻找一种关系,使得输入原始的anchor A经过映射得到一个跟真实窗口G更接近的回归窗口G’,即:给定A=(Ax, Ay, Aw, Ah),寻找一种映射f,使得f(Ax, Ay, Aw, Ah)=(G’x, G’y, G’w, G’h),其中(G’x, G’y, G’w, G’h)≈(Gx, Gy, Gw, Gh)。 那么经过何种变换才能从图6中的A变为G’呢? 比较简单的思路就是:

    缩进 1. 先做平移 缩进 2. 再做缩放

    2.5 对proposals进行bounding box regression

    可以看到其num_output=36,即经过该卷积输出图像为WxHx36,在caffe blob存储为[1, 36, H, W]。与上文中fg/bg anchors存储为[1, 18, H, W]类似,这里相当于feature maps每个点都有9个anchors,每个anchors又都有4个用于回归的[dx(A),dy(A),dw(A),dh(A)]变换量。利用上面的的计算公式即可从foreground anchors回归出proposals。

    2.6 Proposal Layer

    Proposal Layer负责综合所有[d x(A),d y(A),d w(A),d h(A)]变换量和foreground anchors,计算出精准的proposal,送入后续RoI Pooling Layer。 Proposal Layer有3个输入:fg/bg anchors分类器结果rpn_cls_prob_reshape,对应的bbox reg的[d x(A),d y(A),d w(A),d h(A)]变换量rpn_bbox_pred,以及im_info;另外还有参数feat_stride=16,这和图4是对应的。 首先解释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则保存了该信息。所有这些数值都是为了将proposal映射回原图而设置的,如图12,毕竟检测就是为了在原图上画一个框而已~

    Proposal Layer forward(caffe layer的前传函数)按照以下顺序依次处理:

    再次生成anchors,并对所有的anchors做bbox reg位置回归(注意这里的anchors生成顺序和之前是即完全一致的)按照输入的foreground softmax scores由大到小排序anchors,提取前pre_nms_topN(e.g. 6000)个anchors。即提取修正位置后的foreground anchors利用feat_stride和im_info将anchors映射回原图,判断fg anchors是否大范围超过边界,剔除严重超出边界fg anchors。进行nms(nonmaximum suppression,非极大值抑制)再次按照nms后的foreground softmax scores由大到小排序fg anchors,提取前post_nms_topN(e.g. 300)结果作为proposal输出。

    之后输出proposal=[x1, y1, x2, y2], 注意,由于在第三步中将anchors映射回原图判断是否超出边界,所以这里输出的proposal是对应MxN输入图像尺度的,这点在后续网络中有用。另外我认为,严格意义上的检测应该到此就结束了,后续部分应该属于识别了~

    RPN网络结构就介绍到这里,总结起来就是: 生成anchors -> softmax分类器提取fg anchors -> bbox reg回归fg anchors -> Proposal Layer生成proposals

    3.RoI pooling

    而RoI Pooling层则负责收集proposal,并计算出proposal feature maps,送入后续网络。从图3中可以看到Rol pooling层有2个输入:

    原始的feature mapsRPN输出的proposal boxes(大小各不相同)

    3.1 为何需要RoI Pooling

    先来看一个问题:对于传统的CNN(如AlexNet,VGG),当网络训练好后输入的图像尺寸必须是固定值,同时网络输出也是固定大小的vector or matrix。如果输入图像大小不定,这个问题就变得比较麻烦。有2种解决办法:

    从图像中crop一部分传入网络将图像warp成需要的大小后传入网络

    两种办法的示意图如图13,可以看到无论采取那种办法都不好,要么crop后破坏了图像的完整结构,要么warp破坏了图像原始形状信息。回忆RPN网络生成的proposals的方法:对foreground anchors进行bound box regression,那么这样获得的proposals也是大小形状各不相同,即也存在上述问题。所以Faster RCNN中提出了RoI Pooling解决这个问题。

    3.2 RoI Pooling原理

    其中有新参数pooled_w=pooled_h=7,另外一个参数spatial_scale=1/16应该能够猜出大概吧。

    缩进RoI Pooling layer forward过程:在之前有明确提到:proposal=[x1, y1, x2, y2]是对应MxN尺度的,所以首先使用spatial_scale参数将其映射回MxN大小的feature maps尺度(这里来回多次映射,是有点绕);之后将每个proposal水平和竖直都分为7份,对每一份都进行max pooling处理。这样处理后,即使大小不同的proposal,输出结果都是7x7大小,实现了fixed-length output

    4.Classification

    Classification部分利用已经获得的proposal feature maps,通过full connect层与softmax计算每个proposal具体属于那个类别(如人,车,电视等),输出cls_prob概率向量;同时再次利用bounding box regression获得每个proposal的位置偏移量bbox_pred,用于回归更加精确的目标检测框。Classification部分网络结构如图。 从PoI Pooling获取到7x7=49大小的proposal feature maps后,送入后续网络,可以看到做了如下2件事:

    通过全连接和softmax对proposals进行分类,这实际上已经是识别的范畴了再次对proposals进行bounding box regression,获取更高精度的rect box

    这里来看看全连接层InnerProduct layer,如图, 其计算公式如下: 其中W和bias B都是预先训练好的,即大小是固定的,当然输入X和输出Y也就是固定大小。所以,这也就印证了之前Poi Pooling的必要性。到这里,我想其他内容已经很容易理解,不在赘述了。

    5.Faster RCNN训练

    Faster CNN的训练,是在已经训练好的model(如VGG_CNN_M_1024,VGG,ZF)的基础上继续进行训练。实际中训练过程分为6个步骤:

    在已经训练好的model上,训练RPN网络,对应stage1_rpn_train.pt利用步骤1中训练好的RPN网络,收集proposals,对应rpn_test.pt第一次训练Fast RCNN网络,对应stage1_fast_rcnn_train.pt第二训练RPN网络,对应stage2_rpn_train.pt再次利用步骤4中训练好的RPN网络,收集proposals,对应rpn_test.pt第二次训练Fast RCNN网络,对应stage2_fast_rcnn_train.pt

    可以看到训练过程类似于一种“迭代”的过程,不过只循环了2次。至于只循环了2次的原因是应为作者提到:“A similar alternating training can be run for more iterations, but we have observed negligible improvements”,即循环更多次没有提升了。接下来本章以上述6个步骤讲解训练过程。

    5.1 训练RPN网络

    在该步骤中,首先读取RBG提供的预训练好的model(本文使用VGG),开始迭代训练。来看看stage1_rpn_train.pt网络结构,如图 [未完,接下来准备做Faster RCNN代码复现]

    Processed: 0.020, SQL: 8