Faster RCNN 中自定义 Python 层的作用理解

本文主要分析了 Faster RCNN 中 anchor_target_layer.py, proposal_target_layer.pyproposal_layer.py 三个自定义 python 层的代码。

训练阶段的主要网络结构

训练阶段的主要网络结构

测试阶段的主要网络结构

测试阶段的主要网络结构


proposal_layer.py (训练,测试阶段都有)

source
输入: score, bbox_deltas, im_info

  1. 生成 anchors, 利用预测得到的 bbox_deltas 作为输入,对所有的 anchors 作回归,得到 proposals. (注意,这里生成 anchors 的方式与训练时 anchor_target_layer.py 里一致)
  2. 对超出原图的 proposals 进行 clip, 筛除尺寸过小的 proposals.
  3. 根据输入的 scores 进行排序,选取前 N 个保留。(eg. 6000)
  4. 对剩下的 proposals 进行 nms,筛除一部分 proposals.
  5. 再根据 scores 排序,选取前一部分 proposals. (eg. 300)
  6. 输出 proposals

anchor_target_layer.py (仅在训练阶段)

source
输入: ‘rpn_cls_score’,‘gt_boxes’,‘im_info’, ‘data’
(1) 生成 所有的 anchors,记为 all_anchors,选出在图像内部的 anchor,记为 anchors.
(2) 生成与 1 步中 anchors 同尺寸的 labels,初始化为 -1.
(3) 计算 anchorsgt_boxes 的 IoU,得到 overlaps,得到每个 anchor 对应的 gt_box (IoU 最大).
(4) 根据 RPN 正负样本选取规则 1,将每个 gt_box 的 IoU 最大 anchor 的 label 置为 1.
(5) 根据 RPN 正负样本选取规则 2,将与任意 gt_box 的 IoU 大于某阈值的 anchor 的 label 置为 1. 将与所有 gt_box 的 IoU 小于某阈值的 achor 的 label 置为 0. 剩下的保留为 -1. 这样,就为每个 anchor 分配了标签。
(6) 根据正负样本的数量限制,将一部分正样本(label 为 1)置为 -1. 负样本同样。
(7) 计算 anchors 中每个 anchor 和 其对应的 gt_box 之间的 delta 作为 bbox_targets.
这样,上面计算得到的 labelsbbox_targets 其实就是 RPN 网络的 loss 的真值。
(8) 将得到的 anchorsbbox_targets unmap 回原来的 all_anchors 中。这样,所有生成的 anchors 都有一个类别标记(-1,0,1)和 bbox_targets. (在 all_anchors 不在 anchors 中的 anchor 的 bbox_target 用 0 填充。label 用 -1 填充。这样在计算 RPN loss 时不会计算此 anchor 的 loss.(-1 被忽略))。
(9) 将 all_anchorslabelsbbox_targets 输出,与预测的结果计算 rpn_loss.


proposal_target_layer.py (仅在训练阶段)

source
接受 proposal_layer.py 的输出(0, x1, y1, x2, y2) 和 gt_boxes (每个 GT box 的坐标和类别) (x1, y1, x2, y2, label)作为输入。

  1. 将输入的 rois 和 gt_boxes 合并 (vstack),形成总的 rois,记为 all_rois, 格式为(0, x1, y1, x2, y2), 共 M 个。
  2. 计算每个 roi 和每个 gt_box 的 IoU,形成一个 matrix,设 gt_boxes 共有 N 个,则尺寸为 M×NM\times N.
  3. 找到每个 roi 对应的 IoU 最大的 gt_box 的索引,并将此 gt_box 的类别赋给此 roi. 这样每个 roi 都有一个物体类别。
  4. 选择一些最大 IoU (最大 IoU 指 roi 与所有 gt_box 的 IoU 的最大值) 大于某阈值的 roi 作为 foreground,选择一些最大 IoU 在某区间内的 roi 作为 background。将作为 background 的 roi 的类别改为 0,用作最后 loss_cls 的计算。将 fg rois 和 bg rois 合并(vstack),作为一个输出。记为 rois,用作 ROI Pooling.
  5. 计算这些 rois (第4步获得)与其对应的 gt_boxes 之间的 delta 作为位置预测的目标,用来计算 loss_bbox. delta计算方法

2021/03/16:

  1. 这里,第一步将 gt_boxes 与 proposal_layer.py 输入的 rois 合并(vstack)是为了将 gt_boxes 作为 fg rois 参与后面的 loss 计算,因为每一个 gt_box 肯定会和自己本身的 IoU 为1,这样,就会被选作 fg roi, 进行后面的 loss 计算。
  2. 感觉这一步生成的 rois 作用类似于 RPN 中的 anchor。都要计算与其对应的 gt_box 之间的 delta 作为回归的真值。其类别也是由其对应的 gt_box 赋予的。

文章作者: taosean
文章链接: https://taosean.github.io/2018/11/06/Faster-RCNN-Python-layer/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 taosean's 学习之旅