可以看成图像分类与定位的结合,给定一张图片,目标检测系统要能够识别出图片的目标并给出其位置,由于图片中目标数是不定的,且要给出目标的精确位置,目标检测相比分类任务更复杂。目标检测的一个实际应用场景就是无人驾驶。
目标检测算法可以分为两类:
- 一类是基于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网络直接预测不同目标的类别与位置。精确度低,速度快。
YOLO-V1
滑动窗口与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)以及边界框的置信度。这个置信度包含两个:
- (1)这个边界框含有目标的可能性大小
当边界框时背景时(即步包含目标),;包含目标时,
- (2)这个边界框的准确度
用预测框与实际框(groud truth)的IOU(intersection over union,交并比)来表征,记为
- 因此置信度定义为
边界框的大小与位置: 即(中心中标x,中心坐标y,边界框宽,边界框高)。
还有分类问题,每个单元格还要预测出C个类别的概率值,表征的是该单元格预测的边界框目标所属各个类别的概率。这个概率值是在各个边界框置信度下的条件概率,即。不管单元格预测多少个边界框,其只预测一组类别的概率值(这个单元格n个边界框中属于狗的概率值),只是YOLO算法的一个缺点。YOLO9000是把类别概率预测值和边界框绑定在一起。
还可以计算出各个边界框类别置信度(class-specific confidence scores):
边界框类别置信度表征的是该边界框中目标属于各个类别的可能性大小以及边界框匹配目标的好坏。一般是根据类别置信度来过滤网络的预测框。
总结:每个单元格预测(B x 5 + C),如果将输入图片划分为S x S个网络,那么最终预测值大小的张量。对于PASCALVOC数据,共有20个类别,如果使用S=7,B=2,那么最终的预测结果就是大小的张量,下面的网络结构中我们会详细讲述每个单元格的预测值的分布位置。
网络设计
YOLO采用卷积网来提取特征,再使用全连接层来得到预测值。网络结构参考googleNet模型,24个卷积层和2个全连接层。对于卷积层来说,重要使用1x1卷积来做channle reduction,然后紧跟3x3卷积。对于卷积层和全连接层,采用Leaky Relu激活函数:。最后一层采用线性激活函数。
网络最后输出为7×7×30大小的张量。对于每一个单元格,前20个元素是类别概率值,然后2个元素是边界框置信度,两者相乘得到类别置信度,最后8个元素是边界框的。把置信度c和都翻开排列是为了计算方便,这30个元素都是对应一个单元格。网络的预测值是个二维张量,其shape为。采用切片,那么就是类别概率部分,
是置信度部分,是边界框的预测结果。
网络训练
在训练之前,现在Imagenet上进行预训练,其与训练的分类模型采用下图中前20个卷积层,然后添加一个average-pool层和全连接层。与训练之后,在预训练得到的20层卷积层之上加上随机初始化的4个卷积层和2个全连接层。由于检测任务一般需要更高清的图片,所以要将网络的输入从224x224增加到了448x448.整个网络的流程如下图所示:
训练损失函数
YOLO算法将目标检测看成回归问题,所以采用的是均方差损失函数。但是对不同部分采用不同的权重值。
定位误差:边界框坐标预测误差,采用较大的权重。然后其区分不包含目标的边界框与含有目标的边界框的置信度。不包含目标的边界框:采用较小的权重值。其他权重值均设置为1。然后采用均方误差,其同等对待大小不同的边界框。实际上较小的边界框的坐标误差应该要比大的边界框要敏感,为了保证这一点,将网络的边界框的宽与高预测改为对其平方根的预测,即预测值变为。
每个单元格预测多个边界框,但是只对应一个类别。则在训练的时候,如果单元格内确实存在目标,那么只选择与groud truth的IOU最大的那个边界框来负责预测该目标,其他边界框可认为不存在目标。这样设置的结构将会是一个单元格对应的边界框更加专业化,可以分别适用不同大小,不同高宽比的目标,从而提升模型性能。如果一个单元格内存在多个目标,YOLO算法也只能选择其中一个来训练,这是YOLO的缺点。注意对于不存在对应目标的边界框,其误差项就是只有置信度,坐标项误差是没法计算的。只有当一个单元格内确实存在目标的时候,才计算分类误差项。
最终的损失函数计算如下:
置信度target值:如果不存在目标,此时,则;若存在目标,,此时需要确定(当然你希望最好的话,可以将IOU取1,这样),但是YOLO实现中,使用了一个控制参数rescore(默认为1),当其为1时,IOU就是计算truth与pred之间的真是IOU。不过很多复现YOLO的项目还是取。
网络预测
非极大值抑制算法(non maximum suppression,NMS)
这个算法不单单是针对YOLO算法的,所有的检测算法中都会用到,NMS算法主要解决的是一个目标被多次检测的问题。我们希望最后仅仅输出其中一个最好的预测框,那么就可以使用NMS来实现这样的效果:首先从所有的检测框中找到置信度最大的那个框,然后挨个计算与剩余框的IOU,如果其值大于一定阈值(重合度过高),那么就将该框剔除,然后对剩余的检测框重复上述过程,知道处理完所有的检测框。YOLO预测过程也需要用到NMS算法。
下面分析YOLO预测过程????????
先不考虑batch,预测一张输入图片。根据前面分析,最终的网络输出是,分成三个部分(类别概率部分,置信度部分,边界框部分)然后将前两项相乘(
乘以,可以各补一个维度来完成),可以得到类别置信度为,总共预测了个边界框。
所有的准备数据都得到,使用第一种策略来得到检测框的结果:首先对于每个预测框根据类别置信度选取置信度最大的那个类别作为其预测标签,经过这层处理可以得到各个预测框的预测类别及对应的置信度值,其大小都是。 (2:每个单元格有2个边界框)
一般情况下,会设置置信度阈值,就是将置信度小于该阈值的box过滤掉,所以经过这层处理,剩余的是置信度比较高的预测框。最后再对这些预测框使用NMS算法,最后留下来的就是检测结果。一个值得注意的点是NMS是对所有预测框一视同仁,还是区分每个类别,分别使用NMS。Ng在deeplearning.ai中讲应该区分每个类别分别使用NMS,但是看了很多实现,其实还是同等对待所有的框,我觉得可能是不同类别的目标出现在相同位置这种概率很低吧。
对于YOLO算法使用了另一种思路:先使用NMS,然后再确定各个box的类别。基本过程如下图:
算法性能分析
数据集PASCAL VOC 2007
Yolo算法可以在较高的mAP上达到较快的检测速度,其中Fast Yolo算法比快速DPM还快,而且mAP是远高于DPM;
相比Faster R-CNN,Yolo的mAP稍低,但是速度更快;
所以,Yolo算法算是在速度与准确度上做了折中。
相比Faster R-CNN,Yolo的mAP稍低,但是速度更快。所以。Yolo算法算是在速度与准确度上做了折中。
相比Faster R-CNN,Yolo的mAP稍低,但是速度更快。所以。Yolo算法算是在速度与准确度上做了折中。
优点
缺点