目标检测综述-从RCNN到Mask-RCNN
存货, 介绍了RCNN系列的发展历史以及基本理念
RCNN
预测
Rich feature hierarchies for accurate object detection and semantic segmentation(2013)
-
Selective Search 生成大约2000个 Region Proposals, 这是category-independent的, 也就是只有object/background之分
-
特征提取:
- 将Region Proposals切割的图片缩放(crop/warp) 到固定尺寸(227*227)
- 通过(Alexnet) 生成4096维特征向量
-
对每一类:
- 通过$k$个SVM(二分类), 输出属于各个类的score
- 给出score和proposal之后, 对每一类用non-maximum suppresion over a learned threshold来去重
-
通过训练好的LR模型Bounding Box Regression对proposal进行精修
训练
- 载入ILSVRC2012上预训练的Alexnet
- 训练(Fine-Tune)CNN:
- 数据: region proposals切割好的图片
- 模型: 将网络最后一层改为$R^{N+1}$层, 代表了N+1(背景)类
- IoU > 0.5是正样本, 否则是负样本(第N+1类)
- 优化: SGD, batch大小为128, 每个batch中正负样本比为1/3, 学习率为预训练的1/10
- 训练 SVM:
- 正样本: Ground Truth 通过CNN的特征向量
- 负样本: IoU < 0.3 的proposal通过CNN的特征向量
- 训练LR进行Bounding Box Regression
- 输入: CNN输出的4096维向量
- 正样本: 计算出bbox delta
备注
Q: 为何不用Fine-tune的时候的CNN直接检测物体类别? 最后一层不就是softmax分类器吗? A: 因为准确率低, 为了获得充足的样本训练CNN, IoU阈值(>0.5)取得比较低, 检测出来的物体往往不包含整个样本. 将提取出来的特征给SVM并用更严格的策略(Ground Truth为正样本, <0.3为负样本, 其他丢弃, 这是验证集测试mAP出来的结果)来判断包括物体的bbox, 效果更好. 因为SVM适合小样本训练.
Q: 什么是Bounding Box Regression? A: 有四个模型, 两个是回归坐标的, 两个是回归长宽的. 输入是CNN提取Regional Proposals的特征向量, 输出是四种model要回归的目标中的一个: $$ \begin{aligned} \hat G_x &= P_w d_x(P) + P_x \\ \hat G_y &= P_h d_y(P) + P_y \\ \hat G_w &= P_w \exp(d_w(P)) \\ \hat G_h &= P_h \exp(d_h(P)) \\ \end{aligned} $$
Q: 什么是Hard negative mining? A: rcnn中的Hard negative mining方法是如何实现的
SPPNet
Spatial Pyramid Pooling in Deep Convolutional Networks for Visual Recognition(2014/6) SPPNet主要做了两件事:
-
从特征图上裁剪ROI
- 在RCNN里, 通过Selective Search生成2000个Region Proposals, 然后crop/warp, 再喂进CNN, 太慢
- 在SPPNet里, 将整张图片喂进CNN, 然后从特征图上直接裁剪出ROI. 这样只需要一次前向传播, 比之前要2000次快得多
-
提出Spatial Pyramid Pooling Layer(SPP Layer)解决了把不同尺度的feature map转换为一个尺度的方案, 不再需要crop/warp了:
- 将feature map按不同维度划分并max pooling
- 拼接各个维度的输出, 产生固定维度的输出
-
训练上, 由于可以输入任何尺寸的图片, 所以是分几个阶段用不同分辨率的图训练的. 其他细节看这篇专栏吧….
Fast RCNN
Fast R-CNN(2015/4)
预测
- Selective Search 生成大约2000个 Region Proposals, 和RCNN一样
- 特征提取:
- 将图片输入CNN, 得到特征图
- 用Region Proposals直接从特征图上得到切割过的特征
- 使用ROI pooling layer得到特征向量, 所以从Fast RCNN开始, 训练和预测对图片的尺寸没有要求了
- 特征向量 -> FC1 -> SoftMax Probability ($K+1$)
- 特征向量 -> FC2 -> bbox offsets ($4 \times K$)
- 对每一类用nms得到最终结果
训练
- 预训练CNN (Imagenet):
- 将最后一层pooling layer换成ROI pooling layer
- 将最后一个全连接层换成两个并行的全连接层FC1, FC2
- 网络需要同时输入图片和ROI
- 同时训练bbox regressor和softmax分类器
- bbox regressor用Smooth L1损失函数
- Softmax for probability
- 将两个损失相加之后回传
- 一个Mini-Batch中重采样正负样本:
- 一个batch包含两张图
- 每张图贡献64个ROI, 一共128个
- 正样本: IoU>0.5
- 负样本: IoU $\in$ [0.1, 0.5) (hard negative mining)
Notes
- ROI pooling: 其实就是单层SPP layer, 详细机制参考region-of-interest-pooling-explained
- 原始图片中的ROI如何映射到到feature map?这坑挺深的
Faster RCNN
Faster R-CNN: Towards Real-Time Object Detection(2015/6) 核心是把Selective Search交给了RPN做, 而RPN和fast rcnn是可以合并的
RPN
https://www.quora.com/How-does-the-region-proposal-network-RPN-in-Faster-R-CNN-work
- 输入: CNN产生的固定尺寸的特征图
- 第一层: $n \times n$ 卷积层, 输出256维特征向量. ($3 \times 3$ in the paper)
- 两个并行的分支:
- $cls$ 分支: $(2k, H, W)$ 每个像素位置产生$2k$个anchor boxes, 其中k为不同比例/尺寸的anchor数目
- $reg$分支: $(4k, H, W)$每个像素位置产生$4k$个delta, bbox regression
- RPN’s loss function:
$$
L(p_i, t_i) = \frac{1}{N_{cls}} \sum\limits_{i} L_{cls}(p_i, p^{\star}_{i}) + \lambda \frac{1}{N_{reg}} \sum\limits_{i} p_{i}^{\star}L_{reg}(t_i, t^{\star}_{i})
$$
- $i$: index of anchor in a mini-batch
- $p_i$: predicted probability of foreground
- $p^*_i$: grund truth. 1 for postive, 0 for negative
- $t_i$: bbox regression offset
- $L_{cls}$: log loss
- $L_{reg}$: Smooth L1 loss
Notes
- 后续RPN产生的ROIs扔进fast rcnn即可, RPN和RCNN共享backbone, 训练过程和细节不表, 见Faster R-CNN
- 有关RPN的细节见faster rcnn中rpn的anchor,sliding windows,proposals
Feature Pyramid Network
Feature Pyramid Networks for Object Detection(2016/11) 核心是Lateral Block. 解决了位置精度和语义信息的冲突问题:
- 越靠近输入的特征图语义信息越少, 但是位置信息越精确(特征图大)
- 越远离输入的特征图语义信息越强, 但是位置信息越弱(各种卷积, pooling)
- 左边是resnet的四层
stage
输出的特征图, 简称C2, C3, C4, C5 - 右边是P层, 每个P层通过上一层P层的upscale和相邻C层的smooth(统一通道数)之后相加得到. 每层通道数都是256, 其中最高层P4直接由C5 smooth而来.
|
|
RetinaNet
Focal Loss for Dense Object Detection: 对正负样本不平衡的深入挖掘
YOLO
人家讲的很好了, 懒得复制粘贴了 简单说几点
- 直接在7x7的特征图上输出每个格子的检测/分类结果, 每个格子输出两个proposal$(C_x, C_y, w, h, score, \vec c)$, 这个score相当于RPN的score, $\vec c$是一个one-hot的类概率向量.
- 这个输出是先拉平之后经过fc层再还原成7x7的! 如此简单粗暴, 惊不惊喜, 意不意外? PANet有更优雅的做法, 分出一个branch来指导. 但总之有fc层会对速度影响挺大的.
- 这么多loss混在一起, 需要给予不同的权重防止某一种dominate. 有/没有object的权重是不同的(这个有没有需要用iou去判断)
- 小box的损失应该比大box大, 设计损失函数的时候直接用长宽的根号差来处理…
嗯, 这种把所有损失一锅端的方法非常粗暴
SSD
- 这玩意就是个class-specified RPN.
- SSD取了backbone不同阶段的特征图, 大概当时FPN还没横空出世吧?
Mask RCNN
详见blog中关于mask-rcnn的文章…懒得再复制粘贴了
DetNet(SOTA)
DetNet: A Backbone network for Object Detection[ECCV18] 主要是对ResNet50的魔改
- 加入了空洞卷积
- 唔 为了防止越卷越小加入了一些1x1卷积(似乎?
没有看到特别有趣的insight…