R-CNN Series

RCNN

1
2
3
R-CNN源于2014年伯克利大学的这篇论文
《Rich feature hierarchies for accurate object detection and semantic segmentation》
其架构和模型训练参数等借鉴了AlexNet,也和同时期的Overfeat也有很多共同之处。成为目标检测领域尤其是two stage模式的开山鼻祖。

R-CNN网络结构

  • R-CNN 算法流程分四个步骤:

    1. 一张图像生成1k~2k个候选区域(使用 Selective Search 方法) [https://zhuanlan.zhihu.com/p/485727819]

      候选区域生成 (Selective Search) 的主要思想:图像中物体可能存在的区域应该是有某些相似性或者连续性区域的。

      1. 首先,对输入图像进行分割算法产生许多小的子区域。
      2. 其次,根据这些子区域之间相似性(相似性标准主要有颜色、纹理、大小等等)进行区域合并,不断的进行区域迭代合并。每次迭代过程中对这些合并的子区域做bounding boxes(外切矩形),这些子区域外切矩形就是通常所说的候选框。

      SS算法

    2. 对每个候选区域,使用深度网络(图片分类网络)提取特征

      1. 通过SS算法可以在一张图片中生成大概2000个候选区域,将候选区域送到CNN网络之前先进行resize处理,将2000候选区域缩放到 227 × 227 (原文是不管候选框多大都resize到 227 × 227)
      2. 接着将候选区域输入事先训练好的AlexNet / VGG CNN网络获取4096维的特征,得到2000×4096维矩阵。
    3. 特征送入每一类SVM分类器,判断是否属于该类

      1. 2000×4096维特征与20SVM组成的权值矩阵4096×20相乘,获得2000×20维矩阵表示每个建议框是某个目标类别的得分

        SVM分类器计算矩阵

      2. 分别对上述2000×20维矩阵中每一列即每一类进行**NSM(非极大值抑制)**剔除重叠建议框,得到该列即该类中得分最高的一些建议框。

    4. 使用回归器精细修正候选框位置。(使用 Selective Search 算法得到的候选框并不是框得那么准)

      1. 对NMS处理后剩余的建议框进一步筛选
      2. 分别用20个回归器对上述20个类别中剩余的建议框进行回归操作,最终得到每个类别的修正后的得分最高的bounding box

      (原文):

      1. 保留与真实目标比IoU大于某一阈值的预测框,不满足的直接删除
      2. 接着再分别使用20个回归器对剩余的预测框进行回归操作,最终得到每个类别的修正后得分最高的预测框。这里的实现方法跟上面的SVM分类差不多,依旧是对卷积神经网络输出的特征向量进行预测,利用每个边界框得到4096维特征向量来预测的。通过回归分类器之后会得到四个参数分别对应着目标建议框的中心点的x,y偏移量和目标边界框的宽高缩放因子。通过预测的四个值对得到的建议框进行调整得到最终的预测边界框。
  • RCNN存在的问题

    1. 检测速度慢,测试一张图片约53s (CPU)。用Selective Search算法提取候选框用时约2秒,一张图像内候选框之间存在大量重叠,提取特征操作冗余。
    2. 训练速度慢,并且训练过程极其复杂。
    3. 训练所需空间大,对于SVM和bbox回归训练,需要从每个图像中的每个目标候选框提取特征,并写入磁盘。对于非常深的网络,如VGG16,从VOC07训练集上的5k图像上提取的特征需要数百GB的存储空间。

SPPNet

1
2
由提出ResNet的何凯明在论文《Spatial Pyramid Pooling in Deep Convolutional Networks for Visual Recognition》中提出
主要就是可以解决CNN输入需要固定尺寸的问题,而且在分类和目标检测中都可以得到比较好的效果

SPPNet网络结构

  • 针对R-CNN的缺点:

    1).对每个候选区域提取特征。2).输入CNN的候选区域大小固定,要经过Resize。SPPNet做出了以下改进,具体内容看表格

    1. SPPNet让SS算法得到候选区域与feature map直接映射,得到候选区域的映射特征向量(这是映射来的,不需要每个候选区域都再经过CNN的计算,极大的减少了计算量)。

    2. SPPNet引入一种空间金字塔池化( spatial pyramid pooling,SPP)层以移除网络对固定尺寸的限制(不需要候选区域经过crop/wrap等操作变换成固定大小的图像)。

      image regions vs feature map regions

      R-CNN模型 SPPNet模型
      1.R-CNN让每个候选区域经过crop/wrap等操作变换成固定大小的图像. 2. 固定大小的每个候选区域塞给CNN 传给后面的层做训练回归、分类操作 1.SPPNet把全图塞给CNN得到全图的feature map. 2.让SS算法得到候选区域与feature map直接映射,得到候选区域的映射特征向量(这是映射来的,不需要过CNN). 3.映射过来的特征向量大小不固定,所以这些特征向量塞给SPP层(空间金字塔变换层),SPP层接收任何大小的输入,输出固定大小的特征向量,再塞给FC层. 4.经过映射+SPP转换,简化了计算,速度/精确度也上去了
  • 两个关键问题:

    • SPP层怎么可以接收任意大小的输入,输出固定的向量?

      spp layer会将每个候选区域分成1x1,2x2,4x4三张子图,对每个子图的每个区域作max pooling,得出的特征再连接到一起就是(16+4+1)x256=21x256=5376维向量,接着给全连接层做进一步处理。

    • SPPNet怎么就能把候选区域从全图的feature map 直接得到特征向量?

      feature map整个映射过程有具体的公式:$(x,y)=(Sx’,Sy’)$ $(x’,y’)=([x/S]+1,[y/S]+1)$(左上角+,右下角-)

      其中 S 就是CNN中所有的strides的乘积,包含了池化、卷积的stride。论文中使用S的计算出来为2x2x2x2=16,在ZF-5结构中。

