FasterRcnn原理理解记录

  • fasterRcnn总的结构图
    总体结构

    图1

    从图1可以看到,faster Rcnn的总体结构由以下几个部分组成:

    1. Conv layers
    2. Region Proposal Networks(RPN)
    3. RoI pooling
    4. Classification
    5. Faster RCNN训练
  • 1. conv layeres—特征提取
    这里可采用预训练好的、精度高的、或者参数少的模型,如:resnet101,50,vgg16,等网络。
    假设图像原来的尺寸为M×N,一个MxN大小的矩阵经过Conv layers固定变为(M/16)x(N/16),这是conv layeres在特征提取的时候,采用同尺寸卷积,采用4层最大值池化操作。.经过conv layeres之后得到一个batchsize×3×(M/16)x(N/16)的矩阵。
    conv layer的特征图,再分别与进行两次卷积运算,卷积参数为:

    self.m1 = nn.Conv2d(n, 18, 3, 1, 1)
    self.m2 = nn.Conv2d(n, 36, 3, 1, 1)

得到batchsize*18*(M/16)(N/16)和batchsize*36(M/16)*(N/16)的两个矩阵,前面为RPN得到的分类结果(只有前景和目标两类+忽略类),后面的矩阵为9×4×(M/16)×(N/16)anchor中目标的坐标。

  • 2. Region Proposal Networks(RPN)—候选区域生成

2.1 生成以128为基础的,比例为[1:0.5, 1:1, 0.5:1]的9个不同尺寸的anchors。目的:为了适应不同形状的物体设计的。9个anchors的具体数值为:

#    anchors =
#
#       -83   -39   100    56
#      -175   -87   192   104
#      -359  -183   376   200
#       -55   -55    72    72
#      -119  -119   136   136
#      -247  -247   264   264
#       -35   -79    52    96
#       -79  -167    96   184
#      -167  -343   184   360

2.2 将特征图中(M/16)×(N/16)的区域映射回原图的尺寸,就是把特征图上的坐标×16倍,16为conv layer缩小的尺寸。

shift_x = np.arange(0, width) * self._feat_stride             # 24*32,_feat_stride就是缩放的比例16
shift_y = np.arange(0, height) * self._feat_stride            # 24*32
shift_x, shift_y = np.meshgrid(shift_x, shift_y)
shifts = np.vstack((shift_x.ravel(), shift_y.ravel(),
                    shift_x.ravel(), shift_y.ravel())).transpose()

2.3 将2.2中返还回原图坐标系的每个坐标+2.1中的anchors,则可以得到9×(M/16)×(N/16)个候选框all_anchor

all_anchors = (self._anchors.reshape((1, A, 4)) +
               shifts.reshape((1, K, 4)).transpose((1, 0, 2)))      # 一个1×9×4矩阵+768×1×4的矩阵,得到768×9×4
all_anchors = all_anchors.reshape((K * A, 4))    

2.4 为计算RPN的loss,则要计算1 conv layer中输出batchsize*18*(M/16)(N/16)和batchsize*36(M/16)*(N/16)的两个矩阵的目标label和target_box

2.5 利用原图的尺寸对all_anchor进行尺寸约束

2.6 计算all_anchor中每个anchor与图片中目标的重合率。这里为了好理解,以一张输入图片为例,图片中可以含有1个或多个目标。输出nanchors×k的矩阵 k为目标的个数
重合率计算可参考:https://www.cnblogs.com/dudumiaomiao/p/6560841.html

2.7 计算每个anchor与目标的最大重合率max_overlap, 如果max_overlap<0.3,则认为是背景,如果max_overlap>0.7则认为是目标。同时,为了以防万一,将与每个目标重合最大anchor也设为目标类。

labels[max_overlaps < self.negative_overlap] = 0            # 一个anchor和所有的gt_box重合率都小于0.7时,为背景

# fg label: for each gt, anchor with highest overlap
labels[gt_argmax_overlaps] = 1                              # 每一个gt_box重合最大的为目标

# fg label: above threshold IOU
labels[max_overlaps >= self.positive_overlap] = 1           # 就是和目标区域重合较大的置为1

2.8 如果背景类和目标类太多,则进行下采样,就是舍弃一些类,将类别设为-1。(这里不知道为啥)

2.9 将每个anchor与每个目标重合最大的那个目标设为target_box

2.10 最后得到的label就是一个nanchor×1的矩阵,其中的数值为[-1,0,1]中的一类,-1表示舍弃的,0表示背景类,1表示目标类。target_box为每个anchor的回归/修正系数。所以RPN中batchsize*36*(M/16)*(N/16)为回归/修正系数,并不是anchor的坐标。
矩形的回归修正系数求解可参考:https://www.cnblogs.com/dudumiaomiao/p/6560841.html

2.11 计算RPN的loss,交叉熵和L1loss。但是这里有两个疑问:1. 值为-1的label也输入交叉熵的计算了,不会参数计算吗?2. 有些-1的target_box不为[0 0 0 0]不会产生误差吗?

  • 3. Proposal Layer 参考的:https://blog.csdn.net/hellor123/article/details/75676314
    Proposal Layer有3个输入:fg/bg anchors分类器结果rpn_cls_prob_reshape,对应的bbox reg的[dx(A),dy(A),dw(A),dh(A)]变换量rpn_bbox_pred,以及im_info;另外还有参数feat_stride=16。

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

  1. 再次生成anchors,并对所有的anchors做bbox reg位置回归(注意这里的anchors生成顺序和之前是即完全一致的)
  2. 按照输入的foreground softmax scores由大到小排序anchors,提取前pre_nms_topN(e.g. 6000)个anchors。即提取修正位置后的foreground anchors
  3. 利用feat_stride和im_info将anchors映射回原图,判断fg anchors是否大范围超过边界,剔除严重超出边界fg anchors。
  4. 进行nms(nonmaximum suppression,非极大值抑制)
  5. 再次按照nms后的foreground softmax scores由大到小排序fg anchors,提取前post_nms_topN(e.g. 300)结果作为proposal输出。

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

RPN网络结构就介绍到这里,总结起来就是:
生成anchors -> softmax分类器提取fg anchors -> bbox reg回归fg anchors -> Proposal Layer生成proposals

猜你喜欢

转载自blog.csdn.net/u011622208/article/details/81415079
今日推荐