深度学习目标检测之 R-CNN 系列:Faster R-CNN 网络详解
深度学习目标检测之 R-CNN 系列包含 3 篇文章:
- 深度学习目标检测之 R-CNN 系列: 从 R-CNN 和 Fast R-CNN 到 Faster R-CNN 总览
- 深度学习目标检测之 R-CNN 系列:Faster R-CNN 网络详解
- 深度学习目标检测之 R-CNN 系列:用 Faster R-CNN 训练自己的数据(caffe 版)
1. 前言
为了深入了理解 Faster R-CNN,这里建议参考 simple-faster-rcnn-pytorch 中的代码.
2. Faster R-CNN 网络概览
下图大致描述了 Faster R-CNN 的过程。
下面这幅图可能更清楚的表达了 Faster R-CNN 是如何工作的。只是需要注意的是下图是 test 网络。
更具体的过程可以参考下图。
-
- 将图片输入 CNN 网络(比如 ZF/VGG 等预训练好的分类模型),得到 feature maps;
-
- 将 feature maps 喂入 RPN(Region Proposal Network) 网络得到 region proposals (包含第一次回归)。更具体的,RPN 首先生成一堆Anchor box,对其进行裁剪过滤后通过 softmax 判断 anchors 属于前景(foreground)或者背景(background),即是不是物体,所以这是一个二分类任务;同时,另一分支 bounding box regression 修正(回归) anchor box,形成较精确的 proposal,注意这并是最后得到的 proposal,后面还会再进行第二次回归;
-
- 将上两步的输出:feature maps 和 region proposals 喂入 RoI Pooling 层得到统一 size 的 feature maps;
-
- 将 3 输出的 feature maps 输入全连接层,利用 Softmax 进行具体类别的分类,同时利用 L1 Loss 完成 bounding box regression 回归(第二次回归)操作获得物体的精确位置。
3. CNN
这里的 CNN 网络也可以叫做 conv layers,因为就是 conv + ReLU + Pooling 的组合,是没有 fc 层的。以 VGG16(13 个 conv + 3 个 fc) 为例,这里仅仅保留了其 13 个 conv 层,另外只保留了 4 个 Pooling 层,所以网络的 stride 为 16。
4. RPN
下图是 RPN 网络图,通过两个 1x1 的卷积层(conv)将 feature map 的 channel 分别变为 18 和 36,分别用来做分类和 bonding box 回归。这里面最为关键的 layer 就是 rpn-data,几乎所以核心的功能也都是在这个 layer 中完成。
RPN 网络具体的计算流程如下图所示。
总的来说,RPN 输入为 feature map, bbox 的标签(即训练集中所有物体的类别与 bbox 的位置),输出 proposal, 分类 loss,回归 loss。
值得注意的是这里预测的不是 bbox 的坐标,而是预测的相对于 Anchor 的偏移量。显然如果直接预测坐标,由于坐标变化幅度大,网络很难收敛与准确预测。
4.2 分类 loss
对于 RPN 而言就是一个二分类(前景和背景分类),采用的损失函数为交叉熵损失函数。
4.3 BBox 回归
假设我们对 anchor a 进行回归得到 predicated bbox p,那我们归一化的目标是希望 p 无限接近于 ground true(标记的结果)t。
在二维平面上,从矩形框 p 变换到矩形框 t,显然就是平移和缩放操作。假设 x , y , w , h x, y, w, h x,y,w,h 分别为 p 的中心坐标及宽和高; x a , y a , w a , h a x_a, y_a, w_a, h_a xa,ya,wa,ha 分别为 a 的中心坐标及宽和高; x ∗ , y ∗ , w ∗ , h ∗ x^*, y^*, w^*, h^* x∗,y∗,w∗,h∗ 分别为 t 的中心坐标及宽和高。那么从 p 到 a 的变换可以表示如下。
{ x = x a + ∇ x y = y a + ∇ y w = w a ⋅ ∇ w h = h a ⋅ ∇ h \left\{ \begin{aligned} & x = x_a +\nabla x\\ & y = y_a +\nabla y\\ & w = w_a \cdot \nabla w\\ & h = h_a \cdot \nabla h\\ \end{aligned} \right. ⎩⎪⎪⎪⎪⎨⎪⎪⎪⎪⎧x=xa+∇xy=ya+∇yw=wa⋅∇wh=ha⋅∇h
上面的 ∇ \nabla ∇ 部分都是基于 w , h w, h w,h 计算出来的,表示如下。
{