原论文:《Faster R-CNN: Towards Real-Time Object
Detection with Region Proposal Networks》
代码:
- (Python) https://github.com/rbgirshick/py-faster-rcnn
- (Matlab) https://github.com/shaoqingren/faster_rcnn
关键点:RPN(区域候选网络,Region Proposal Networks)、anchor
Faster-RCNN 是对 Fast-RCNN 的改进,主要改进的方向是提高网络的计算速度。
Fast-RCNN 计算速度的瓶颈在于:使用 Selective Search 算法生成候选区域。这种算法无法利用GPU的计算优势。
Faster-RCNN 与 Fast-RCNN 的主要区别在于生成候选区域的方式不同:
Faster-RCNN 采用 RPN 生成候选区域,而Fast-RCNN 采用 Selective Search 算法生成候选区域,除此以外,其他基本相同。
准确来说,Faster-RCNN 中使用的目标检测器就是 Fast-RCNN。
下面分别是 Fast-RCNN 与 Faster-RCNN 的流程图。本文中仅着重记录 RPN 的相关信息。
RPN
- 输入:特征图(由特征提取器(CNN)在图片上得到)
- 输出:预测框距离真实框的偏移量(4个坐标)、目标物得分+背景得分
- 基本结构: 卷积神经网络
- 详细构造:一个 n × n n\times n n×n 的卷积网络,两个并列的全连接网络(分别用作框回归与分类)。这里, n = 3 n=3 n=3,两个全连接网络分别由 1 × 1 1\times1 1×1 的卷积网络构成。用于框回归的网络将会输出真实框相对锚框的偏移量,而借助这些偏移量及相应的锚框,我们就可以得到需要的候选区域。详情可以参考RPN(区域生成网络)
- 其他:这个网络的最后,使用NMS和top-N筛选了候选框。
Anchor(锚)
论文中对锚的定义:At each sliding-window location, we simultaneously predict multiple region proposals, where the number of maximum possible proposals for each location is denoted as
k
k
k. So the reg layer has
4
k
4k
4k outputs encoding the coordinates of
k
k
k boxes, and the cls layer outputs
2
k
2k
2k scores that estimate probability of object or not object for each proposal. The
k
k
k proposals are parameterized relative to
k
k
k reference boxes, which we call anchors. An anchor is centered at the sliding window in question, and is associated with a scale and aspect ratio. By default we use 3 scales and 3 aspect ratios, yielding
k
=
9
k=9
k=9 anchors at each sliding position. For a convolutional feature map of a size
W
×
H
W\times H
W×H (typically
∼
2
,
400
\sim2,400
∼2,400), there are
W
H
k
WHk
WHk anchors in total.
我的理解:原始图片与特征图是存在对应关系的,特征图上的每一点都在原始图片上存在对应的区域(感受野),这个区域的中心就可以作为一个锚点。进而可以围绕这个锚点在原始图片上构造
k
k
k 个矩形区域,这些矩形区域的尺寸及长宽比是可以由人工控制的超参数。这样,每个锚点都有会
k
k
k 个锚框(换句话说,每个特征点都在原图上被配给了
k
k
k 个框 )。
原论文里使用了三种尺寸及三种长宽比,即特征图上每个值负责预测
k
=
3
×
3
=
9
k=3\times3=9
k=3×3=9 个锚。
RPN 的损失函数:
L
(
{
p
i
}
,
{
t
i
}
)
=
1
N
c
l
s
∑
i
L
c
l
s
(
p
i
,
p
i
∗
)
+
λ
1
N
r
e
g
∑
i
p
i
∗
L
r
e
g
(
t
i
,
t
i
∗
)
L(\{p_i\},\{t_i\})=\frac{1}{N_{cls}}\sum_{i}L_{cls}(p_i,p_i^*)+\lambda\frac{1}{N_{reg}}\sum_{i}p_i^*L_{reg}(t_i,t_i^*)
L({pi},{ti})=Ncls1i∑Lcls(pi,pi∗)+λNreg1i∑pi∗Lreg(ti,ti∗)
其中,
- i i i 是锚在小批量样本中的索引值;
- p i p_i pi 是第 i i i 个锚作为一个对象的可能性或概率;
- p i ∗ p_i^* pi∗ 是真实的分类标签,且 p i ∗ = { 1 if anchor is positive 0 if anchor is negative p_i^*=\begin{cases} 1 & \text{if anchor is positive} \\ 0 & \text{if anchor is negative} \end{cases} pi∗={10if anchor is positiveif anchor is negative;
- t i t_i ti 是4维的向量,它表示预测的边界框的参数化坐标,即 ( t x , t y , t w , t h ) (t_x,t_y,t_w,t_h) (tx,ty,tw,th),具体情况可以参考下面的方程组,或者R-CNN的边界框回归;
- t i ∗ t_i^* ti∗ 也是4维的向量,但属于真实的背景框,它与正的锚(Positive Anchor)相关,即 ( t x , t y , t w , t h ) (t_x,t_y,t_w,t_h) (tx,ty,tw,th);
- L c l s L_{cls} Lcls 是二分类的对数似然损失函数;
- L r e g L_{reg} Lreg 是框回归的损失函数: L r e g ( t i , t i ∗ ) = R ( t i − t i ∗ ) L_{reg}(t_i,t_i^*)=R(t_i-t_i^*) Lreg(ti,ti∗)=R(ti−ti∗);
- R ( x ) R(x) R(x) 在 Fast-RCNN 的论文(即 s m o o t h L 1 smooth_{L_1} smoothL1 )中有定义:* s m o o t h L 1 = { 0.5 x 2 if ∣ x ∣ < 1 ∣ x ∣ − 0.5 otherwise smooth_{L_1}=\begin{cases} 0.5x^2 & \text{if } |x|<1 \\ |x|-0.5 & \text{otherwise} \end{cases} smoothL1={0.5x2∣x∣−0.5if ∣x∣<1otherwise;
- N c l s N_{cls} Ncls 在原论文里采用 mini-batch 的尺寸(256);
- N r e g N_{reg} Nreg 在原论文里采用 anchor 的数量( ≈ 2400 \approx 2400 ≈2400)
- λ = 10 \lambda=10 λ=10。
RPN 的输出为: { p i } \{p_i\} {pi}与 { t i } \{t_i\} {ti}。
使用下面的方式对每个框进行回归:
{
t
x
=
(
x
−
x
a
)
/
w
a
t
y
=
(
y
−
y
a
)
/
h
a
t
w
=
l
o
g
(
w
/
w
a
)
t
h
=
l
o
g
(
w
/
w
a
)
,
{
t
x
∗
=
(
x
∗
−
x
a
)
/
w
a
t
y
∗
=
(
y
∗
−
y
a
)
/
h
a
t
w
∗
=
l
o
g
(
w
∗
/
w
a
)
t
h
∗
=
l
o
g
(
w
∗
/
w
a
)
\begin{cases} t_x &= (x-x_a)/w_a \\ t_y &= (y-y_a)/h_a \\ t_w &= log(w/w_a)\\ t_h &= log(w/w_a) \\ \end{cases}, \begin{cases} t_x^* &= (x^*-x_a)/w_a \\ t_y^*&=(y^*-y_a)/h_a \\ t_w^* &= log(w^*/w_a) \\ t_h^* &= log(w^*/w_a) \end{cases}
⎩⎪⎪⎪⎨⎪⎪⎪⎧txtytwth=(x−xa)/wa=(y−ya)/ha=log(w/wa)=log(w/wa),⎩⎪⎪⎪⎨⎪⎪⎪⎧tx∗ty∗tw∗th∗=(x∗−xa)/wa=(y∗−ya)/ha=log(w∗/wa)=log(w∗/wa)
其中,
x
,
y
,
w
,
h
x,y,w,h
x,y,w,h 分别是框的中心坐标及框的宽高。
(
x
,
y
,
w
,
h
)
,
(
x
a
,
y
a
,
w
a
,
h
a
)
,
(
x
∗
,
y
∗
,
h
∗
,
w
∗
)
(x,y,w,h),(x_a,y_a,w_a,h_a),(x^*,y^*,h^*,w^*)
(x,y,w,h),(xa,ya,wa,ha),(x∗,y∗,h∗,w∗) 分别属于预测框、锚框、真实框。
这个操作是在用 t i t_i ti 拟合 t i ∗ t_i^* ti∗。
左右两边的方程组均可视为从一个框变换为另一个框的方法(平移+放缩):左边部分是从锚框变为实际框,右边部分是从锚框变为预测框。这部分可参考《(RegionProposal Network)RPN网络结构及详解》及《R-CNN(Regions with CNN features)学习笔记》
注意:
RPN 的输出为 { p i } \{p_i\} {pi}与 { t i } \{t_i\} {ti},它并不直接输出预测框的 x , y , w , h x,y,w,h x,y,w,h,所以在计算回归的损失函数时考虑的是 t i − t i ∗ \pmb{t}_i-\pmb{t}_i^* ttti−ttti∗。
也就是说,在训练时,是先计算出 t i ∗ \pmb{t}_i^* ttti∗,再通过优化损失函数 L r e g ( t i , t i ∗ ) L_{reg}(t_i,t_i^*) Lreg(ti,ti∗) 得到与预测框有关的 t i \pmb{t}_i ttti,再用左侧的方程组计算出具体的预测框。在Faster-RCNN与R-CNN/Fast-RCNN中,边界框回归目的不同之处:前者目的是用锚框生成候选候选区域,而后者是在矫正从Selective Search算法中得到的候选框。
代码中关于RPN网络的模型图,左侧用于测试,右侧用于端到端的训练。
工具是Netron。
补充说明:在右侧图的上侧,除了连接到直接连接到
Convolution
层的流程线以外,还有另外三个流程线,它们分别指向了Python
层、Python
层、ROIPooling
层,这三个流程线均来自data
层。
参考材料:
- R-CNN(Regions with CNN features)学习笔记
- Fast R-CNN 论文学习笔记
- Selective Search 论文学习笔记
- FCN 全卷积网络 Fully Convolutional Networks for Semantic Segmentation
- 从RCNN到SSD,这应该是最全的一份目标检测算法盘点
- 一文带你了解 Faster R-CNN
- RPN(区域生成网络)(推荐)
- (RegionProposal Network)RPN网络结构及详解
- 透彻理解RPN: 从候选区域搜索到候选区域提取网络(推荐)