论文笔记: 目标检测算法(R-CNN,Fast R-CNN,Faster R-CNN,YOLOv1-v3)
R-CNN(Region-based CNN)
motivation: 之前的视觉任务大多数考虑使用 SIFT 和 HOG 特征, 而近年来 CNN 和 ImageNet 的出现使得图像分类问题取得重大突破, 那么这方面的成功能否迁移到 PASCAL VOC 的目标检测任务上呢? 基于这个问题, 论文提出了 R-CNN.
基本步骤: 如下图所示, 第一步输入图像. 第二步使用生成 region proposals 的方法 (有很多, 论文使用的是 seletivce search,ImageNet2013 检测任务的冠军 UVA 也使用了该算法) 提取约 2000 个候选区域. 由于 CNN 固定输入大小所以第二步和第三步之间需要做一个 warped region. 第三步将 2000 个候选区域分别输入到 CNN(AlexNet)计算 2000 个特征向量, 第四步将各个特征向量 (4096 维, 相比于之前常用的方法 UVA 减小了 2 个量级, 4k vs 360k) 输入到 (类特定的) 各个线性 SVM 中分类(比如 VOC 的 20 个类别就有 20 个 SVM). 对于特定类的 SVM, 由于有 2000 个候选区域, 所以有 2000 个结果, 使用非极大值抑制来获得得分较高的一些候选区.
CNN 的训练: 使用的 CNN 在 ImageNet2012 分类数据集上做了预训练. 微调时把最后的 1000 类改为 N+1 类, 对于 VOC 而言 N 为 20, 对于 ImageNet2013 检测数据集而言 N 为 200, 以 IOU 大于等于 0.5 为正样本, 其它为负样本, 学习率 0.001, 每次 SGD 迭代 (128 的 batch size) 中用了 32 个正窗口 (所以类上) 和 96 个背景窗口.
SVM 的训练: 以 0.3 作为 IOU 阈值来选取正负样本. 由于负样本太多, 采用 hard negative mining 的方法在负样本中选取有代表性的负样本.
R-CNN BB: 为了提高定位表现, 额外使用了一个 bounding box regression. 用第五个池化层的特征输入到 SVM 获取得分, 然后 (根据最大 IOU) 构建候选区域和真实区域的数据集, 训练一个回归器, 可以对候选区域的位置修正.
结果比较之 VOC: 在 VOC 2007 上调参, 在 VOC 2010-12 上进行预测. CNN 在 VOC 2012 训练集上做微调, SVM 在 VOC 2012 的训练验证集上进行训练. 超越了其它算法.
结果比较之 ImageNet2013:OverFeat 是 ImageNet2013 定位任务的冠军, 对于检测任务在赛后也获得了第一的成绩 (24.3% 的 mAP), 是 ImageNet2013 检测数据集(200 类) 上表现最好的检测算法(当时), 而 R-CNN 用在 ImageNet2013 的检测数据集上获得了 31.4% 的 mAP.
Fast R-CNN
R-CNN 的三个缺点: 多阶段(训练 CNN, 训练 SVM, 训练 bb 回归器); 训练时空间和时间代价高(对于 SVM 和 bb 回归器需要把每张图像的每个候选区特征通过 CNN 提取出来存到磁盘); 预测阶段很慢(因为要对每张图像的每个候选区域提取特征).
SPPnet 的改进: R-CNN 预测慢是因为对于每个候选区域要过一次 CNN 而不共享计算, 而 SPPnet 则是使用共享计算来加速. 如下第一个图所示, SPP 输入整张图, 计算一个 feature map, 在 feature map 上找到候选区对应的一个子图, 然后对子图做一个金字塔池化得到一个固定长度的特征向量(下图中得到的是 4x4+2x2+1 个特征). 尽管如此, SPPnet 仍然有多阶段以及特征写入磁盘的缺点, 而且因为 SPPnet 的特征是从 conv5 的 feature map 上池化而来的, 所以只 fine-tuning 金字塔池化层之后的层(这限制了深层网络的准确性).
motivation:Fast R-CNN 修正了 R-CNN 和 SPPnet(Spatial pyramid pooling)的缺点, 提升了速度和准确率. 它是一个单阶段的算法, 使用了 multi-task loss, 可以对整个网络进行更新, 而且不需要把特征存到磁盘上.
主要步骤: 如下第二个图所示, 输入为一整张图以及一系列的 (selective search 生成的) 候选区域(映射到 conv5 的 feature map 上得到 ROI),ROI 意为 Region of Interest. 像 SPPnet 一样对 ROI 进行池化, 只不过这里是单水平的金字塔池化(如下第一个图是三水平), 比如分成 7x7 个子图对每个子图取最大得到长度为 49 个 ROI 特征. 池化后经过 FC, 然后分成两个分支, 一个分支用 softmax 做分类, 一个分支用 bb 回归器做定位, 使用 multi-task loss 进行训练.
mini-batch sampling:R-CNN 和 SPPnet 在微调训练时每个 batch 是从 128 张图像中分别取一个 RoI. 而 Fast 取 N 个图像, 每个图像取 R/N 个 ROI(论文中使用 N=2,R=128), 这样来自同一个图像的 ROI 在前向和后向过程中就可以共享内存和计算, 提高了效率. 采样时 25% 的 ROI 是从 IOU 为 0.5 以上的侯选框选的, 剩余的 ROI 是从 IOU 为 [0.1, 0.5) 中的侯选框选的.
SGD 超参: softamx 和 bb 回归器的全连接层使用 0 均值, 0.01 和 0.001 的标准差的高斯分布进行初始化. bias 为 0. 所有层的权重学习率为 1 倍的全局学习率, 偏置为 2 倍的全局学习率, 全局学习率为 0.001. 对于 VOC07 或者, VOC12 的训练, 30k 次迭代, 然后学习率减为 0.0001 然后训练另外 10k 次迭代. momentum 为 0.9,weight decay 为 0.0005.
截断的 SVD: 将庞大的全连接层压缩为截断的 SVD 可以提高检测速度.
应该微调哪些层: 消融学习中, 固定前面的卷积, 只微调后面的全连接层 (像 SPPnet 那样) 发现 mAP 下降, 说明微调前面的卷积层是重要的. 那么是不是说所有的卷积层都应该被微调呢, 不是, 通过实验发现 conv1 对 mAP 影响不大, 对于 VGG16, 发现只需要更新 conv3_1 以及以后的层.
其它实验和讨论: 通过实验, 发现单尺度可以获得和多尺度差不多的结果, 所以论文的实验都是使用单尺度. 通过实验, 发现更多训练数据可以提高 mAP. 通过实验, 发现 softmax 比 SVM 好一点点, 差距不大. 通过实验, 发现随着候选区数量的增加, mAP 先增后降, 说明不是越多越好. 将 Fast 运行在 COCO 数据集上建立一个初步 baseline.
Faster R-CNN
motivation:Fast R-CNN 的瓶颈在于生成候选区域 (Selective Search 的) 的方法非常耗时, Faster 提出把生成候选区域也放到卷积网络来做 (网络称为 RPN,Region Proposal Networks), 将 RPN 和检测网络(Fast R-CNN) 结合成一个网络进行统一的训练和检测, 这样可以共享卷积操作, 减小计算时间. 实验也表明了 Faster 可以提高检测表现.
主要步骤: 如下第一个图所示, 在原来网络的最后一层卷积层加入一个 RPN 来生成 ROI, 然后根据 feature map 和 ROI 进行 ROI 池化, 后面和 Fast 一样再接全连接, softmax 和回归器.
RPN 结构: 设计如下第二个图, RPN 在最后一个卷积层上以 nxn 的窗口滑动进行卷积 (论文中 n 为 3, 所对应的感受野是很大的), 每个窗口(一小块 3x3 的区域) 被映射成低维特征(ZFnet-256d,VGG-512d), 然后分为两路接两个 1x1 卷积得到分类层和回归层. 其中 k 表示事先设计的 k 个 anchor(论文中 k 为 9,3 种 scale 和 3 种宽高比组合), 分类层的 2k 个单元中的 2 表示是或不是, 回归层的 4k 个单元中的 4 表示目标对应的坐标位置. 最后会根据这两个层计算一个损失进行训练.
训练 RPN: 训练时, 和某个 grouth truth 的 IoU 值最高的 anchor 视为正样本, 和任意 ground truth 的 IoU 超过 0.7 的 anchor 也视为正样本. 和所有 ground truth 的 IoU 低于 0.3 的视为负样本, 其它的忽略, 超出原图边界的 anchor 也忽略 (如果测试阶段得到这种 anchor, 则 clip 到边界). 一个 mini-batch(256) 为一张图像的多个 anchor, 正负比例为 1 比 1. 共享卷积层遵循 R-CNN 的实践进行 ImageNet 分类的预训练来对参数初始化, 对 ZFnet 调整整个网络, 对 VGG 微调 conv3_1 以上的层. 其它新增层 (RPN) 用(0,0.01)的高斯分布初始化参数. 前 60k 次 mini-batch 使用 0.001 的学习率, 后 20k 次 mini-batch 使用 0.0001 的学习率, 在 VOC 数据集上. momentum 为 0.9,weight decay 为 0.0005.
RPN 和检测网络 (Fast R-CNN) 的训练: 论文采用的是交替训练的方式, 第一步按上述步骤训练 RPN. 第二步用 RPN 产生的候选区域训练检测网络, 检测网络也进行了预训练, 到这一步, 二者不共享前面的公共卷积层. 第三步用检测网络的参数初始化 RPN 前面的公共卷积层, 微调 RPN, 此时 RPN 和检测网络共享前面的卷积层. 第四步, 微调检测网络的后半部分 (固定公共卷积层). 另外, RPN 产生的区域可能高度重叠, 根据 RPN 的分类分数, 使用非极大值抑制(0.7 的 IOU 阈值) 来减小候选区域数量.
Yolo(You Only Look Once)v1
motivation: 与 R-CNN 系列算法 (产生候选区域, 分类, 回归修正) 不同, yolo 直接用一个单独的卷积网络输入图像, 输出 bb(bounding box)和分类概率.
优点: 第一是更快 (不需要像 R-CNN 系列那样复杂的步骤). 第二是站在全局的角度(可以看到整张图像) 去预测, 可以产生更小的背景误差. 第三是能学到泛化能力强的特征(实验表明).
缺点: 第一是施加了很强的空间限制, 导致系统能预测的目标数量有限, 而且对靠的很近的物体和很小的物体的检测效果不好. 第二是难以泛化到新的不常见的长宽比物体. 第三是损失函数对小 bb 和大 bb 的误差同等对待, 小误差对大 bb 来说没什么, 但是对小 bb 来说影响很大, yolo 的主要错误就是来源于定位错误. 还有一点是准确率无法达到 state-of-art 的水平.
主要思想: 如下图所示, 将输入图像划分为 SxS 的格子, 目标 (物体) 的中心落在哪个格子内, 就由哪个格子负责. 每个格子检测 B 个 bb 和 C 个类别的条件概率. 每个 bb 包含 5 个值(x, y, w, h, 置信度), 其中 x 和 y 相对于格子归一化到 0 到 1,w 和 h 相对于整张图像归一化为 0 到 1, 置信度定义为 \(Pr(Object)*IOU_{pred}^{truth}\), 我们希望 "如果没有物体则置信度为 0, 如果有物体, Pr 为 1, 置信度表示为 IOU".C 个类别的条件概率为 \(Pr(Class_i | Object)\). 测试阶段用条件概率乘上置信度, 得到一个类相关的置信度. 所以最后输出层的单元数字应该为 SxSx(Bx5+C), 论文中 S 为 7,B 为 2,C 为 20 类(VOC 数据集), 所以输出是一个 7x7x30 的 tensor. 另外, 对于一个大物体, 可能出现多个格子对它负责预测, 这个时候使用非极大值抑制处理.
训练: 网络结构参考 GoogleNet 做了修改. 在 ImageNet 上做了 1000 类分类的预训练, 然后增加卷积层和全连接层, 把 224 的输入改成 448(检测需要更细粒度的视觉信息). 输出层使用线性激活, 其它层使用 leaky relu. 在 VOC07 和 12 的训练集和验证集上训练了 135 个 epochs, 在 VOC12 测试时也使用 (加入) 了 VOC07 的测试集进行训练. batch size 为 64,momentum 为 0.9,weight decay 为 0.0005. 学习率在第一个 epoch 从 0.001 缓慢升到 0.01, 如果一开始使用高学习率会由于不稳定的梯度导致模型不收敛. 然后 0.01 训练 75 个 epochs,0.001 训练 30 个 epochs,0.0001 训练最后 30 个 epochs. 为了防止过拟合使用了 dropout(第一个连接层之后, 0.5)和数据增强.
损失函数: 如下 (论文中给出的) 式子所示. 损失函数把定位误差和分类误差平等对待可能不太好, 而且一张图像可能很多格子是没有物体的, 使得置信度几乎为 0, 这压制了确实有物体的格子的梯度, 使得模型不稳定. 所以需要减小不含物体的 bb 的置信度带来的损失(给予一个 0.5 的权重 \(\lambda_{noobj}\)), 增加 bb 坐标带来的损失(给予一个 5 的权重 \(\lambda_{coord}\)). 损失函数把大 bb 和小 bb 平等对待也不太好, 为了一定程度上弥补这个问题, 对于宽度和高度, 使用它们的平方根来代替它们本身.
其它: 关于 yolo 之前在 ng 深度学习课程中有所了解, 具体笔记见:
- .
- \[\lambda_{
- coord
- }\sum_{
- i=0
- }^{
- S^2
- }\sum_{
- j=0
- }^{
- B
- }\mathbb{
- 1
- }_{
- ij
- }^{
- obj
- }[(x_i-\hat{
- x
- }_i)^2+(y_i-\hat{
- y
- }_i)^2] + \\ \lambda_{
- coord
- }\sum_{
- i=0
- }^{
- S^2
- }\sum_{
- j=0
- }^{
- B
- }\mathbb{
- 1
- }_{
- ij
- }^{
- obj
- }[(\sqrt{
- w_i
- }-\sqrt{
- \hat{
- w
- }_i
- })^2+(\sqrt{
- h_i
- }-\sqrt{
- \hat{
- h
- }_i
- })^2] + \\ \sum_{
- i=0
- }^{
- S^2
- }\sum_{
- j=0
- }^{
- B
- }\mathbb{
- 1
- }_{
- ij
- }^{
- obj
- }(C_i - \hat{
- C
- }_i)^2+ \lambda_{
- noobj
- }\sum_{
- i=0
- }^{
- S^2
- }\sum_{
- j=0
- }^{
- B
- }\mathbb{
- 1
- }_{
- ij
- }^{
- noobj
- }(C_i - \hat{
- C
- }_i)^2 + \\ \sum_{
- i=0
- }^{
- S^2
- }\mathbb{
- 1
- }_{
- i
- }^{
- obj
- }\sum_{
- c \in classes
- }(p_i(c)-\hat{
- p
- }_i(c))^2\]
- Fast R-CNN(2015 ICCV):Fast R-CNN https://arxiv.org/PDF/1504.08083v2 (模型源码 - caffe 实现 https://GitHub.com/rbgirshick/fast-rcnn )
- Faster R-CNN(2015 NIPS):Faster R-CNN: Towards Real-Time Object Detection with Region Proposal Networks https://arxiv.org/PDF/1506.01497v3 (模型源码 - caffe 实现 https://GitHub.com/rbgirshick/py-faster-rcnn )
- Yolov1(2016 CVPR):You Only Look Once: Unified, Real-Time Object Detection https://arxiv.org/PDF/1506.02640v5 (模型源码 - darknet(C 和 cuda) https://pjreddie.com/darknet/yolov1/ )
- Yolov2(2017 CVPR):YOLO9000: Better, Faster, Stronger https://arxiv.org/PDF/1612.08242v1 (模型源码 - darknet(C 和 cuda) https://pjreddie.com/darknet/yolov2/ )
来源: https://www.cnblogs.com/liaohuiqiang/p/9740382.html