RPN网络
首先经过一个3 ∗ * ∗ 3的卷积层,然后兵分两路:
- foreground anchors
- bounding box regression偏移量
可以看到RPN网络实际分为2条线,上面一条通过softmax分类anchors获得foreground和background(检测目标是foreground),下面一条用于计算对于anchors的bounding box regression偏移量,以获得精确的proposal。而最后的Proposal层则负责综合foreground anchors和bounding box regression偏移量获取proposals,同时剔除太小和超出边界的proposals。其实整个网络到了Proposal Layer这里,就完成了相当于目标定位的功能。
anchor和foreground与background的判定
首先介绍一下anchor,特征提取最后输出的feature map中,每一个cell都对应了9个不同尺寸的anchor,这些anchor的比例为(1:1)(1:2)(2:1)而且这些anchor的size是根据检测图像设置的。
这样的话。这些anchor可以覆盖了整个检测图像。根据源代码可以看出,输入图片会被resize成800
∗
*
∗ 600的大小。
RPN层先经过3
∗
*
∗ 3的卷积层,这样使得该点又可以融合周边几个点的信息,增强鲁棒性。并且,全部anchors拿去训练太多了,训练程序会在合适的anchors中随机选取128个postive anchors+128个negative anchors进行训练
MxN大小的矩阵送入Faster RCNN网络后,到RPN网络变为(M/16)x(N/16),不妨设 W=M/16,H=N/16。在进入reshape与softmax之前,先做了1x1卷积,
为何要在softmax前后都接一个reshape layer?其实只是为了便于softmax分类。对应至上面的保存bg/fg anchors的矩阵,其在caffe blob中的存储形式为[1, 2x9, H, W]。而在softmax分类时需要进行fg/bg二分类,所以reshape layer会将其变为[1, 2, 9xH, W]大小,即单独“腾空”出来一个维度以便softmax分类,之后再reshape回复原状。
bounding box regression
这部分直接贴公式吧,已经看了很多遍了
如何通过线性回归获得
为了让预测值(tx,ty,tw,th)与真实值差距最小
优化目标:
Proposal Layer
Proposal layer输入三个参数:(dx(A),dy(A),dw(A),dh(A)),foreground anchors,im-info[M, N, scale_factor](保存此次缩放信息)
它的处理步骤:
- 生成anchors,利用(dx(A),dy(A),dw(A),dh(A))对所有anchors做bbox regression回归(这里的anchors生成和训练时完全一致)
- 按照输入的foreground softmax scores由大到小排序anchors,提取前pre_nms_topN(e.g. 6000)个anchors,即提取修正位置后的foreground anchors。
- 限定超出图像边界的foreground anchors为图像边界(防止后续roi pooling时proposal超出图像边界)
- 剔除非常小(width<threshold or height<threshold)的foreground anchors
进行nonmaximum suppression - 再次按照nms后的foreground softmax scores由大到小排序fg anchors,提取前post_nms_topN(e.g. 300)结果作为proposal输出。
总之,RPN网络是个二分类+bbox regression的网络,它的二分类在于把背景和前景分开,然后输出有大量前景的bbox。有一些面试会问到,RPN可以单独使用么,我觉得如果单独使用的话,首先bbox不会很精准,其次他没有对物体分类的作用,因为它只能把背景剔除。如果没有RPN的话,它会怎样呢?
- 网络会对所有的anchor定的region进行识别分类,这会使得网络难以收敛,因为有太多“背景”的region,他们对于类的预测没有任何贡献
- 大量无用的region会非常消耗计算时间
yolo有类似rpn的机制,那就是最后输出时的confidence值,这个值决定了前景和背景。
ssd是将anchor机制融合在了1 stage模型中,原理与本文所述基本一致。
ROI Pooling 层
Rol pooling层有2个输入:原始的feature maps和RPN输出的proposal boxes(大小各不相同)。
由于ROI Pooling层之后是全连接层,输入的大小要固定,但是生成的proposal大小不一致,所以需要ROI Pooling层。RoI Pooling layer forward过程:在之前有明确提到: 是对应MxN尺度的,所以首先使用spatial_scale参数将其映射回(M/16)x(N/16)大小的feature maps尺度;之后将每个proposal水平和竖直分为pooled_w和pooled_h份,对每一份都进行max pooling处理。这样处理后,即使大小不同的proposal,输出结果都是一样大小,实现了fixed-length output(固定长度输出)。
训练RPN网络
损失函数:
上述公式中 i 表示anchors index,
P
i
Pi
Pi表示foreground softmax probability,
P
i
Pi
Pi*
表示对于GT predict概率,(即当第i个anchor与GT间 IoU>0.7,认为是该anchor是foreground,
P
i
Pi
Pi*=1;反之 IoU<0.3 时,认为是该anchor是background,
P
i
Pi
Pi*=0;至于那些 0.3<IoU<0.7 的anchor则不参与训练);t代表predict bounding box,t*代表对应foreground anchor对应的GT box。
由于在实际过程中,
N
c
l
s
N_{cls}
Ncls和
N
r
e
g
N_{reg}
Nreg差距过大,用参数
λ
λ
λ平衡二者(如
N
c
l
s
N_{cls}
Ncls=256,
N
r
e
g
N_{reg}
Nreg=2400时设置
λ
λ
λ=10 ),使总的网络Loss计算过程中能够均匀考虑2种Loss。
smooth L1损失函数
L
r
e
g
L_{reg}
Lreg使用的soomth L1 loss,计算公式如下:
特别需要注意的是,在训练和检测阶段生成和存储anchors的顺序完全一样,这样训练结果才能被用于检测!
关于为何使用smooth L1损失函数,fast rcnn有一句话是:L1 loss that is less sensitive to outliers than the L2 loss used in R-CNN and SPPnet.它使得loss对于离群点更为鲁棒,L2的话它对离群点,异常值更敏感,容易发生梯度爆炸。而smooth是L1和L2损失函数的结合。