faster RCNN RPN 数据生成部分学习记录

参考的代码注释理解https://blog.csdn.net/weixin_41693877/article/details/107059287

1.产生anchor

VGG16一共有5个pool层,我们选用第4个pool层的输出作为提取出来的特征图,这样相比于原图就缩小了16倍,即下采样倍数是16,输出特征图为原图的1/16。在这里插入图片描述
输入以(3×600×800),因此输出特征图(,512,37,50),相当于每一个特征点对应一个16x16的图像区域。并且以16x16大小的区域作为基础单位,以ratios=[0.5,1,2],scales=2**np.arange(3, 6),产生9个anchor。
在此引用参考链接的描述:
1.base_size=16
这个参数指定了最初的类似感受野的区域大小,因为经过多层卷积池化之后,feature map上一点的感受野对应到原始图像就会是一个区域,这里默认设置为16是因为使用了VGG16作为特征提取器,前面说了其下采样率为16,所以feature map上一点对应到原图的大小为16x16的区域。当然也可以根据不同的特征提取网络来设置。

2.ratios=[0.5,1,2]
这个参数指的是要将16x16的区域,按照1:2,1:1,2:1三种比例进行变换。

3.scales=2**np.arange(3, 6)
这个参数是要将输入的区域,的宽和高进行三种倍数,分别是8,16,32,
如16x16的区域变成(16∗8)∗(16∗8)=128∗128(16∗8)∗(16∗8)=128∗128的区域(16∗16)∗(16∗16)=256∗256(16∗16)∗(16∗16)=256∗256的区域,(16∗32)∗(16∗32)=512∗512(16∗32)∗(16∗32)=512∗512的区域。

2.网络结构

https://zhuanlan.zhihu.com/p/64723237在这里插入图片描述
RPN网络结构https://blog.csdn.net/weixin_41693877/article/details/107066700

经过RPN网络之后,得到两个预测分支,一个是对前景背景的预测得到输出为(,18,37,50),表示每个特征点对应9个anchor,每个anchor对应0-1两个值,0是背景,1是前景。
另外一个是对目标框位置的预测(,36,37,50)表示9个anchor相对于GT的偏移量(tx,ty,tw,th)4x9=36。

3训练标签的生成

(1)生成所有的anchor

首先需要将特征图的每一个特征点,映射到原图像上。特征图是(,18,37,50),尺寸是原图的1/16,所以每一个特征点对应一个16x16的区域。在特征图上为(0,0)位置的特征点,对应原图
(0,0,16,16)前两个为左上角坐标,后两个为右下角坐标。在这里插入图片描述
每一个特征点,对应原图一个偏移量,需要将每个特征点对应的9个anchor平移到原图对应的区域。

		# 生成锚框坐标的移动量
        feat_height, feat_width = rpn_cls_score.size(2), rpn_cls_score.size(3) # [0, 16, 32, ...., 784]
        shift_x = np.arange(0, feat_width) * self._feat_stride                   # [0, 16, 32, ...., 576]
        shift_y = np.arange(0, feat_height) * self._feat_stride
        shift_x, shift_y = np.meshgrid(shift_x, shift_y)
           # x = [[0, 16, 32, ...., 784], [0, 16, 32, ...., 784],...., [0, 16, 32, ...., 784]] 
        # y = [[0, 0, 0, ....., 0], [16, 16, ...., 16], ....,[576, 576, ...., 576]]
        # 利用numpy首先得到锚框每个坐标的移动量,并利用contiguous保证内存连续
        shifts = torch.from_numpy(np.vstack((shift_x.ravel(), shift_y.ravel(),
                                  shift_x.ravel(), shift_y.ravel())).transpose())
        # shifts = [[0, 0, 0, 0], [16, 0, 16, 0], .....[784, 576, 784, 576]]
        #生成的9个anchor是一个绝对量大小,现在要将他们移动到原图上,就需要一个平移量,
        #比如特征图上(0,0)的点对应的9个anchor,是大小为(16*16)的框产生的,直接对应在原图大小上(0,0,16,16,)区域,不需要平移,直接对应到原处,所以平移的大小是(0,0,0,0)
        #特征图上是(0,1)的点对应的9个anchor,是(16*16)产生的,对应在原图大小上(16,0,32,16)区域,相对于原点的(0,0,16,16,)区域,需要将9个anchor平移到原图对应区域,加上偏移量(16,0,16,0),
        #特征图一个点对应一个16*16的区域,anchor是以16*16大小的框为基本生成的9个anchor,9个anchor要对应到原图上每一个16*16的区域,所以尽行平移。
        shifts = shifts.contiguous().type_as(rpn_cls_score).float()

        A = self._num_anchors  # 每个特征点锚框的数量, 数量为9
        K = shifts.size(0)   # 特征点的数量, 数量为1850

        # 调用基础anchor加上偏移量生成所有anchors
        self._anchors = self._anchors.type_as(gt_boxes) # move to specific gpu.
        all_anchors = self._anchors.view(1, A, 4) + shifts.view(K, 1, 4)
        all_anchors = all_anchors.view(K * A, 4)  # 修改形状,(16650, 4)

