Faster R-CNN: Towards Real-Time Object Detection with Region Proposal Networks! |
从R-CNN到Fast RCNN,再到本文的Faster R-CNN,目标检测的四个基本步骤 (1.候选区域生成,2.特征提取,3.分类,4.位置精修)终于被统一到一个深度网络框架之内。所有计算没有重复,完全在GPU中完成,大大提高了运行速度。
Faster R-CNN统一的网络结构如下图所示,可以简单看作RPN网络+Fast R-CNN网络。
注意:上图Fast R-CNN中含特有卷积层,我认为不是所有卷积层都参与共享。具体步骤如下:
|
|
---|
对于这 51 × 39 51×39 51×39个位置和 51 × 39 × 9 51×39×9 51×39×9个anchor,下图展示了接下来每个位置的计算步骤:
如下图所示绿色框为飞机的Ground Truth(GT),红色为提取的foreground anchors,即便红色的框被分类器识别为飞机,但是由于红色的框定位不准,这张图相当于没有正确的检测出飞机。所以我们希望采用一种方法对红色的框进行微调,使得foreground anchors和GT更加接近。
对于窗口一般使用四维向量 ( x , y , w , h ) (x, y, w, h) (x,y,w,h) 表示,分别表示窗口的中心点坐标和宽高。
我们使用 A A A 表示原始的foreground anchor,使用 G G G 表示目标的ground truth,我们的目标是寻找一种关系,使得输入原始的Anchor A经过映射到一个和真实框 G G G更接近的回归窗口 G ′ G^{\prime} G′,即:
那么经过何种变换 F F F才能从图10中的 a n c h o r anchor anchor A A A变为 G ′ G' G′ 呢? 比较简单的思路就是:
先做平移
G x ′ = A x + A w ⋅ d x ( A ) G y ′ = A y + A h ⋅ d y ( A ) \begin{aligned} G_{x}^{\prime} &=A_{x}+A_{w} \cdot d_{x}(A) \\\\ G_{y}^{\prime} &=A_{y}+A_{h} \cdot d_{y}(A) \end{aligned} Gx′Gy′=Ax+Aw⋅dx(A)=Ay+Ah⋅dy(A)
再做缩放
G w ′ = A w ⋅ exp ( d w ( A ) ) G h ′ = A h ⋅ exp ( d h ( A ) ) \begin{array}{l}{G_{w}^{\prime}=A_{w} \cdot \exp \left(d_{w}(A)\right)} \\\\ {G_{h}^{\prime}=A_{h} \cdot \exp \left(d_{h}(A)\right)}\end{array} Gw′=Aw⋅exp(dw(A))Gh′=Ah⋅exp(dh(A))
上面4个公式中,我们需要学习4个参数,分别是 d x ( A ) , d y ( A ) , d w ( A ) , d h ( A ) d_{x}(A),d_{y}(A),d_{w}(A),d_{h}(A) dx(A),dy(A),dw(A),dh(A) ,当输入的anchor A与GT相差较小时,可以认为这种变换是一种线性变换, 那么就可以用线性回归来建模对窗口进行微调 (注意,只有当anchors A和GT比较接近时,才能使用线性回归模型,否则就是复杂的非线性问题了)。
接下来的问题就是如何通过线性回归获得 d x ( A ) , d y ( A ) , d w ( A ) , d h ( A ) d_{x}(A),d_{y}(A),d_{w}(A),d_{h}(A) dx(A),dy(A),dw(A),dh(A) 了。线性回归就是给定输入的特征向量 X X X, 学习一组参数 W W W, 使得经过线性回归后的值跟真实值 Y Y Y 非常接近,即 Y = W X Y=WX Y=WX。对于该问题,输入 X X X 是cnn feature map,定义为 Φ Φ Φ;同时还有训练传入A与GT之间的变换量,即 ( t x , t y , t w , t h ) (t_{x}, t_{y}, t_{w}, t_{h}) (tx,ty,tw,th) 。输出是 d x ( A ) , d y ( A ) , d w ( A ) , d h ( A ) d_{x}(A),d_{y}(A),d_{w}(A),d_{h}(A) dx(A),dy(A),dw(A),dh(A) 四个变换。那么目标函数可以表示为:
d ∗ ( A ) = w ∗ T ⋅ ϕ ( A ) d_{*}(A)=w_{*}^{T} \cdot \phi(A) d∗(A)=w∗T⋅ϕ(A)
其中 ϕ ( A ) \phi(A) ϕ(A)是对应anchor的feature map组成的特征向量, W ∗ W_* W∗ 是需要学习的参数, d ∗ ( A ) d_*(A) d∗(A) 是得到的预测值( ∗ * ∗ 表示 x , y , w , h , x,y,w,h, x,y,w,h,也就是每一个变换对应一个上述目标函数)。为了让预测值 d ∗ ( A ) d_*(A) d∗(A) 与真实值 t ∗ t_* t∗ 差距最小,设计损失函数:
loss = ∑ i = 1 N ( t ∗ i − w ^ ∗ T ⋅ ϕ ( A i ) ) 2 \operatorname{loss} =\sum_{i=1}^{N}\left(t_{*}^{i}-\hat{w}_{*}^{T} \cdot \phi\left(A^{i}\right)\right)^{2} loss=i=1∑N(t∗i−w^∗T⋅ϕ(Ai))2
函数优化目标为:
W ^ ∗ = argmin W ∗ ∑ i n ( t ∗ i − W ∗ T ⋅ ϕ ( A i ) ) 2 + λ ∥ W ∗ ∥ 2 \hat{W}_{*}=\operatorname{argmin}_{W_{*}} \sum_{i}^{n}\left(t_{*}^{i}-W_{*}^{T} \cdot \phi\left(A^{i}\right)\right)^{2}+\lambda\left\|W_{*}\right\|^{2} W^∗=argminW∗i∑n(t∗i−W∗T⋅ϕ(Ai))2+λ∥W∗∥2
需要说明,只有在GT与需要回归框位置比较接近时,才可近似认为上述线性变换成立。说完原理,对应于Faster RCNN原文,foreground anchor与ground truth之间的平移量 ( t x , t y ) (t_x, t_y) (tx,ty)与尺度因子 ( t w , t h ) (t_w, t_h) (tw,th) 如下:
t x = ( x − x a ) / w a t y = ( x − y a ) / h a t w = log ( w / w a ) t h = log ( h / h a ) \begin{array}{c}{t_{x}=\left(x-x_{a}\right) / w_{a} \quad t_{y}=\left(x-y_{a}\right) / h_{a}} \\\\ {t_{w}=\log \left(w / w_{a}\right) \quad t_{h}=\log \left(h / h_{a}\right)}\end{array} tx=(x−xa)/waty=(x−ya)/hatw=log(w/wa)th=log(h/ha)
对于训练bouding box regression网络回归分支,输入是cnn feature Φ Φ Φ,监督信号是Anchor与GT的差距 ( t x , t y , t w , t h ) (t_x, t_y, t_w, t_h) (tx,ty,tw,th),即训练目标是:输入 Φ Φ Φ 的情况下使网络输出与监督信号尽可能接近。那么当bouding box regression工作时,再输入 Φ Φ Φ 时,回归网络分支的输出就是每个Anchor的平移量和变换尺度 ( t x , t y , t w , t h ) (t_x, t_y, t_w, t_h) (tx,ty,tw,th),显然即可用来修正Anchor位置了。
在得到每一个候选区域 a n c h o r anchor anchor A A A 的修正参数 ( d x ( A ) , d y ( A ) , d w ( A ) , d h ( A ) ) (dx(A),dy(A),dw(A),dh(A)) (dx(A),dy(A),dw(A),dh(A))之后,我们就可以计算出精确的 a n c h o r anchor anchor,然后按照物体的区域得分从大到小对得到的 a n c h o r anchor anchor 排序,然后提出一些宽或者高很小的 a n c h o r anchor anchor (获取其它过滤条件),再经过非极大值抑制抑制,取前Top-N的 a n c h o r s anchors anchors,然后作为 p r o p o s a l s proposals proposals (候选框)输出,送入到RoI Pooling层。
RoI Pooling层负责收集所有的候选框,并计算每一个候选框的特征图,然后送入后续网络,从Faster RCNN的结构图我们可以看到RoI Pooling层有两个输入:
先来看一个问题:对于传统的CNN(如AlexNet,VGG),当网络训练好后输入的图像尺寸必须是固定值(全连接层的限制,具体的解释可以参考我这篇文章:论文阅读笔记:(SSPNet)),同时网络输出也是固定大小的vector or matrix。如果输入图像大小不定,这个问题就变得比较麻烦。有2种解决办法:
我们把每一个候选框的特征图水平和垂直分为pooled_w(文章中为7)和pooled_h(7)份,对每一份进行最大池化处理,这样处理后,即使大小不一样的候选区,输出大小都一样,实现了固定长度的输出:
通过RoI Pooling层我们已经得到所有候选区组成的特征向量,然后送入全连接层和softmax计算每个候选框具体属于哪个类别,输出类别的得分;同时再次利用框回归获得每个候选区相对实际位置的偏移量预测值,用于对候选框进行修正,得到更精确的目标检测框。
Faster R-CNN的训练,是在已经预训练好的model(如VGG_CNN_M_1024,VGG,ZF)的基础上继续进行训练。实际中训练过程分为6个步骤:详细参考知乎大神的博客!
本文参考了许多优秀作者的文章,虽然有些具体细节还没有搞懂,下一步阅读代码,在这里表示衷心的感谢!