目标检测是一件比较实际的且具有挑战性的计算机视觉任务,其可以看成图像分类与定位的结合,给定一张图片,目标检测系统要能够识别出图片的目标并给出其位置,由于图片中目标数是不定的,且要给出目标的精确位置,目标检测相比分类任务更复杂。目标检测的一个实际应用场景就是无人驾驶,如果能够在无人车上装载一个有效的目标检测系统,那么无人车将和人一样有了眼睛,可以快速地检测出前面的行人与车辆,从而作出实时决策。
本文的内容如下:
YOLO的全称叫做“You Only Look Once”,简单来说,YOLO可以做到将一张图片输入,直接输出最终结果,包括框和框内物体的名称及score(得分)。而很多其他检测方法如Faster R-CNN便是通过两次检测来达到目的。具体的两次检测过程如下所述:
因此,Region Proposal的作用为:
YOLO的优势是:不需要region proposal,所谓的region proposal即需要进行多于一次的识别过程。以Faster R-CNN为代表的目标检测的方法就是两次检测的过程。
这边我们提到了边界框,边界框的大小和位置用4个值来表示:(x,y,w,h),其中(x, y)是边界框的中心坐标,w和h是边界框的宽与高。具体来说,(x, y)是相对于每个单元格左上角坐标点偏移值,并且单位是相对于单元格大小的,而w和h预测值是相对于整个图片的宽和高的比例,这样理论上4个元素的大小在[0, 1]范围内,而且每个边界框的预测值实际上包含5个元素:(x, y, w, h, c)。前四个元素表征边界框的大小和位置,最后一个值是置信度。
总结一下:
每个单元格需要预测(B*5+C)个值。输入的图片为S x S网络,因此最终的预测值为S x S x (B x 5 + C)大小的张量,在论文里给出的例子为S=7,B=2, 因此最终的张量大小为7 x 7 x 30。
Yolo采用卷积网络来提取特征,然后使用全连接层来得到预测值。网络结构参考GooLeNet模型(2014年Christian Szegedy提出的一种全新的深度学习结构)。YOLO检测层包含24个卷积层和2个全连接层。
(这里一开始我数不出来为什么有24个卷积层,其实要仔细看图,你会发现有一些“x4” “x2”,把这些考虑进去你就会发现确实是24层)
最后得到的7 x 7 x 30 代表的是最后的输出,代表一共49个cell,每个cell拥有30个值,其中有20个值为类别概率值,即该cell检测出来的属于某类物体的概率。而剩下的10个值可以分成两部分,分表代表cell两个Bounding Box各自的参数部分。
我们取一个cell来看,一个cell有30个元素,如图所示:
如果在grid cell里没有物体存在,则Pr(object)=0,存在的意思是指物体的ground truth中心点在这个cell里面。另外我们发现,一个grid cell里面虽然有两个Bounding Box, 但是它们共享同一组分类概率,因此同一个cell只能识别同一个物体。
边界框的大小和位置用4个值来表示:(x, y, w, h), 其中(x,y)是边界框的中心坐标,w和h是边界框的宽与高。(x, y)是相对于每个单元格左上角坐标点偏移值,并且单位是相对于单元格大小的,而w和h预测值是相对于整个图片的宽和高的比例,这样理论上4个元素的大小在[0, 1]范围内,而且每个边界框的预测值实际上包含5个元素:(x, y, w, h, c)。前四个元素表征边界框的大小和位置,最后一个值是置信度。
LOSS函数和其他神经网络一样,是优化的目标,在yolo v1里LOSS函数相当复杂,大体可以分为三部分,下面具体介绍一下LOSS函数:
为了便于说明,我们将各部分用不同颜色圈起来:
除此之外,针对各项的系数,还有一些tips:
训练的最终结果是得到一个网络,网络参数是根据不停地优化LOSS函数而得到的。
训练:训练集的图片都进行各个物体的人工标注(4个顶点的坐标),通过运算,得到x y w h,然后图片被分成S x S个小格,针对每个小格有b个BBOX,然后经过优化LOSS,不停地使得BBOX逼近Ground Truth。
测试:利用训练好的网络,输入图片,直接给出box和对应的物体。
训练过程:
测试过程:
输入图片,网络会按照与训练时相同的分割方式将测试图片分割成S x S的形状,因此,划分出来的每个网格预测的class信息和Bounding box预测的confidence信息相乘,就得到了每个Bounding box的class-specific confidence score,即得到了每个Bounding box预测具体物体的概率和位置重叠的概率。
对于98个Bounding Box都这么运算,最后可以得到:
每个“条”一共有20个值,分别是20个物体的得分,因此一共有98*20个值,我们按照类别把它们分为20类。之后的过程如下(先以第一类假设为“dog”举例):
直观来感受一下非极大值抑制的过程:
非极大值抑制:抑制的过程是一个迭代-遍历-消除的过程。
1.将所有框的得分排序,选中最高分及其对应的框。
2.遍历其余的框,如果和当前最高分框的重叠面积(IOU)大于一定阈值,我们就将框删除。
3.从未处理的框中继续选一个得分最高的,重复上述过程。
(具体可见其他博主整理,或者bilibili yolov1讲解)
针对其他类别,比如cat,vehicle等,均采用这种方式,直到将所有的score值得到。
然后,针对每一个Bounding Box,查看其最大的值,如果在20个值里面最大值非0,那么我们就把这个bounding box认定为是识别对应物体的框。
当然,yolo v1有相当的缺陷: