重点参考《深度学习(十八)基于R-CNN的物体检测》和《RCNN学习笔记(1):Rich feature hierarchies for accurate object detection and semantic segmentation》
R-CNN(Regions with Convolutional Neural Network Features)【1】是RBG大神将CNN引入目标检测领域的开山之作,之后的一系列进化算法(SPP-Net、fast R-CNN、faster R-CNN、YOLO、YOLO2、SSD)都是受其启发做的
R-CNN的主要贡献有2个:
1)经典目标检测算法一般使用滑动窗口扫描所有可能区间,同时需要考虑变化窗口尺寸以适应不同大小的目标,这种方法效率太低。R-CNN使用Selective Search方法预先提取所有候选区域
2)经典目标检测算法依赖人工设计的特征,R-CNN使用深度学习自动提取和学习特征
算法思路
首先使用Selective Search方法提取所有可能区域(大约2K个),然后采用CNN(AlexNet)提取每个候选区域的特征向量(维度4096),最后使用SVM对每个特征做分类(图1)
图1. R-CNN算法总体思路
候选框提取
使用Uijlings的Selective Search方法,算法输出的区域有很多,需要做一个非极大值抑制(对概率最高的区域,计算其他区域和他的重合度,如果重合度比较大则删除这些区域;然后考虑概率第二高的区域。。。),最后得到大约2K个候选区域。
由于CNN的需要统一尺寸的输入,因此这里还需要将候选区域resize(对AlexNet是227*227)。文章试验了2种不同的resize方法:
1)各向异性缩放
不管当前区域的长宽比,直接resize。结果可能会扭曲原图
2)各向同性缩放
这里也有2种处理办法
a.直接在原始图中做边界扩展,如果到了图像边缘则用区域的均值做填充
b.在区域边缘使用固定背景颜色做填充
需要注意的是,这两类方法中文章还加了padding处理(就是先添加一定尺寸的边界)。
最终文章选择padding=16的各向异性resize方法
CNN特征提取
文章考虑了AlexNet和VGG16两个经典的网络。前者测试的精度为58.5%,后者为66%;但VGG16的计算量是AlexNet的7倍。最后文章选择AlexNet
文章将CNN训练分为两步:首先使用ILSVRC2012的数据做预训练(1000类),然后使用VOC数据集做fine-tunning(之所以要预训练是因为VOC数据量太少)
fine-tuning阶段将网络输出换成21类,学习率设为0.001,每次迭代使用32个正样本和96个负样本(IoU重叠阈值设为0.5,大于该值为正,小于为负)
文章同时测试了不用fine-tuning,直接用AlexNet的模型做特征提取,发现p5层的精度与f6、f7差不多,其中f6得到的特征比f7精度还搞。而fine-tuning后的f7输出特征获得的分类精度会得到大幅度提高。
这个测试表明,入过不针对特定任务做fine-tuning,CNN与SIFT一样,获得的是基础的通用特征。
SVM训练及测试
实际上CNN最后一层(softmax)就能提供分类结果,那为什么要用f7的特征通过SVM做分类呢?
这是由于考虑到过拟合的风险,CNN的训练数据比较宽松,一个bouding box可能只包含一部分物体(IoU=0.5),也作为正样本训练;
而SVM适用于少样本训练,所以训练数据可以比较严格(文章选择IoU=0.3),这样能获得比softmax更高的分类精度。
对于K个目标分类,同时训练K个SVM。假设图片候选框为2000个,那么输入特征维度为2000*4096,SVM的权重维度为4096*1(需要注意的是,由于IoU的选择不同,CNN和SVM的正负样本性质可能不一样)
算法实现
RBG大神在Github上公开了代码,可能是由于selective search代码的原因,使用的Matlab
参考文献
【1】 Girshick R, Donahue J, Darrell T, et al. Rich Feature Hierarchies for Accurate Object Detection and Semantic Segmentation[C]// Computer Vision and Pattern Recognition. IEEE, 2013:580-587.