Fast R-CNN

1
2
Fast R-CNN 是作者Ross Girshick继 R-CNN 后的又一力作,论文名就叫做 Fast R-CNN2015年发表。
同样使用VGG16作为网络的backbone,与 R-CNN 相比训练时间快了 9 倍,测试推理时间快了 213 倍,准确率从 62% 提升至了 66%(在 Pascal VOC 数据集上)

参考文章:

Fast R-CNN

ROI Pooling

RoI Pooling及其改进


Fast R-CNN网络结构

  • Fast R-CNN 算法流程分四个步骤:

    1. 一张图像生成1k~2k个候选区域(使用 Selective Search 方法)

    2. 将图像输入网络得到相应的特征图,将 Selective Search 算法生成的候选框投影到特征图上获得相应的特征矩阵

    3. 将每个特征矩阵通过 ROI pooling层缩放为$ 7 \times 7$大小的特征图

      ROI「region of interests」:指的是矩形框框出的区域,可能是有目标的也可能没目标,概念上等价于proposal region。

      ROI Pooling层的具体做法是:

      对候选框所对应的特征矩阵,将其划分为7*7,也就是49等份。划分之后,对每一个区域做一个最大池化下采样操作,也就是MaxPooling操作。如此对49等分的候选区域操作,便得到了一个7*7的特征矩阵。

      也就是说,无论候选框的特征矩阵是怎么样的尺寸,都被缩放到一个7*7的大小,这样就可以不去限制输入图像的尺寸了。

    4. 接着将特征图展平通过一系列全连接层获得预测结果

      最后并联了两个全连接层分别对分类和bbox进行预测。

      分类结点数为 N+1,因为需要增加上背景。bbox预测的全连接层则是$4*(N+1)$个结点,对每一类都要预测出来边界框回归参数。

      边界框回归器

      边界框回归器

  • 损失函数

    Fast RCNN将分类与回归做到了一个网络里面,因此损失函数必定是多任务的:
    $$
    L(p,u,t^u,v)=L_{cls}(p,u)+\lambda[u\geq1]L_{loc}(t^u,v)
    $$

    1. 分类损失:$L_{cls}(p,u) $

      使用交叉熵损失,p为预测结果的向量表示,u为真实类别的标签数据。

    2. bbox回归器损失:$\lambda[u>=1]L_{loc}(t^u,v)$ :

      • $\lambda$: 用于调节两部分损失函数的比例,一般取1

      • $[u\geq1]$: 是因为将u定义成了真实类别的索引,而且将background这一类定义成了0。所以如果标签是0的时候,这部分是不需要计算bbox的损失函数的,因为background不需要bbox。

      • $L_{loc}(t^u,v)$
        $$
        L_{loc}(t^u,v)=\sum_{i\in{x,y,w,h}}smooth_{L1}(t_i^u-v_i)
        $$

        $$
        smooth_{L1}(x)=
        \begin{cases}
        0.5x^2 &if\space|x|<1\
        |x|-0.5 &otherwise
        \end{cases}
        $$

        这一部分就是把预测框与groud truth中的x, y, w, h都单独拿出来进行相减(实际上就是L1的损失函数),然后计算smooth函数($Smooth_{L1}$),最后把这四个的smooth进行相加就是bbox回归器的损失函数。

        1
        2
        3
        4
        5
        6
        def smooth_l1(y_true, y_pred):
        # y_true和y_pred是特征位置的真实值和预测值
        abs_diff = K.abs(y_true - y_pred)
        less_than_one = K.cast(K.less(abs_diff, 1.0), "float32")
        loss = (0.5 * abs_diff**2) * less_than_one + (abs_diff - 0.5) * (1 - less_than_one)
        return loss

