R-CNN 简介
R-CNN 提出于 2014 年, 应当算是卷积神经网络在目标检测任务中的开山之作了, 当然同年间还有一个 overfeat 算法, 在这里暂不讨论.
在之后的几年中, 目标检测任务的 CNN 模型也越来越多, 实时性与准确率也越来越好, 但是最为经典的模型还是很值得学习的.
那么下面就正式开始吧:
对于 R-CNN 模型, 个人是这样理解, 它其实是将 4 个应用于不同任务的已有的算法很好的结合了起来, 最终在目标检测任务中取得了不错的效果, 这种结合更像是偏向于工程的方法, 而不是在算法上的一种突破, 当然在后续的 Fast-RCNN 与 Faster-RCNN 中模型逐步完善并整合成为一个模型, 但是在 R-CNN 中是没有的.
所以 R-CNN 由 4 个部分构成, 它们分别是:
1. 区域建议算法(ss)
2. 特征提取算法(AlexNet)
3. 线性分类器(线性 SVM)
4. 边界框修正回归模型(Bounding box)
区域建议算法:
首先是区域建议 (Region Proposal) 算法, 这个东西在 CNN 之前就已经有了, 而且算法不止一种, ss(selective search)算法是比较著名的一个, 此外还有 EdgeBox,MSER,MCG 等等算法.
那么 ss 算法在 R-CNN 中有什么用呢? 这要从目标检测任务开始谈起, 在一副图像中要实现目标检测任务, 一种最简单的思路是如果建立滑动窗, 对每次滑动窗提取出来的图像做分类, 如果分类结果恰好是目标的话, 就实现了检测啦, 目标的属性由分类器给, 目标的位置由滑动窗给. 但是考虑到一次滑动遍历产生的子图像数量就不小了, 同时还有不同步长和窗口尺寸的情况, 此时产生的待分类图像是非常多的, 这种方式显然没什么实用价值, 于是就有了 ss 算法, 一种根据图像自身信息产生推荐区域的算法, 它大概会产生 1000-2000 个潜在目标区域, 照比滑动遍历的方式, 这个数量已经减少了很多了.
特征提取算法:
这里的特征提取算法其实就是卷积神经网络, R-CNN 中使用的是 AlexNet, 但是作者 (Ross) 并没有把 AlexNet 当做分类器来使用, 而是只用了网络的特征层做 ss 算法输出的图像的特征提取工作, 然后第 7 层特征给了 SVM 分类器, 第五次特征给了 Bounding Box 回归模型.
线性分类器:
R-CNN 使用了线性 SVM 分类器, 这个没啥好说的, 机器学习中很牛的算法了, 需要说明的是, 目标检测任务是有分类的功能的, 比如一个任务是检测猫和狗, 那么除了要框出猫和狗的位置之外, 也需要判断是猫还是狗, 这也是 SVM 在 R-CNN 中的作用. 所以待检测物体有几类, 那么就应该有几个二分类的 SVM 分类器, 在上面的例子中, 就需要两个二分类分类器了, 分别是 "猫 - 非猫" 模型和 "狗 - 非狗" 模型, 在 R-CNN 中, 分类器有 20 个, 它的输入特征是 AlexNet 提取到的 fc7 层特征.
边界框修正回归模型:
Bounding box 也是个古老的话题了, 计算机视觉常见任务中, 在分类与检测之间还有一个定位任务, 在一副图像中只有一个目标, 然后把这个目标框出来, 用到的就是 Bounding box 回归模型.
在 R-CNN 中, Bounding box 的作用是修正 ss 推荐的区域的边界, 输入的特征是 AlexNet 的第五层特征, 与 SVM 分类器一样, 它也是每一个类别都有一个模型, 一共 20 个.
在上面, 我们分别介绍了 R-CNN 的四个部分和他们的作用, 可以看到, 其实都是之前的东西, 但是 R-CNN 的成功之处在于找到一种训练与测试的方法, 把这四个部分结合了起来, 而准确率大幅提升的原因在于 CNN 的引入. 我们参考下 HOG+SVM 做行人检测的方法, HOG 就是一种手工特征, 而在 R-CNN 中换成了 CNN 提取特征.
所以个人的看法是理解 R-CNN 的关键不在于上面提到的四个算法本身, 而是它们在 R-CNN 到底是怎么训练和测试的!
R-CNN 的训练
R-CNN 训练了 CNN,SVM 与 Bounding box 三个模型, 因为 ss 算法用不着训练, 哈哈~~
ss 在生成了 1000-2000 个推荐区域之后, 就和训练任务没啥关系了, 训练样本是由 ss 区域生成出来的子图构建起来的.
而且三个部分的训练时 ** 的, 并没有整合在一起.
1. 训练 CNN
CNN 是在 ImageNet 上 pre-train 的 AlexNet 模型, 在 R-CNN 中进行 fine-tune,fine-tune 的过程是将 AlexNet 的 Softmax 改为任务需要的类别数, 然后还是当做一个分类模型来训练, 训练样本的构建使用 ss 生成的子图, 当这些图与实际样本的框 (Ground-truth) 的 IoU 大于等于 0.5 时, 认为是某一个类的正样本, 这样的类一共有 20 个; IoU 小于 0.5 时, 认为是负样本. 然后就可以 AlexNet 做 pre-train 了, pre-train 之后 AlexNet 的 Softmax 层就被扔掉了, 只剩下训练后的参数, 这套参数就用来做特征提取.
2. 训练 SVM
之前提到了, SVM 的输入特征是 AlexNet fc7 的输出, 然后 SVM 做二分类, 一个有 20 个 SVM 模型. 那么对于其中某一个分类器来说, 它的正样本是所有 Ground-truth 区域经过 AlexNet 后输出的特征, 负样本是与 Ground-truth 区域重合 IoU 小于 0.3 的区域经过 AlexNet 后输出的特征, 特征和标签确定了, 就可以训练 SVM 了.
3. 训练 Bounding box 回归模型
Bounding box 回归模型也是 20 个, 还是拿其中一个来说, 它的输入是 AlexNet conv5 的特征, 注意这里的 20 指的是类的个数, 但是对一个 Bounding box 来说, 它有 4 套参数, 因为一个 Bounding box 回归模型分别对 4 个数做回归, 这 4 个数是表征边界框的四个值, 模型的损失函数如下:
其中 i 是样本个数,* 就是 4 个数, 他们分别是 x,y,w,h, 其中 (x,y) 是中心位置,(w,h)是宽和高; P 是 ss 给出来的区域, 它由 Px,Py,Pw,Ph 四个数决定, 这个区域经过 AlexNet 后再第五层输出特征, 然后在特征每一个维度前都训练一个参数 w, 一组特征就有一组 w, 随 4 组做回归就有 4 组 w; 最后一个数就是 t, 它同样有 4 个数 tx,ty,tw,th, 是这样计算出来的:
而 G 就是经过修正后的边界框, 它还是 4 个数 Gx,Gy,Gw,Gh. 通过上面的公式可以看到, t 是边界框的偏差.
最后就是到底什么样的 ss 区域能够作为输入, 在这里是 IoU 大于 0.6 的.
用一句话总结 Bounding box 回归模型就是: 对于某一个类的回归模型而言, 用 IoU>0.6 的 ss 区域经过卷积后作为输入特征, 用同一组特征分别训练 4 组权值与之对应, 对边界框四个属性值分别做回归.
经过上面三个 ** 的部分, R-CNN 的训练就完成了, 可以看到, 确实是非常麻烦, 这不仅仅体现在速度慢上, 过程也及其繁琐, 因为每一步都需要重新构建样本.
R-CNN 的测试
经过训练的 R-CNN 就可以拿来做测试了, 测试过程还是可以一次完成的, 它有下面几步:
1.ss 算法提取 1000-2000 个区域;
2. 对所有的区域做归一化, 为了 CNN 网络能接受;
3. 用 AlexNet 网络提出两套特征, 一个是 fc7 层的, 一个是 con5 层的;
4. 对于一个 fc7 区域的特征, 分别过 20 个分类器, 看看哪个分类器给的分数最高, 以确定区域的类别, 并把所有的区域一次操作;
5. 对上述所有打好 label 的区域使用非极大值抑制操作, 以获取没有冗余 (重叠) 的区域子集, 经过非极大值抑制之后, 就认为剩下的所有的区域都是最后要框出来的;
6. 重新拿回第 5 步剩下的区域 con5 层的特征, 送入 Bounding box 模型, 根据模型的输出做出一次修正;
7. 根据 SVM 的结果打标签, 根据修正的结果画框;
8. 结束!!!!!!
R-CNN 性能评价
R-CNN 的出现使计算机视觉中的目标检测任务的性能评价 map 出现了质的飞跃:
但是 R-CNN 也有一个很致命的缺陷, 超长的训练时间和测试时间:
训练时间需要 84 个小时, 如果说训练时间还不是那么重要的话, 那么单张图片的测试时间长达 47s, 这个缺陷使 R-CNN 失去了实用性, 好在后续的各种算法对其进行了改进, 这个我们后面在提.
补充
1. 非极大值抑制在这里不介绍了;
2. 如何根据 Bounding box 模型的输出做出修正:
模型输出是四个值的偏差(比例), 那么根据如下公式就能够得到最后的位置
第五个公式就是 Bounding box 模型.
深度学习目标检测 (object detection) 系列(二):
来源: https://juejin.im/post/5b9b57c3e51d450e9649b7ff