介绍目标探测的基本方法,传统方法 DPM,神经网络分类 R-CNN 系列方法和神经网络回归 YoLo 系列方法。
目标探测
先来看下什么是目标探测,下图矩形框(running box)表示的物体都可以作为目标探测的对象。不止矩形框,椭圆形框在某些场合更适合做目标探测,因为它能更好的捕捉对象,并对物体朝向做相应调整,机变性更好。
目标探测的任务一般分为单目标探测和多目标探测。目的一是找到目标的位置坐标,二是判定目标类别。
目标探测的应用场景有安防、自动驾驶等。从技术方面讲,目标探测传统方法用的是DPM,虽然目前已经被神经网络超越,但是很多思想可以借鉴。神经网络大体上有两类方法,一类是分类方法主要是RCNN系列方法 ,先找到若干候选区,然后一个区域一个区域排查,判断有没有要找的物体;另一类是回归方法主要是YoLo系列方法,直接找到区域,以及区域有什么物体。
下面来看下目标探测的两个直接思路。
直接思路一:回归问题
一类思路是把目标探测看作是一个回归问题。直接生成 class score,也就是判断是该类别(物品)的 confidence value,和 box coordinates,也就是检测框的坐标值。整个任务的损失函数其实是位置差和分类差的一个组合。
直接思路二:局部识别问题
另一类思路是在很多位置上尝试识别,能够完成识别的地方就是目标位置。如下图,我们生成潜在的候选区域(proposal),然后采用分类器逐个判别这些区域内图像是不是目标物体,如果是,可以把候选区域做延展(用 regression),看有没有更合适的候选框。
一个问题是怎样找到这些候选位置?
一种方法是用不同 scale 的 sliding windows 来遍历所有的位置,这种方法代价太高,另一种更有效的方法是直接计算候选区域。现在有很多算法能够有效的产生候选区域,比较常用的是 EdgeBoxes(在 RCNN 中使用)。
传统方法-DPM
传统方法主要包括 3 个步骤:
- 利用不同尺度的滑动窗口在图像上进行区域搜索,定位候选区域;
- 对候选区域进行特征提取,如sift,hog,haar等;
- 利用分类器进行分类识别,svm等
主要思路就是提取图像特征,制作出激励模板,在原始图像滑动计算,得到激励效果图,然后根据激励分布确定目标位置。如下图人物识别把人为设计的激励模板和 HOG 特征图结合,如果有人,会得到加强的激励,然而同样的,柱子也会得到激励。
DPM(Deformable Part Model)可以看做是HOG(Histograms of Oriented Gradients)+SVM(Surpport Vector Machine) 方法的扩展,大体思路是一致的 — 先计算梯度方向直方图,然后用 SVM 训练得到物体的梯度模型。有了这样的模板就可以直接用来分类了,简单理解就是模型和目标匹配。DPM 只是在模型上做了很多改进工作。
由于目标可能会形变,之前模型不能很好的适应复杂场景的探测,所以一个改进是各个部分单独考虑,对物体的不同部分单独进行学习,所以DPM把物体看成了多个组成部件(比如说人脸的鼻子,嘴巴等),用部件间的关系来描述物体,这个特点非常符合自然界许多物体的非刚性特征。基本思路如下:
- 产生多个模板,整体模板(root filter)以及不同局部模板(part filter)
root filter 包含目标的整体信息,而 part filter 采用高分辨率的细节建模,看的梯度会更加精细 - 不同模板同输入图片“卷积”产生特征图
- 特征图组合形成融合特征
- 对融合特征进行传统分类,回归,得到目标位置
- 模型在图像特定位置和尺度的得分, 等于 root filter 的得分加上各个 part filter 得分的总和。每个 part filter 的得分等于该 part 在所有空间位置的得分的最大值,而部件在某位置的得分等于 part filter 在此位置的得分减去此位置的变形代价(也就是 part 偏离其理想位置的程度)
DPM 的优点是方法比较直观、简单,运算速度快,也可以适应运动物体变形,很好的处理遮挡、非刚性可变和视觉变换问题,到 2012 年前,是最好的方法。然而 DPM 也有一些缺点
- 性能一般
- 激励特征人为设计,表达能力有限,工作量大,难以进行迁移学习
- 大幅度旋转无法适应,稳定性差
神经网络分类: R-CNN 系列方法
R-CNN(CVPR2014, TPAMI2015)
算法
神经网络的分类思想是对多个位置,不同尺寸,用卷积神经网络判断区域内图片是不是某物,候选位置(proposal)提出方法一般用 EdgeBox。
R-CNN 最初提出的时候选择 20 类进行探测,是在 ImageNet 模型的基础上,把 1000 类的分类模型变成能识别 21 类(20类+other)的 Fine-tune 分类模型。
=>
特征的提取过程: 对图片计算候选区域;对候选区域切分图片,对切分部分进行 resize 变成输入大小;提取相应高级特征;存储特征(大容量,200-300G空间存储图片)
单独目标探测器训练:对每一类进行单独训练,保证每一类训练数据平衡,每一类都是 binary 分类(yes/no)。比如猫的分类器,可能大部分图片没有一个理想的猫,只有一个耳朵,这不算猫,我们要与真值进行比较,看左上右下区域,如果重合(共有区域)比较多,就认为是猫的图片。每一类都有很多的正例反例(1/0)。
单独目标回归器训练-基于候选区域微调: 同样的,每一类单独训练,保证每一类训练数据平衡,这里是每一类做 BBOX 回归。目的是在知道是不是猫以及位置的偏移后,用回归对位置进行 offset,离真值(ground truth)更近,最终的探测精度会更高。
总的来说,R-CNN 的测试过程就是
- 对每个图像生成 1k-2k 个候选区域
- 对每个候选区域,使用深度网络进行特征计算
- 特征喂给每一类的 svm 分类器,判别是否属于该类分类;同时用回归修正候选框位置
- 后续处理
常用数据集
评估方法
- MAP(mean average precision)
- IoU,真值和预测值多重叠部分与两者的并集的比值,一般大于 0.5 就认为是正确的
R-CNN 结果对比
Regionlets(2013) 并没有经过 fine-tune,R-CNN(2014, AlexNet) 用事先训练好的分类器进行了 fine-tune,R-CNN+bbox reg(AlexNet),用了 regression,加了 offset 对检测框做了范围调整,R-CNN(vgg-16)把 base model 改成了 vgg
总的来说,主要是从下面三个角度进行了模型的调整
- Finetune
- 回归微调
- Base 模型
优缺点
优点:
- CNN 用于目标探测,利 用了 CNN 高效识别能力, 大大提高性能
- 摆脱人为设计物品模版, 方法具有通用性
- 分类+回归,有了找到精确位置的可能
缺陷:
- 为了检测一个目标,所有候选区域计算,大量卷积运算,非常慢
对于速度慢这个问题,SPP-NET 给出了解决方案。R-CNN 对图像提完 region proposal(2k 左右)之后将每个 proposal 当成一张图像进行后续处理(CNN提特征+SVM分类),实际上对一张图像进行了2000次提特征和分类的过程!SPP-NET 对图像提一次卷积层特征,然后将 region proposal 在原图的位置映射到卷积层特征图上,这样对于一张图像只需要提一次卷积层特征,然后将每个 region proposal 的卷积层特征输入到全连接层做后续操作 - SVM 训练与CNN 断裂, SVM Loss 没办法用于 CNN Loss,有效信息不能用于优化模型, not end-to-end
- 每一类单独训练,异常繁琐
Fast R-CNN(ICCV2015)
Fast R-CNN 的三个进步
- 共享卷积计算
增加 ROI pooling layer - 完整训练(end-to-end)
用 softmax 代替 svm 分类,用多目标损失函数加入候选框回归,除 region proposal 提取外实现了 end-to-end - 多目标一起学习
共享卷积计算
Fast R-CNN 在最后一个卷积层后加了一个 ROI pooling layer,实际上就是上面提到的 SPP-NET 的一个精简版,特点是:
- 卷积计算保持空间位置
- 共同区域的卷积计算只需进行一次
- 切割候选区+提取特征图=计算完整特征图+切割对应候选区
把图片的 region proposal 切割出来,resize,提取特征,其实就等同于在原图特征图里找到 region proposal
一个重要的问题是不同区域的特征如何保持一致?
全连接层要求接的区域形状一致;所以要特征图里区域的一致性处理,也就是做一个 pooling
特征一致化 - Max Pooling
局部区域
100x50 =>按 4:2 pooling
50x100 => 按 2:4 pooling
=> 25x25 feature
=> 225 FC
如果 pooling size 不完美,其实也没有问题,pooling 本身就是填充 pooling 后的图的每一个 pixel,只要从 pooling 前某区域选一个 pixel 值即可,不一定要规整
位置 + 类别联合学习
图片 => cnn feature map计算 => proposal应用 => feature map相应区域做 region pooling 得到固定大小的 feature map => classification & regression
用 softmax 代替 svm 分类,使用多任务损失函数(multi-task loss),将候选框回归直接加入到 cnn 网络中训练,除去 region proposal 的提取阶段,这样的训练过程是端到端的(end-to-end),整个网络的训练和测试十分方便
性能提升
看一下性能提升的情况
然而前提是 不考虑候选区域(proposal)的生成,如果加上候选区域(proposal)的时间
region proposal 的提取使用 selective search,目标检测时间大多消耗在这上面(提region proposal 2~3s,而提特征分类只需0.32s),无法满足实时应用,那么,怎么解决候选区域的计算呢?一个方法是也靠神经网络。
Faster R-CNN(NIPS2015)
RPN(Region Proposal Network)
用神经网络来解决候选区域的生成问题,主要是神经网络特征增加一组输出 RPN(Region Proposal Network)候选区域网络
- 直接产生候选区域,无需额外生成
本质上是 sliding window,RPN 只需在最后的卷积层上滑动一遍,因为 anchor 机制和候选框回归可以得到多尺度多长宽比多 region proposal - 直接用于后续特征图切割
最后的特征图中有很多个 pixel,每个 pixel 和卷积核进行计算,生成 k 个可能的 prpoposal(实际中 k 往往=9,一个区域可能同时被多个物体占用,所以尽可能把可能分布的形状都生成),每个 proposal 有个 score 的计算。如图,左边是 3x3 的卷积网络的特征图,右边是 k 个 anchor box(相当于小的候选生成单元)。我们对特征图进行 sliding window 的计算,每个 pixel 生成 256 长的向量(向量长度其实是自己设计的,vgg 建议 512-d),这个向量用来生成 k 个 proposal 的值,以及对应的 2k score(是/不是目标物体),4k 个 coordinates(上下左右坐标)。
网络输出的值:
- 是不是一个目标
- 覆盖范围的相对位置
k=9(3种尺寸,3种长宽比)个 anchor,能产生多少个 proposal?
特征图 size HxW -> HWx9 in paper 2400x9
如果是 VGG conv5 作为特征图,3x3 区域对应的原始图像区域?
经过了 4 个 pooling,往前推,6x6 -> 12x12 -> 24x24 -> 48x48,也就是 16 倍的一个缩放
Anchor的平移不变怎么理解
较小的平移 pooling 过程中忽略,3 个 pixel 的移动经过 4 层的 pooling,移动后的位置和原位置相差可以忽略
Anchor 同外接 Proposal 区别
数量:1-2个数量级减少;性能:更高效;
速度:10x
Anchor 设计的借鉴意义?
神经网络有能力找到最终量,也有能力找到很多中间量。只用 Anchor 判断是不是目标,会不会存在大材小用,能够判断更多吗?或者说,能在是不是目标的基础上,判断是什么目标吗,也就是直接拟合
为了让RPN的网络和Fast R-CNN网络实现卷积层的权值共享,训练 RPN 和 Fast R-CNN的时候用了4阶段的训练方法:
- 使用在 ImageNet 上预训练的模型初始化网络参数,微调 RPN 网络;
- 使用(1)中RPN网络提取 region proposal 训练 Fast R-CNN网络;
- 使用(2)的 Fast R-CNN 网络重新初始化 RPN, 固定卷积层进行微调;
- 固定(2)中 Fast R-CNN 的卷积层,使用 (3) 中 RPN 提取的 region proposal 微调网络
Faster R-CNN 用了直接联合学习(joint learning) 的方法,如上图,一个网络有 4 个损失函数
- Anchor 是不是目标
- Anchor 回归候选区域回归
- Fast R-CNN 分类
- Fast R-CNN 基于候选位置回归
联合学习的方法产生了更少的候选区,但是精度不会受到影响,速度却快了 10 倍,接近于实时处理(@K40 GPU, 12G)。
性能提升
接近于实时处理,然而还是很难实时的目标探测,下面的 YOLO 这类方法可以达到实时性。
神经网络回归: YoLo 系列方法
YoLo
算法
YoLo 将目标探测任务看作目标区域预测和类别预测的回归问题,用单个神经网络直接预测物品边界和类别分数,可以直接找到物体是什么,在哪里。
把图片分成 SxS 的格子(grid cell),一般是 7x7 的网络,每个网格生成:
- B 个 Bbox,4 个 coordinates + 1 个 confidence score
- N 个类别分数 $Pr(Class_i|Object)$
与 Anchor 不同的是,这里有 N 个分数,表示属于每一类的分数分别是多少
S=7, B=2, N=20
总共的回归目标: SxSx(5B+N)
2x5+20=30 个参数,49x30=1470 个数值,用来回归
候选区域个数: (B=2) 98 个 << Faster R-CNN
每个小区域生成 2 个候选区,一个小的区域就是一个粗糙的 proposal,对小区域进行大范围的 regression,找到目标
损失函数:
性能
性能:
- 实时运行
- 精度稍微下降
- 定位精度较差
经过大量的 pooling,位置的响应会有一定弱化
Limitations
- YoLo 的每一个网格只预测两个 boxes,一种类别。这导致模型对相邻目标预测准确率下降。因此,YOLO 对成队列的目标(如一群鸟)识别准确率较低。
- YoLo 是从数据中学习预测 bounding boxes,因此,对新的或者不常见角度的目标无法识别。
- YoLo 的损失函数对small bounding boxes 和 large bounding boxes 的 error 平等对待,影响了模型识别准确率。因为对于小的 bounding boxes,small error影响更大。
SSD: The Single Shot Detector
SSD 分类更细,网络结构有点像 resnet。中间多层特征参与位置、种类计算,在不同 layer 输出的不同尺寸的 feature map 划格子,在格子上提“anchor”,弥补了 Yolo 只在最后一层分 7x7 的框漏掉的部分。和 Yolo 相比,更快更准确。
- 候选区 98 vs 8732
- 速度 21:46 (vgg base)
- 精度 66.4:74.3