Faster R-CNN

1
2
Faster R-CNN 是作者 Ross Girshick 继 Fast R-CNN 后的又一力作,
同样使用 VGG16 作为 backbone,推理速度在 GPU 上达到 5fps(每秒检测五张图,包括候选区域生成),准确度也有一定的进步。核心在于 RPN 区域生成网络(Region Proposal Network)。

这篇文章介绍Faster R-CNN写的非常非常详细!


Faster R-CNN网络结构

  • Faster R-CNN 算法流程分三个步骤:

    1. 将图像输入网络得到相应的特征图-feature map
    2. 使用RPN网络(Region Proposal Network)生成候选框,将 RPN 生成的候选框投影到特征图上获得相应的特征矩阵
    3. 将每个特征矩阵通过 ROI pooling 层缩放为$7 \times 7$大小的特征图,接着将特征图展平通过一系列全连接层获得预测结果
  • RPN 网络结构

    滑动窗口生成anchors -> softmax分类器提取positvie anchors -> bbox reg回归positive anchors -> Proposal Layer生成proposals

    Faster R-CNN细节

    流程细节:

    1. 在经过backbone之后生成Feature Map大小为:H*W*N

      N是根据使用backbone的通道数来定的,比如VGG16为512个通道,而使用ZF网络则是256个通道。

    2. 对特征图做了3x3卷积,但输出层数保持不变(N),相当于每个点又融合了周围3x3的空间信息(猜测这样做也许更鲁棒?反正我没测试)

    3. 在上一步的结果上使用滑动窗口,每滑动到一个位置生成一个一维的向量, 在向量的基础上通过两个全连接层去输出目标概率(背景/非背景)和边界框回归参数。

      256-d是指使用ZF model作为backbone,最终每个点都用一个256维的向量表示,即N=256

      1*1卷积+Cls layer + Reg layer:

      分类任务「Cls layer」中,经过1*1卷积后,输出图像大小为:H*W*18,正好对应9个anchor boxes的2分类结果。为何要在softmax前后都接一个reshape layer?其实只是为了便于softmax分类,具体原因这就要从caffe的实现形式说起。

      回归任务「Reg layer」,经过1*1卷积后,输出图像大小为:H*W*36,正好对应9个anchor boxes的边界框。

      2k 中的 k 指的是 k 个 anchor boxes,2是指为背景的概率和为前景的概率

      4k 中的 k 指的是 k 个 anchor boxes,4是指每个 anchor 有 4 个边界框回归参数

      RPN

    4. Proposal层

      Proposal层共有三个输入:分类器结果【1,2*9,H,W】、边界框回归参数【1,4*9,H,W】、img_info

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

      1. 生成anchors,利用$d_x(A),d_y(A),d_w(A),d_h(a)$对所有的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)

      6. 对应的bbox reg的结果作为proposal输出

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

  • ROI Pooling层

    同Fast R-CNN中的ROI层作用和用法

  • FC层

    同Fast R-CNN中的FC层作用和用法

  • 损失函数

    RPN的损失也分为两个部分:分类损失和边界框回归损失
    $$
    L({p_i},{t_i})=\frac{1}{N_{cls}}\sum_{i}L_{cls}(p_i,p_i^*)+\lambda\frac{1}{N_{reg}}\sum_{i}{p_i^*}L_{reg}(t_i,t_i^*)
    $$

补充材料

  • Faster R-CNN

    1. 实际上生成的那么多 anchors 并不是每个都用来训练 RPN 网络。对于每张图片我们从上万个 anchor 当中采样 256 个 anchor,这些 anchor 由正样本和负样本 1:1 组成的。如果正样本不足 128,就用负样本进行填充。两种定义正样本的方式:(1)anchor 与 ground-truth 的 iou 超过 0.7,(2)某个 anchor 与 ground-truth 拥有最大的 iou。负样本是与所有的 ground-truth 的 iou 都小于 0.3 的。

    2. 感受野

      感受野


R-CNN Series
https://adzuki23.github.io/2024/05/15/OD-RCNN/
作者
Hongyu Li
发布于
2024年5月15日
更新于
2024年8月4日
许可协议