[图解]Faster R-CNN – 原理和实现细节

  • Post author:
  • Post category:其他




论文原文


Faster R-CNN: Towards Real-Time Object Detection with Region Proposal Networks



网络结构

Faster R-CNN 使用了注意力(attention)机制,它由两个模块组成。

1. RPN(region proposal network) 作用是推荐图像中的有物体区域。

2. Fast R-CNN 检测器 作用是检测是什么物体。



RPN

RPN网络的输入是任意大小的图像,输出是一些矩形以及这些矩形中

是否有物体

的得分。如下图所示。

在原文中,RPN网络为CNN后面接一个3×3的卷积层,再接两个并列的(sibling)1×1的卷积层,其中一个是用来给softmax层进行分类(2分类,有物体还是没有物体),另一个用于给候选区域精确定位(框位置的偏移)。



Anchors

Anchors是一些预设大小的框,原文中Anchors的面积有三种

ANCHOR_AREAS = [128**2,256**2,512**2]

, 长宽比也有三种

ANCHOR_RATIOS = [0.5,1,2]

,所以一共有9种大小的Anchors,即k=9。Anchors的大小如下图所示:



写成坐标的形式为:

[[ -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.]]

原本中Anchors的stride为16,也就是Anchor以

步长16

在原图中滑动。对于一张1000*600的图像,总共大约有20000个anchors(≈60×40×9),如果忽略越过图像边界的anchor,在训练时每张图像总共有约6000个anchor。

由于标记为没有物体的anchor更多一些,所以在训练时随机取256个正样本和负样本为1:1的anchors。



如何确定一个anchor是正样本还是负样本?

一个anchor如果满足以下两个条件之一的被认为是

正样本



(i) 这个anchor和ground truth的方框有着最大的

IoU

重叠。

(ii) 这个anchor和ground truth的方框有

超过0.7



IoU

重叠。

一个anchor如果满足以下条件的被认为是

负样本



(i) 这个anchor和ground truth的方框的IoU重叠

小于0.3




既不是正样本也不是负样本的anchor在训练中不被使用。



实现细节

1.所有输入图像都被缩放成

短边600像素

(长边不超过1000像素)。

假设输入图像尺寸为354(宽)×480,会被缩放为600×814,(记为image_scale),然后按照[batch, height, width, channel]即[1, 814, 600, 3]的尺寸输入网络。

2.对于vgg16网络,输入图像会被映射成512维的特征图。

由vgg网络的代码(conv5层之前):

net = slim.repeat(self._image, 2, slim.conv2d, 64, [3, 3],
                  trainable=False, scope='conv1')
net = slim.max_pool2d(net, [2, 2], padding='SAME', scope='pool1')
net = slim.repeat(net, 2, slim.conv2d, 128, [3, 3],
                  trainable=False, scope='conv2')
net = slim.max_pool2d(net, [2, 2], padding='SAME', scope='pool2')
net = slim.repeat(net, 3, slim.conv2d, 256, [3, 3],
                  trainable=is_training, scope='conv3')
net = slim.max_pool2d(net, [2, 2], padding='SAME', scope='pool3')
net = slim.repeat(net, 3, slim.conv2d, 512, [3, 3],
                  trainable=is_training, scope='conv4')
net = slim.max_pool2d(net, [2, 2], padding='SAME', scope='pool4')
net = slim.repeat(net, 3, slim.conv2d, 512, [3, 3],
                  trainable=is_training, scope='conv5')

image_scale经过了4个池化层(卷积层由于有padding不会改变feature maps长和宽),所以得到的feature maps的尺寸为image_scale的

1/16

,也就是[1, 51, 38, 512]。

3.Anchors的个数为

51×38×9

(已知k=9)。

因此rpn网络

分类

的输出尺寸为[1, 51, 38, 18],其中后一半[:, :, :, 9:]表示正样本的概率,前一半[:, :, :, :9]表示负样本的概率。

而矩形框偏移

回归

的输出尺寸为[1, 51, 38, 36],(36=9×4),每个proposed region的4个参数是输出的矩形框(roi)相对于anchor进行平移缩放的4个系数。

rpn网络最终输出的矩形框位置是

anchor的位置



偏移位置

计算出来的,具体计算方式见参考资料。

由于roi网络输出的方框很多(51×38×9≈17000个),原文中的做法是先clip_boxes,即去掉与边界交叉的方框(剩下5000个左右的anchor),然后使用非极大值抑制(NMS)来去掉重叠的方框,最终只保留2000或300个方框(取决于训练还是测试)。


非极大值抑制(NMS)的原理



用普通话翻译一下非极大值抑制就是:

不是局部的最大值的那些值都滚蛋


由于score越大越接近期待值,因此将与score最大的方框IoU>0.7的都去除。

4.ROI pooling的详细过程。

将rpn输出的300个

大小不同

的方框从feature maps上对应的位置裁剪(crop)下来,然后缩放(resize)成14×14大小,这时候所有的方框可以表示为尺寸为[300, 14, 14, 512]的张量,再使用一个2×2的max_pool,得到的roi_pooling的结果尺寸为[300, 7, 7, 512]。

5.测试的详细过程。

测试过程中,输入的图像经过预测模型会输出[300 21]的分值以及[300 84]的方框位置。(设置网络保留300个方框,需要预测的种类为20类(pascal voc),加上背景一类)。

然后设定一个得分的阈值(比如0.95),大于该阈值的方框会被保留。如下图所示:




最后再使用一次NMS,对于多个重合的方框只保留一个。结果如下图所示:




调试信息

_image shape: (1, 814, 600, 3)
feature_maps shape: [  1  51  38 512]
rpn_cls_score shape: [ 1 51 38 18]  # 2k=18
rpn_bbox_pred shape: [ 1 51 38 36]  # 4k=36
rois shape: [300   5]  # [:,0]全是0
roi_pooling shape: [300   7   7 512]
cls_prob shape: [300  21]
bbox_pred shape: [300  84]



参考资料


https://github.com/endernewton/tf-faster-rcnn



https://web.cs.hacettepe.edu.tr/~aykut/classes/spring2016/bil722/slides/w05-FasterR-CNN.pdf



https://zhuanlan.zhihu.com/p/31426458



我的博客

如果这些内容对你有所帮助,可以关注我的博客哦~


http://www.xyu.ink/blog



版权声明:本文为MISADS原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。