R-CNN
目标检测模型被称为将卷积神经网络引入目标检测的开山之作,尽管现在看来其性能早已达不到应用的标准,但是它的一些设计思想至今仍具有学习的意义。
IoU
与非极大抑制:非极大抑制(NMS)算法原理与Python实现 R-CNN
,全称Region CNN
,即区域卷积神经网络。其进行目标检测的主要思想就是生成可能存在目标的候选区域region proposal
,然后通过CNN
、分类器等手段判断区域中是否存在检测目标,并进行分类。最后再对识别出目标的区域范围进行精细的调整即可。
R-CNN
进行目标识别主要分为四个步骤:
1000~2000
个候选区域以进行识别CNN
提取每个候选区域的特征向量SVM
根据特征向量对区域进行分类Bounding Box Regression
对检测框进行调整 R-CNN
在生成候选区域时选择了比传统的滑动窗口性能更好的选择搜索算法Selective Search
。
选择搜索算法的主要思想和python
实现我已经在另一篇博客"选择搜索(Selective Search)算法介绍与Python实现解释"中进行了详细的介绍,此处不再赘述。
通过选择搜索算法,模型能够在原图上提取出1000~2000
个可能包含检测目标的候选区域,这些区域的位置信息和大小信息以如下形式返回:
regions = [[x, y, w, h], ...]
# x: 候选区域中心点横坐标
# y: 候选区域中心点纵坐标
# w: 候选区域宽度
# h: 候选区域高度
将每个候选区域输入卷积神经网络便可以提取出这个区域的特征向量。R-CNN
论文发表时所采用的网络为AlexNet
,初始权重也直接采用了当时AlexNet
的训练结果,其结构如下:
AlexNet
输入图像的尺度都是固定的,然而候选区域的大小形状缺并不唯一,为了能够将不同的候选区域输入同一个CNN
,一般可以采取以下两种做法:
resize
函数将图像缩放到指定的大小。这种做法十分简单,缺点时可能导致图像的形状特征被破坏 除了缩放,R-CNN
论文中还为图像增加了padding
(这个概念和CNN
中的padding
一样),通过实验,对候选区域采用各向异性缩放并且padding
为16时,模型效果最优。
区域分类的样本是CNN
提取出的区域特征向量,采用的分类模型是SVM
,那么每个样本的标签从何而来呢?
候选区域生成算法生成的候选区域有1000~2000
个,并且每张图像生成的候选区域都不一样,所以肯定无法人为进行标注。R-CNN
最终采取的策略是,如果候选区域与人工标注的少量检测框的交并比Intersection over Union, IoU
大于某个阙值,就将其判为正例,否则判定为反例。这个阙值的取值通过论文作者的实验,最终建议取值为0.3
。(关于交并比的解释详见博客"非极大抑制(NMS)算法原理与Python实现")
准备好训练数据后,便可以针对每一个类别训练一个二分类SVM
,通过多个SVM
的输出结果便可以知道输入特征向量对应的候选区域中是否存在某种物体。
通过SVM
分类得到的预测框虽然能够正确判定框中的检测物体,但是其预测框与真实框的IoU
却可能很低,例如:
为了提高模型识别目标的准确率,此时就需要对检测框进行一定程度上的修正,即使用边框回归Bounding Box Regression
对检测框进行微调。关于边框回归算法的解释详见我的另一片博客"边框回归(Bounding Box Regression)算法解释"。简而言之,边框回归算法通过学习对预测框的平移参数和缩放参数,可以尽可能让预测框更加接近于真实框。
通过上述的四个步骤,R-CNN
的目标检测任务就基本完成了,此时模型已经能够输出一些较为精准的检测框,例如:
但是,不难发现,此时R-CNN
的输出似乎总是会产生一些冗余。在上图的示例输出中,就出现了多个检测框检测同一个目标的情况。这种情况可以通过对输出进行非极大抑制Non-Maximum Suppression, NMS
解决。
所谓非极大抑制,顾名思义,就是对检测准确率不高的检测框的输出进行抑制,从而达到缩减输出检测框数量并清除冗余的目的。关于非极大抑制算法的详细说明和python
实现详见博客"非极大抑制(NMS)算法原理与Python实现"。
进行NMS
后,模型的输出如下: