目标检测算法可以分为两类:
- 一类是基于region proposal的R-CNN系列算法(R-CNN,Fast R-CNN, Faster R-CNN),它们是two-stage的。要先使用启发式方法(selective search)或者CNN网络(RPN)产生region proposal,然后再在region proposal上做分类与回归。精确度高,速度低。
- 另一类是YOLO,SSD这类one-stage算法,仅仅使用一个CNN网络直接预测不同目标的类别与位置。精确度低,速度快。
采用滑动窗口的目标检测算法思路很简单,将检测问题转化为了图像分类问题。原理是采用不同大小和比例(宽高比)的窗口在整张图片上按照一定步长进行华东,然后对这些窗口对应的区域做图像分类,这样就可以实现对整张图片的检测。缺点是不知道要检测的目标大小,所以要设置不同大小和比例的窗口去滑动,还要采取合适的步长,这样会产生很多的子区域,并且都要经过分类器去做预测,这需要很大的计算量,所以你的分类器不能太复杂,因为要保证速度。解决思路之一就是减少要分类的子区域,这就是R-CNN的一个改进策略,其采用了selective search方法来找到最有可能包含目标的子区域(Region Proposal),其实可以看成采用启发式方法过滤掉很多子区域,这会提升效率。
如果用的是CNN分类器,滑动窗口非常耗时,使用全卷积方法,将网络中的卷积层代替全连接层。例如输入16x16图像经过一系列卷积操作得到2x2特征图,这个图上的每个元素与原图是一一对应的,相当于卷积核14x14,步长为2的卷积,产生4个字区域,输出通道数4,可看成4个类别的预测概率值,这样一次CNN计算就可以实现窗口滑动的所有子区域的分类预测,这就是overfeat算法的思路。这是因为卷积操作图片的空间位置信息的不变性,位置对应关系保存好了。这个思路也被R-CNN借鉴,诞生了Fast R-CNN。
尽管上面可以减少滑动窗口的计算量,但只是针对一个固定大小与步长的窗口,远远不够。
YOLO算法很好的解决了这个问题,不再是窗口滑动,而是直接将原始图片分割成互补重合的小方块,然后通过卷积最后产生这样大小的特征图,特征图的每个元素也是对应原始图片的小方块,然后利用每个元素来预测那些中心点在该小方格内的目标。
设计
将图片resize成448x448,送入到CNN网络,最后处理网络预测结果得到预测的目标。
具体的说,YOLO的CNN网络将图片分割成SXS网格,每个单元格检测那些中心点落在格子内的目标,如下图狗这个目标的中心点落在左下角一个单元格内,那么这个单元格负责预测这个狗。
每个单元格会预测B个bouding box以及bouding box的confidence。这个confidence代表所预测的box中含有object的confidence和这个bounding box预测的有多准的置信度,这个值是这样算的:
:bounding box内含有目标的概率,有取1,否则为0;
:bounding box和GT之间IoU
因此每个bounding box预测 (x, y, w, h) 和 confidence 共5个值。每个单元格还要预测一个类别信息 C 类,则 SxS个 网格,每个网格要预测 B 个 bounding box 还要预测 C 个 categories(因为编码时,假如狗在单元格中心,那么狗的概率为1,其他概率为0,编码后类似:100000000000.。。)。
输出就是 S x S x (5*B+C) 的一个 tensor。
注意:class 信息是针对每个网格的,confidence 信息是针对每个 bounding box 的。
每个单元格预测的c类的方法是,只要目标落在单元格中心,单元格就负责预测这个类,所以只预测了一次。
举例说明: 在 PASCAL VOC 中,图像输入为 448x448,取 S=7,B=2,一共有20 个类别(C=20),则输出就是 7x7x30 的一个 tensor。
在 test 的时候,每个网格预测的 class 信息和 bounding box 预测的 confidence信息相乘,就得到每个 bounding box 的 class-specific confidence score:
每个网格预测类别的概率 x 含有类别的概率下的置信度 = 预测的box属于某一类的概率,也有该 box 准确度的信息
得到每个 box 的 class-specific confidence score 以后,设置阈值,滤掉得分低的 boxes,对保留的 boxes 进行 NMS 处理,就得到最终的检测结果。
*由于输出层为全连接层,因此在检测时,YOLO 训练模型只支持与训练图像相同的输入分辨率。
*虽然每个格子可以预测 B 个 bounding box,但是最终只选择只选择 IOU 最高的 bounding box 作为物体检测输出,即每个格子最多只预测出一个物体。当物体占画面比例较小,如图像中包含畜群或鸟群时,每个格子包含多个物体,但却只能检测出其中一个。这是 YOLO 方法的一个缺陷。
网络训练
在训练之前,现在Imagenet上进行预训练,其与训练的分类模型采用下图中前20个卷积层,然后添加一个average-pool层和全连接层。与训练之后,在预训练得到的20层卷积层之上加上随机初始化的4个卷积层和2个全连接层。由于检测任务一般需要更高清的图片,所以要将网络的输入从224x224增加到了448x448.整个网络的流程如下图所示:
也就是最后再通过全连接层将7x7x30的特征图接全连接层转化为上图所示
如何对坐标回归?
作者对坐标进行了归一处理,在同一个量刚下,这样方便处理。
假设有一个bounding box其中心刚好落在了(row,col)网格中,则这个网格需要负责预测整个红框中的dog目标。假设图像的宽为widthimage,高为heightimage;红框中心在(xc,yc),宽为widthbox,高为heightbox那么:(1) 对于bounding box的宽和高做如下normalization,使得输出宽高介于0~1:
(2) 使用(row, col)网格的offset归一化bounding box的中心坐标:
经过上述公式得到的normalization的(x, y, w, h),再加之前提到的confidence,共同组成了一个真正在网络中用于回归的bounding box;
而当网络在Test阶段(x,y,w,h)经过反向解码又可得到目标在图像坐标系的框。
损失函数
最后输出的是7x7x30,也就是一共有7x7个单元格,每个单元格有30维度,8 维是回归 box 的坐标,2 维是 box的 confidence,还有 20 维是类别。
其中坐标的 x, y 用对应网格的 offset 归一化到 0-1 之间,w, h 用图像的 width 和 height 归一化到 0-1 之间。
作者简单粗暴的全部采用了 sum-squared error loss 来做这件事。这种做法存在以下几个问题:
- 第一,8维的 localization error 和20维的 classification error 同等重要显然是不合理的;
- 第二,如果一个网格中没有 object(一幅图中这种网格很多),那么就会将这些网格中的 box 的 confidence push 到 0,相比于较少的有 object 的网格,这种做法是 overpowering 的,这会导致网络不稳定甚至发散。
解决的方法:
-
更重视8维的坐标预测,给这些损失前面赋予更大的 loss weight, 记为在 pascal VOC 训练中取 5。
-
对没有 object 的 box 的 confidence loss,赋予小的 loss weight,记为在 pascal VOC 训练中取 0.5。
-
有 object 的 box 的 confidence loss 和类别的 loss 的 loss weight 正常取 1。
-
对不同大小的 box 预测中,相比于大 box 预测偏一点,小 box 预测偏一点肯定更不能被忍受的。而 sum-square error loss 中对同样的偏移 loss 是一样。
-
为了缓和这个问题,作者用了一个比较取巧的办法,就是将 box 的 width 和 height 取平方根代替原本的 height 和 width。这个参考下面的图很容易理解,小box 的横轴值较小,发生偏移时,反应到y轴上相比大 box 要大。(也是个近似逼近方式)
一个网格预测多个 box,希望的是每个 box predictor 专门负责预测某个 object。具体做法就是看当前预测的 box 与 ground truth box 中哪个 IoU 大,就负责哪个。这种做法称作 box predictor 的 specialization。
- 只有当某个网格中有 object 的时候才对 classification error 进行惩罚。
- 只有当某个 box predictor 对某个 ground truth box 负责的时候,才会对 box 的 coordinate error 进行惩罚。
缺点
YOLO 方法模型训练依赖于物体识别标注数据,因此,对于非常规的物体形状或比例,YOLO 的检测效果并不理想。
YOLO 采用了多个下采样层,网络学到的物体特征并不精细,因此也会影响检测效果。
YOLO 的损失函数中,大物体 IOU 误差和小物体 IOU 误差对网络训练中 loss 贡献值接近(虽然采用求平方根方式,但没有根本解决问题)。因此,对于小物体,小的 IOU 误差也会对网络优化过程造成很大的影响,从而降低了物体检测的定位准确性。
YOLO 对相互靠的很近的物体,还有很小的群体检测效果不好,这是因为一个网格中只预测了两个框(B=2),并且只属于一类。
同一类物体出现的新的不常见的长宽比和其他情况时,泛化能力偏弱。
由于损失函数的问题,定位误差是影响检测效果的主要原因。尤其是大小物体的处理上,还有待加强。