由 第一部分 可知,anchor是在原图16x16区域大小的基础上,进行变换产生的9个固定大小的框,
若是出于边界的特征点,则在原图上对应的anchor,会有出界的情况,此类框要滤除。

shifts = torch.from_numpy(np.vstack((shift_x.ravel(), shift_y.ravel(),
                                  shift_x.ravel(), shift_y.ravel())).transpose())

在这里插入图片描述
在这里插入图片描述
将基本的anchor加上偏移量,对应原图区域

all_anchors = self._anchors.view(1, A, 4) + shifts.view(K, 1, 4)
#all_anchors = self._anchors.view(1, 9, 4) + shifts.view(1850, 1, 4)

在这里插入图片描述
在这里插入图片描述
最后每一个特征点得到自己的对应区域。

keep = ((all_anchors[:, 0] >= -self._allowed_border) &
                (all_anchors[:, 1] >= -self._allowed_border) &
                (all_anchors[:, 2] < long(im_info[0][1]) + self._allowed_border) &
                (all_anchors[:, 3] < long(im_info[0][0]) + self._allowed_border))

在这里插入图片描述
这里是对得到的所有anchor进行处理,删除范围在原图之外的。
以all_anchors[:, 0] >= -self._allowed_border 为例,每个条件得到一个(1*16650)的向量,表示此生成框的真假,符合四个条件的框即为有效框。

(2)匹配标签与anchor

在除去边界不符合条件的基础上,将剩余的anchor与所有的真值进行IOU计算,#生成IoU矩阵,每一行代表一个anchor,每一列代表一个标签。

  1. 对于任何一个Anchor, 与所有标签的最大IoU小于0.3, 则视为负样本。
  2. 对于任何一个标签, 与其有最大IoU的Anchor视为正样本。
  3. 对于任何一个Anchor, 与所有标签的最大IoU大于0.7, 则视为正样本
    根据这样的规则,选定对应的anchor,正样本为1,负样本为0
    另外,生成的anchor特别多,根据需要进行抽选,最后 生成标签向量,对应每一个anchor的状态,1为正,0为负,初始化为-1。label与anchor尺度对应。

(3)求解回归真值

前面第二步在真实边框与锚框匹配时,已经将每个Anchor赋予正样本或者负样本代表了预测类别的真
值,当然锚框的标签属于负样本的话。是不参与计算回归损失的。现在我们需要知道那些标签为正样本的锚框与真实边框的偏移值,以便后面计算回归损失。

得到偏移量的真值后,将其保存在bbox_targets中。与此同时, 还需要求解两个权值矩阵bbox_inside_weights和bbox_outside_weights,前者是用来设置正样本回归的权重,正样本设置为1,负样本设置为0,因为负样本对应的是背景, 不需要进行回归; 后者的作用则是平衡RPN分类损失与回归损失的权重,在此设置为1/256。

理解的不全面,还需要继续深入。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值