【目标检测】|fasterRCNN ROI Pooling原理 RPN输出

原理
https://blog.csdn.net/qq_35608277/article/details/80213663

目标检测architecture通常可以分为两个阶段:
(1)region proposal:给定一张输入image找出objects可能存在的所有位置。这一阶段的输出应该是一系列object可能位置的bounding box。这些通常称之为region proposals或者 regions of interest(ROI),在这一过程中用到的方法是基于滑窗的方式和selective search。
(2)final classification:确定上一阶段的每个region proposal是否属于目标一类或者背景。

这个architecture存在的一些问题是:
产生大量的region proposals 会导致performance problems,很难达到实时目标检测。
在处理速度方面是suboptimal。
无法做到end-to-end training。

ROI pooling提出的根本原因,ROI pooling层能实现training和testing的显著加速,并提高检测accuracy。该层有两个输入:

从具有多个卷积核池化的深度网络中获得的固定大小的feature maps;
一个表示所有ROI的N*5的矩阵,其中N表示ROI的数目。第一列表示图像index,其余四列表示其余的左上角和右下角坐标;
换个说法,实际上这部分输入就是rois:指的是RPN层的输出,一堆矩形框,形状为1x5x1x1(4个坐标+索引index),其中值得注意的是:坐标的参考系不是针对feature map这张图的,而是针对原图的(神经网络最开始的输入)。

ROI pooling具体操作如下:

根据输入image,将ROI映射到feature map对应位置;
将映射后的区域划分为相同大小的sections(sections数量与输出的维度相同);
对每个sections进行max pooling操作;

ROI Pooling的输出
输出是batch个vector,其中batch的值等于roi的个数,vector的大小为channelwh;ROI Pooling的过程就是将一个个大小不同的box矩形框,都映射成大小为w*h的矩形框;

这样我们就可以从不同大小的方框得到固定大小的相应 的feature maps。值得一提的是,输出的feature maps的大小不取决于ROI和卷积feature maps大小。ROI pooling 最大的好处就在于极大地提高了处理速度。

举例

举例:(数字是随意举例的,仅仅为了说明道理)
假设输入的ROI大小为8060,期望输出的ROI固定大小为106;
那么将输入的ROI(8060)划分为106块,即每块的大小为(80/10,60/6)。
对每一块分别进行最大或者最小Pooling操作,即得到了10*6的期望大小的输出ROI。

我们有一个88大小的feature map,一个ROI(57),以及输出大小为2*2. 则分成5/2,7/2

在这里插入图片描述
region proposal 投影之后位置(左上角,右下角坐标):(0,3),(7,8)。在这里插入图片描述
将其划分为(22)个sections(因为输出大小为22),我们可以得到:

说明:在此案例中region proposals 是57大小的,在pooling之后需要得到22的,所以在57的特征图划分成22的时候不是等分的,行是5/2,第一行得到2,剩下的那一行是3,列是7/2,第一列得到3,剩下那一列是4。在这里插入图片描述

在这里插入图片描述
对每个section做max pooling,可以得到:

在这里插入图片描述

RPN输出

分类

在这里插入图片描述

    # vgg16提取后的特征图,先进行3*3卷积
    # 3*3的conv,作为rpn网络 cfg.RPN_CHANNELS=512是卷积后的通道数
    rpn = slim.conv2d(net_conv, cfg.RPN_CHANNELS, [3, 3], trainable=is_training, weights_initializer=initializer,
                        scope="rpn_conv/3x3")
 
    # 每个框进行2分类,判断前景还是背景
    # 1*1的conv,得到每个位置的9个anchors分类特征[1,w,h,9*2],
    rpn_cls_score = slim.conv2d(rpn, self._num_anchors * 2, [1, 1], trainable=is_training,
                                weights_initializer=initializer,
                                padding='VALID', activation_fn=None, scope='rpn_cls_score')

在这里插入图片描述
然后进行reshape,拿一张图片举个例子,图片的shape是(W,H,D=18),然后我们会把他reshape以进行softmax(进行softmax的matrix的一边需要等于num of class,在这里是一个二分类,即是否含有物体,所以是2)。

所以我们会把(W,H,D)reshape成(2,9WH)。这里很重要!!!!对应的代码:

    # change it so that the score has 2 as its channel size
    # reshape成标准形式
    # [1,W,H,9*2]-->[1,9*W*H,2]  分类得分,每个点有9个anchors,每个anchors有2个得分
    rpn_cls_score_reshape = self._reshape_layer(rpn_cls_score, 2, 'rpn_cls_score_reshape')

然后我们进行softmax,得出对这9WH每一个的两个score,一个是有物体,一个是没有物体。对应的代码:

 # 每个anchors是正样本还是负样本。 以最后一维为特征长度,得到所有特征的概率[1,9*W*H,2]
    rpn_cls_prob_reshape = self._softmax_layer(rpn_cls_score_reshape, "rpn_cls_prob_reshape")
   
    # 每个位置的9个anchors预测的类别。得到每个位置的9个anchors预测的类别,[1,?,9,?]的列向量
    rpn_cls_pred = tf.argmax(tf.reshape(rpn_cls_score_reshape, [-1, 2]), axis=1, name="rpn_cls_pred")
 
    # 变换回原始纬度,[1,?*9.?,2]-->[1,?,?,9*2]
    rpn_cls_prob = self._reshape_layer(rpn_cls_prob_reshape, self._num_anchors * 2, "rpn_cls_prob")
 

回归


 
    # 1*1的conv,每个位置的9个anchors回归位置偏移[1,?,?,9*4]
    rpn_bbox_pred = slim.conv2d(rpn, self._num_anchors * 4, [1, 1], trainable=is_training,
                                weights_initializer=initializer,
                                padding='VALID', activation_fn=None, scope='rpn_bbox_pred')

在这里插入图片描述
https://blog.csdn.net/sxlsxl119/article/details/101288364

坐标计算‘

https://zhuanlan.zhihu.com/p/31426458
https://blog.csdn.net/zijin0802034/article/details/77685438

pytorch code

https://blog.csdn.net/Skies_/article/details/107339095

ref

https://blog.deepsense.ai/region-of-interest-pooling-explained/

https://blog.csdn.net/sxlsxl119/article/details/101288364

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值