这篇博客主要介绍下 YOLO v1 算法(CVPR2016 的文章)。YOLO 是目前比较流行的 object detection 算法,速度快且结构简单,其他的 object detection 算法如 faster RCNN,SSD 相信大家也不陌生,以后有机会再介绍。另外提一下,这里算法部分介绍的是 YOLO 的第一个版本,而现在 YOLO 的官网上已经有 YOLO v2 的实现了,这个后续再介绍。
论文名称:You only look once unified real-time object detection
论文链接
1、YOLO v1 算法内容
作者在 YOLO 算法中把物体检测(object detection)问题处理成回归问题,用一个卷积神经网络结构就可以从输入图像直接预测 bounding box 和类别概率。
YOLO 算法的优点:1、YOLO 的速度非常快。在 Titan X GPU 上的速度是 45 fps(frames per second),加速版的 YOLO 差不多是 150fps。2、YOLO 是基于图像的全局信息进行预测的。这一点和基于 sliding window 以及 region proposal 等检测算法不一样。与 Fast R-CNN 相比,YOLO 在误检测(将背景检测为物体)方面的错误率能降低一半多。3、YOLO 可以学到物体的 generalizable representations。可以理解为泛化能力强。4、准确率高,有实验证明。
算法结构图如 Fig1:结构上主要的特点就是 unified detection,不再是原来许多步骤组成的物体检测,这使得模型的运行速度快,可以直接学习图像的全局信息,且可以 end-to-end 训练。
算法首先把输入图像划分成 S*S 的格子,然后对每个格子都预测 B 个 bounding boxes,每个 bounding box 都包含 5 个预测值:x,y,w,h 和 confidence。x,y 就是 bounding box 的中心坐标,与 grid cell 对齐(即相对于当前 grid cell 的偏移值),使得范围变成 0 到 1;w 和 h 进行归一化(分别除以图像的 w 和 h,这样最后的 w 和 h 就在 0 到 1 范围)。原文如下:
另外每个格子都预测 C 个假定类别的概率。在本文中作者取 S=7,B=2,C=20(因为 PASCAL VOC 有 20 个类别),所以最后有7730 个 tensor。如 Fig2,比较好理解。
这里confidence 的计算公式如下:
每个 bounding box 都对应一个 confidence score,如果 grid cell 里面没有 object,confidence 就是 0,如果有,则 confidence score 等于预测的 box 和 ground truth 的 IOU 值,见上面公式。所以如何判断一个 grid cell 中是否包含 object 呢?答案是:如果一个 object 的 ground truth 的中心点坐标在一个 grid cell 中,那么这个 grid cell 就是包含这个 object,也就是说这个 object 的预测就由该 grid cell 负责。
每个 grid cell 都预测 C 个类别概率,表示一个 grid cell 在包含 object 的条件下属于某个类别的概率,如下图:
下面截图连接上面。注意 grid cell 和 bounding box 的区别,类别概率是针对 grid cell 的。
这个乘法具体是怎么做的呢?请看下图:每个 bounding box 的 confidence 和每个类别的 score 相乘,得到每个 bounding box 属于哪一类的 confidence score。
即得到每个 bounding box 属于哪一类的 confidence score。也就是说最后会得到 20_(772)=20_98 的 score 矩阵,括号里面是 bounding box 的数量,20 代表类别。接下来的操作都是 20 个类别轮流进行:在某个类别中(即矩阵的某一行),将得分少于阈值(0.2)的设置为 0,然后再按得分从高到低排序。最后再用 NMS 算法去掉重复率较大的 bounding box(NMS: 针对某一类别,选择得分最大的 bounding box,然后计算它和其它 bounding box 的 IOU 值,如果 IOU 大于 0.5,说明重复率较大,该得分设为 0,如果不大于 0.5,则不改;这样一轮后,再选择剩下的 score 里面最大的那个 bounding box,然后计算该 bounding box 和其它 bounding box 的 IOU,重复以上过程直到最后)。最后每个 bounding box 的 20 个 score 取最大的 score,如果这个 score 大于 0,那么这个 bounding box 就是这个 socre 对应的类别(矩阵的行),如果小于 0,说明这个 bounding box 里面没有物体,跳过即可。具体细节参考最后的参考资料 1。
网络方面主要采用GoogLeNet,卷积层主要用来提取特征,全连接层主要用来预测类别概率和坐标。最后的输出是 7730,这个 30 前面也解释过了,77 是 grid cell 的数量。**这里注意下实现的细节可能人人都不大一样,比如对 inception 的改动,最后几层的全连接层的改动等等,但是重点在于最后一层的输出是 7730。*
另外两个小细节:1、作者先在 ImageNet 数据集上预训练网络,而且网络只采用 fig3 的前面 20 个卷积层,输入是 224224 大小的图像。然后在检测的时候再加上随机初始化的 4 个卷积层和 2 个全连接层,同时输入改为更高分辨率的 448448。2、Relu 层改为 pRelu,即当 x<0 时,激活值是 0.1*x,而不是传统的 0。
损失函数方面,作者采用 sum-squared error 的方式把 localization error(bounding box 的坐标误差)和 classificaton error 整合在一起。但是如果二者的权值一致,容易导致模型不稳定,训练发散。因为很多 grid cell 是不包含物体的,这样的话很多 grid cell 的 confidence score 为 0。所以采用设置不同权重方式来解决,一方面提高 localization error 的权重,另一方面降低没有 object 的 box 的 confidence loss 权值,loss 权重分别是 5 和 0.5。而对于包含 object 的 box 的 confidence loss 权值还是原来的 1。详见下面的原文解释和 loos function 函数。
这里详细讲一下 loss function。在 loss function 中,前面两行表示 localization error(即坐标误差),第一行是 box 中心坐标 (x,y) 的预测,第二行为宽和高的预测。这里注意用宽和高的开根号代替原来的宽和高,这样做主要是因为相同的宽和高误差对于小的目标精度影响比大的目标要大。举个例子,原来 w=10,h=20,预测出来 w=8,h=22,跟原来 w=3,h=5,预测出来 w1,h=7 相比,其实前者的误差要比后者小,但是如果不加开根号,那么损失都是一样:4+4=8,但是加上根号后,变成 0.15 和 0.7。
第三、四行表示 bounding box 的 confidence 损失,就像前面所说的,分成 grid cell 包含与不包含 object 两种情况。这里注意下因为每个 grid cell 包含两个 bounding box,所以只有当 ground truth 和该网格中的某个 bounding box 的 IOU 值最大的时候,才计算这项。
第五行表示预测类别的误差,注意前面的系数只有在 grid cell 包含 object 的时候才为 1。
所以具体实现的时候是什么样的过程呢?
训练的时候:输入 N 个图像,每个图像包含 M 个 objec,每个 object 包含 4 个坐标(x,y,w,h)和 1 个 label。然后通过网络得到 7730 大小的三维矩阵。每个 1*30 的向量前 5 个元素表示第一个 bounding box 的 4 个坐标和 1 个 confidence,第 6 到 10 元素表示第二个 bounding box 的 4 个坐标和 1 个 confidence。最后 20 个表示这个 grid cell 所属类别。注意这 30 个都是预测的结果。然后就可以计算损失函数的第一、二 、五行。至于第二三行,confidence 可以根据 ground truth 和预测的 bounding box 计算出的 IOU 和是否有 object 的 0,1 值相乘得到。真实的 confidence 是 0 或 1 值,即有 object 则为 1,没有 object 则为 0。 这样就能计算出 loss function 的值了。
测试的时候:输入一张图像,跑到网络的末端得到 7730 的三维矩阵,这里虽然没有计算 IOU,但是由训练好的权重已经直接计算出了 bounding box 的 confidence。然后再跟预测的类别概率相乘就得到每个 bounding box 属于哪一类的概率。
YOLO 算法的缺点:
1、位置精确性差,对于小目标物体以及物体比较密集的也检测不好,比如一群小鸟。
2、YOLO 虽然可以降低将背景检测为物体的概率,但同时导致召回率较低。
问题:
一个 grid cell 中是否有 object 怎么界定?
首先要明白 grid cell 的含义,以文中 77 为例,这个 size 其实就是对输入图像(假设是 224224)不断提取特征然后 sample 得到的(缩小了 32 倍),然后就是把输入图像划分成 7*7 个 grid cell,这样输入图像中的 32 个像素点就对应一个 grid cell。回归正题,那么我们有每个 object 的标注信息,也就是知道每个 object 的中心点坐标在输入图像的哪个位置,那么不就相当于知道了每个 object 的中心点坐标属于哪个 grid cell 了吗,而只要 object 的中心点坐标落在哪个 grid cell 中,这个 object 就由哪个 grid cell 负责预测,也就是该 grid cell 包含这个 object。另外由于一个 grid cell 会预测两个 bounding box,实际上只有一个 bounding box 是用来预测属于该 grid cell 的 object 的,因为这两个 bounding box 到底哪个来预测呢?答案是:和该 object 的 ground truth 的 IOU 值最大的 bounding box。
参考资料:
1、https://docs.google.com/presentation/d/1aeRvtKG21KHdD5lg6Hgyhx5rPq_ZOsGjG5rJ1HP7BbA/pub?start=false&loop=false&delayms=3000&slide=id.p
2、http://blog.csdn.net/tangwei2014/article/details/50915317
3、https://zhuanlan.zhihu.com/p/25236464
4、https://zhuanlan.zhihu.com/p/24916786
https://blog.csdn.net/u014380165/article/details/72616238?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-4.channel_param&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-4.channel_param