以下内容摘自斯坦福cs231n目标检测课程:
Idea #1:定位问题视为回归问题
实现步骤:
1. 训练(或下载)一个分类模型(AlexNet, VGG, Inception)
2. 添加新的全连接层用作“回归”
3. 仅训练“回归”模块,SGD,L2 Loss
4. 测试时加入“分类”和“回归”
回归分为两种:
独立于类别的回归:
Class agnostic (4 numbers / per box)
类别明确的回归:
Class specific (C*4 numbers / per box)
定位多个目标:
定位K个目标, eg: cat, cat head, cat left ear, cat right ear
对于回归head,为K*4 numbers one box per object
回归模块的位置:
Idea #2:滑动窗口方法(Sliding Window)
1、FCN(Fully Convolutional Networks)
网络最后输出的图片大小不在是一个1*1大小的图片,而是一个与输入图片大小息息相关的一张图片了。
Alexnet网络设计完毕后,也用FCN的思想,把全连接层看成是卷积层运算,发现如果Alexnet输入一张500*500图片的话,那么它将得到1000张10*10大小的预测分类图,这个时候可以简单采用对着每一张10*10大小的图片求取平均值,作为图片属于各个类别的概率值。
其实Alexnet在测试阶段的时候,采用了对输入图片的四个角落进行裁剪,进行预测,分别得到结果,最后的结果就是类似对应于上面2*2的预测图。这个2*2的每个像素点,就类似于对应于一个角落裁剪下来的图片预测分类结果。只不过Alexnet把这4个像素点,相加在一起,求取平均值,作为该类别的概率值。
需要注意的是,overfeat就是把采用FCN的思想把全连接层看成了卷积层,让我们在网络测试阶段可以输入任意大小的图片。
2、offset max-pooling
offset池化,以一维为例:
在x轴上有20个神经元,如果我们选择池化size=3的非重叠池化,那么根据我们之前所学的方法应该是:对上面的20个,从1位置开始进行分组,每3个连续的神经元为一组,然后计算每组的最大值(最大池化),19、20号神经元将被丢弃,如下图所示:
也可以在20号神经元后面,人为的添加一个数值为0的神经元编号21,与19、20成为一组,这样可以分成7组:[1,2,3],[4,5,6]……,[16,17,18],[19,20,21],最后计算每组的最大值,这就是我们以前CNN中池化层的源码实现方法了。
如果我们只分6组的话,我们除了以1作为初始位置进行连续组合之外,也可以从位置2或者3开始进行组合。也就是说我们其实有3种池化组合方法:
A、△=0分组:[1,2,3],[4,5,6]……,[16,17,18];
B、△=1分组:[2,3,4],[5,6,7]……,[17,18,19];
C、△=2分组:[3,4,5],[6,7,8]……,[18,19,20];
以往的CNN中,一般我们只用了△=0,得到池化结果后,就送入了下一层。于是文献的方法是,把上面的△=0、△=1、△=2的三种组合方式的池化结果,分别送入网络的下一层。这样的话,我们网络在最后输出的时候,就会出现3种预测结果了。
如果是2维图片的话,那么(△x,△y)就会有9种取值情况(3*3);如果我们在做图片分类的时候,在网络的某一个池化层加入了这种offset 池化方法,然后把这9种池化结果,分别送入后面的网络层,最后我们的图片分类输出结果就可以得到9个预测结果(每个类别都可以得到9种概率值,然后我们对每个类别的9种概率,取其最大值,做为此类别的预测概率值)。
OverFeat滑动窗口方法:
overfeat图片分类
1. paper网络架构与训练阶段
(1)网络架构
对于网络的结构,文献给出了两个版本,快速版、精确版,一个精度比较高但速度慢;另外一个精度虽然低但是速度快。下面是高精度版本的网络结构表相关参数:
网络输入:221*221;AlexNet不同之处在于:
(a) 没有使用LRN;
(b)然后也没有Overlap-pooling;
(c)在第一层卷积层,stride为2, (AlexNet是4)。
这边需要注意的是需要把f7这一层,看成是卷积核大小为5*5的卷积层
(2) 网络训练
训练输入:对于每张原图片为256*256,然后进行随机裁剪为221*221的大小作为CNN输入,进行训练。
优化求解参数设置:训练的min-batchs选择128,权重初始化选择高斯分布的随机初始化:
2、网络测试阶段
不再是用一张221*221大小的图片了作为网络的输入,而是用了6张大小都不相同的图片,也就是所谓的多尺度输入预测,如下表格所示:
从layer-5 pre-pool到layer-5 post-pool:这一步的实现是通过池化大小为(3,3)进行池化,然后△x=0、1、2, △y=0、1、2,这样得到对于每一张特征图,都可以得到9幅池化结果图。以上面表格中的sacle1为例,layer-5 pre-pool大小是17*17,经过池化后,大小就是5*5,然后有3*3张结果图(不同offset得到的结果)。
把最后一列不同尺度结果再做一个平均,作为最最后的结果。
如Scale3,输出:15*9*C,共15*9个不同尺度,分别求各尺度类别,最后求平均。
定位任务
把分类层(上面的layer 6~output)给重新设计一下,把分类改成回归问题,然后在各种不同尺度上训练预测物体的bounding box。
实际实现中,用到了不同位置不同尺度的图像:
ImageNet 分类+定位:
1. AlexNet:定位算法未公布;
2. Overfeat:多尺度box回归;
3. VGG:同Overfeat,但尺度和位置更少;方法简单,受益于更深层提取的特征;
4. ResNet:RPN网络,更深层次的特征。
将检测问题看做分类问题:
问题:需要检测很多位置和尺度的box;
解决:分类速度快,尚且可行。
HOG行人检测:(Histogram of Oriented Gradients)
DPM:(Deformable Parts Model)
Deformable Parts Models are CNNs:
将检测问题看做分类问题:
问题:需要检测很多位置和尺度的box;
解决:仅分类可能性很大的box。
区域建议法:(Region Proposals)
查找可能包含有目标的区域:
区域建议法:Selective Search:
区域建议法:其他方法
区域建议+CNN->R-CNN
R-CNN训练:
1. 训练一个ImageNet分类器模型。
2. Fine-tune model.分类类别变为20类,去除最后一层,添加新的分类层共21个输出(含背景)
3. 提取特征:
4. 为每一类训练一个2分类的SVM分类器:
5. box回归:
每一类训练一个线性回归模型,从特征到GT box偏移量的映射
对于窗口一般采用思维向量(x,y,w,h)表示,分别表示中心点和宽高。红色P为原始Proposal,绿色G为Ground Truth,目标是寻找一种P到G的映射,得到G^,更接近G
即,给定(Px, Py, Ph, Pw)寻找映射f,使得:
目标真值不是Ground Truth,而是tx, ty, tw, th:
目标函数为:
损失函数:
数据集统计:
|
PASCAL VOC (2010) |
ImageNet Detection (ILVRC 2014) |
MS-COCO (2014) |
Number of classes |
20 |
200 |
80 |
Number of images (train + val) |
~20K |
~470K |
~120K |
Mean objects per image |
2.4 |
1.1 |
7.2 |
测试结果:
mAP:mean average precision。为每个类计算AP(average precision),然后计算平均
TP:iou>0.5
TL;DR mAP范围:【0,100】,越大越好
RCNN 存在问题:
RCNN 存在问题1:需要为每个Region Proposal前向传播计算特征
解决方案:
Region Proposal共享前面的卷积层
RCNN 存在问题2: SVM和Box回归与CNN不在一条Pipline
解决方案:
端到端的训练(end-to-end),取消SVM,用神经网络代替。
Fast RCNN(核心):ROI Pooling层(Region of Interest Pooling)
训练数据:
R个候选框构成如下:
类别 |
比例 |
方式 |
前景 |
25% |
与某个GTBox的iou∈[0.5, 1] |
背景 |
75% |
与某个GTBox的iou∈[0.1, 0.5) |
ROI Pooling层结构:(VGG16)
代价函数
检测结果
Using VGG-16 CNN on Pascal VOC 2007 dataset
问题:
上表结果不含Region Proposal,Region Proposal 时间为2s,整体提升才近21倍。
解决:
用CNN做Region Proposal。
参考:
本文链接:http://task.lmcjl.com/news/5436.html