分享在某乎上看到的一段话:
不以结婚为目的的谈恋爱,都是耍流氓;
不以盈利为目的的做生意,就是瞎扯淡;
不以输出为目的的知识输入,都是在自嗨。
瞎扯淡~回归正题~
最近为了写论文,先后撸了rcnn,fast-rcnn,faster-rcnn,yolo,ssd,r-fcn,yolo9000等目标检测相关的论文,现在准备一篇一篇小小总结一下(毕竟不以输出为目的的知识输入,都是在自嗨)~
第一篇总结R-CNN,作为目标检测任务的开山鼻祖,R-CNN可谓是一个里程碑的著作。
关于RCNN一篇我觉得讲的非常好的博客请参考关于Faster R-CNN的一切——笔记1:R-CNN,很多内容都是从里面摘出来的,我在原文的基础上做了总结和一些自认为有必要的补充。
NMS(非极大值抑制)部分的图片整理自NMS——非极大值抑制
论文地址:Rich feature hierarchies for accurate object detection and semantic segmentation
后面开始为正文部分
目录:
RCNN是第一个证明CNN可以极大地提高PASCAL中物体检测性能的工作,之所以叫做Region CNN,是因为算法是将CNN应用在已经产生的region proposals上。
上图是r-cnn检测的流程图,详细如下:
一张image生成好多好多Region Poposals
↓
每个Region Proposal用训练好的CNN网络提取特征
↓
每个类别用该类训练好的SVM对每个Region Proposal评分
↓
根据评分对该类的region proposal进行Greedy non-maximum suppression筛选最终的region。
后面的每一个部分按照上面的流程进行解释,最后叙述整体的训练和测试步骤。
因为R-CNN是与region proposal方法无关的,所以本文选择使用Selective Search算法来产生每张图片的proposal,本文选择每张图片生成2000个proposal。
使用了Selective Search方法从一张图像生成约2000-3000个候选区域。基本思路如下:
-使用一种过分割手段,将图像分割成小区域
-查看现有小区域,合并可能性最高的两个区域。重复直到整张图像合并成一个区域位置
-输出所有曾经存在过的区域,所谓候选区域
候选区域生成和后续步骤相对独立,实际可以使用任意算法进行。
在region的特征提取步骤,采用了fine-tune的策略。由于object detection任务的数据集本身就存在数据量少,类别少的特点,用这么少量的数据来训练一个large-scale的cnn网络本身就是一个很不make sense的想法,所以文章先用ImageNet的数据集来pretrain一个CNN网络,如下图1所示,然后再用PASCAL VOC的数据集retrain网络,对网络的参数进行微调,如下图2所示。
最后,对每个region proposal的4096维特征向量,用每一类的SVM分类器对它进行评分(是该类的可能性有多大)。那么如果有N类物体,那么我们可以从一张图上得到一个2000*N的评分矩阵(假如通过selective search方法提取到了2k个region proposals),矩阵的每一行是一个region proposal在N个类别的SVM分类器下的得分。见图3。
最后,假设经过Selective search后,一张图产生了N个Region proposals,经过C(类别个数)个SVM分类器后,产生了(N*C)个结果。我们通过Greedy non-maximum suppression(非极大值抑制)方法来对最后的结果进行过滤和筛选,得到最后的结果。
以下图为例,由于滑动窗口,同一个人可能有好几个框(每一个框都带有一个分类器得分)
其实也就是说,相对于我们的2k个候选框,其对应的某一类别的分类分数会有2k多个(例如2k多个候选框对于人脸这个svm分类器产生了2k多个分数
而我们的目标是一个人只保留一个最优的框:于是我们就要用到非极大值抑制,来抑制那些冗余的框: 抑制的过程是一个迭代-遍历-消除的过程。其一般步骤如下:
(1)将所有框的得分排序(每个类别都做这个操作,这里是以人脸这个类别为例),选中最高分及其对应的框:
例如该图中,我们选择了0.83这个框为起始框。
(2) 遍历其余的框,如果和当前最高分框的重叠面积(IOU)大于一定阈值,我们就将框删除。
例如该图中,女生脸的其中的重合框被去除了(男生框与最高的框没有重叠,所以不动)
(3) 从未处理的框中继续选一个得分最高的,重复上述过程。
如图,女生的人脸已经筛选过,我们以男生得分为0.81的框为初始框,最后过滤掉了0.67得分的框(因为这个框与目标框的Iou超过的阈值)。迭代这个过程。
这里,我们对训练的过程进行更加detail的展开说明,包括:pretrain,fine-tune和训练SVM。
(1) pre-train:预训练的过程其实很简单,就是重现一遍AlexNet在ImageNet数据集上的训练过程,最后得到的训练好的AlexNet最后BaseNetwork。
网络:AlexNet
数据集: ILSVRC 2012
训练平台:caffee
(2) fine-tune:在R-CNN中,region proposals的分类不是直接通过CNN来进行的。region proposal先通过一个CNN网络来提取特征,最后将特征输入SVM来进行分类,(这里有个坑,为什么不直接用CNN来做分类呢?),所以文章的做法是用PASCAL VOC的数据集来对pre-train的AlexNet作为一个分类进行retrain(虽然retrain后的网络只是用来提特征,但是还是作为分类任务来训练的)。
把pre-train好的Alexnet的最后的1000-way softmax层换成(N+1)-way【N是物体类别数目,+1是背景类】的全连接层,其他结构不变,然后在你的目标数据集上训练网络,这个时候训练网络的输入就是你的数据集上提取出的region proposals们了。
训练的细节:
(1)region proposal的标签怎么设置:与某个ground-thuth box的IoU大于等于0.5的为正,其他情况为负。
(2)Mini-batch size:随机采样32个正样本和96个负样本,所以mini-batch大小是128
(3)参数:学习速率设为0.001。
(3) train linear SVM:通过fine-tune训练完毕的AlexNet被最后一个特征提取器来提取最后一层的4096维的特征,这些特征被用来训练与类别个数相当的SVMs。
特定类别的分类器 对每个类都训练一个线性的SVM分类器,训练SVM需要正负样本文件,可以想象得到,刚好包含某一类物体的region proposal应该是正样本,完全不包含的region proposal应该是负样本,但是对于部分包含某一类物体的region proposal该如何训练呢?
对每一类,正负样本的规定是:该类的Ground-truth box是正样本,与Ground-truth box的IoU小于0.3【0.3是在validation集上确定的】的region proposal是负样本,其余的region proposal舍弃,不用作训练。
检测的过程就很简单啦~
(1)通过ss产生2k多个Region Proposal
(2)归一化
(3)输入Fine-tuned的网络,提取4096维的特征(这边就不需要经过IoU筛选了)
(4)每个Region Proposal的特征分别输入所有的SVM分类器进行打分
(5)最后根据分值进行Greedy non-maximum suppression