当咱们谈起计算机视觉时,首先想到的就是图像分类,没错,图像分类是计算机视觉最基本的任务之一,可是在图像分类的基础上,还有更复杂和有意思的任务,如目标检测,物体定位,图像分割等,见图1所示。其中目标检测是一件比较实际的且具备挑战性的计算机视觉任务,其能够当作图像分类与定位的结合,给定一张图片,目标检测系统要可以识别出图片的目标并给出其位置,因为图片中目标数是不定的,且要给出目标的较精确位置,目标检测相比分类任务更复杂。目标检测的一个实际应用场景就是无人驾驶,若是可以在无人车上装载一个有效的目标检测系统,那么无人车将和人同样有了眼睛,能够快速地检测出前面的行人与车辆,从而做出实时决策。
上面尽管能够减小滑动窗口的计算量,可是只是针对一个固定大小与步长的窗口,这是远远不够的。Yolo算法很好的解决了这个问题,它再也不是窗口滑动了,而是直接将原始图片分割成互不重合的小方块,而后经过卷积最后生产这样大小的特征图,基于上面的分析,能够认为特征图的每一个元素也是对应原始图片的一个小方块,而后用每一个元素来能够预测那些中心点在该小方格内的目标,这就是Yolo算法的朴素思想。下面将详细介绍Yolo算法的设计理念。
这就是Yolo算法的朴素思想。下面将详细介绍Yolo算法的设计理念
三、设计理念
总体来看,Yolo算法采用一个单独的CNN模型实现end-to-end的目标检测,整个系统如图5所示:首先将输入图片resize到448x448,而后送入CNN网络,最后处理网络预测结果获得检测的目标。相比R-CNN算法,其是一个统一的框架,其速度更快,并且Yolo的训练过程也是end-to-end的。

具体来讲,Yolo的CNN网络将输入的图片分割成S*S网格,而后每一个单元格负责去检测那些中心点落在该格子内的目标,如图6所示,能够看到狗这个目标的中心落在左下角一个单元格内,那么该单元格负责预测这个狗。每一个单元格会预测B个边界框(bounding box)以及边界框的置信度(confidence score)。所谓置信度其实包含两个方面,一是这个边界框含有目标的可能性大小,二是这个边界框的准确度。前者记为Pr(object),当该边界框是背景时(即不包含目标),此时Pr(object)=0。而当该边界框包含目标时,Pr(object)=1。边界框的准确度能够用预测框与实际框(ground truth)的IOU(intersection over union,交并比)来表征,记为IOU。所以置信度能够定义为Pr(object)*IOU。不少人可能将Yolo的置信度当作边界框是否含有目标的几率,可是其实它是两个因子的乘积,预测框的准确度也反映在里面。边界框的大小与位置能够用4个值来表征:(x,y,h,w),其中(x,y)是边界框的中心坐标,而和是边界框的宽与高。还有一点要注意,中心坐标的预测值(x,y)是相对于每一个单元格左上角坐标点的偏移值,而且单位是相对于单元格大小的,单元格的坐标定义如图6所示。而边界框的w和h预测值是相对于整个图片的宽与高的比例,这样理论上4个元素的大小应该在[0,1]范围。这样,每一个边界框的预测值实际上包含5个元素:(x,y,w,h,c),其中前4个表征边界框的大小与位置,而最后一个值是置信度。算法


总结一下,每一个单元格须要预测(B*5+C)个值。若是将输入图片划分为S*S网格,那么最终预测值为S*S*(B*5+C)大小的张量。整个模型的预测值结构以下图所示。对于PASCALVOC数据,其共有20个类别,若是使用S=7,B=2,那么最终的预测结果就是7*7*30大小的张量。在下面的网络结构中咱们会详细讲述每一个单元格的预测值的分布位置。网络

四、网络设计
Yolo采用卷积网络来提取特征,而后使用全链接层来获得预测值。网络结构参考GooLeNet模型,包含24个卷积层和2个全链接层,如图8所示。对于卷积层,主要使用1x1卷积来作channle reduction,而后紧跟3x3卷积。对于卷积层和全链接层,采用Leaky ReLU激活函数:max(x,0)。可是最后一层却采用线性激活函数。除了上面这个结构,文章还提出了一个轻量级版本Fast Yolo,其仅使用9个卷积层,而且卷积层中使用更少的卷积核。
五、网络训练
在训练以前,先在ImageNet上进行了预训练,其预训练的分类模型采用图8中前20个卷积层,而后添加一个average-pool层和全链接层。预训练以后,在预训练获得的20层卷积层之上加上随机初始化的4个卷积层和2个全链接层。因为检测任务通常须要更高清的图片,因此将网络的输入从224x224增长到了448x448。整个网络的流程以下图所示:

另一点时,因为每一个单元格预测多个边界框。可是其对应类别只有一个。那么在训练时,若是该单元格内确实存在目标,那么只选择与ground truth的IOU较大的那个边界框来负责预测该目标,而其它边界框认为不存在目标。这样设置的一个结果将会使一个单元格对应的边界框更加专业化,其能够分别适用不一样大小,不一样高宽比的目标,从而提高模型性能。你们可能会想若是一个单元格内存在多个目标怎么办,其实这时候Yolo算法就只能选择其中一个来训练,这也是Yolo算法的缺点之一。要注意的一点时,对于不存在对应目标的边界框,其偏差项就是只有置信度,左标项偏差是无法计算的。而只有当一个单元格内确实存在目标时,才计算分类偏差项,不然该项也是没法计算的。
综上讨论,最终的损失函数计算以下:


六、网络预测
在说明Yolo算法的预测过程以前,这里先介绍一下非极大值抑制算法(non maximum suppression, NMS),这个算法不仅仅是针对Yolo算法的,而是全部的检测算法中都会用到。NMS算法主要解决的是一个目标被屡次检测的问题,如图11中人脸检测,能够看到人脸被屡次检测,可是其实咱们但愿最后仅仅输出其中一个较好的预测框,好比对于美女,只想要红色那个检测结果。那么能够采用NMS算法来实现这样的效果:首先从全部的检测框中找到置信度较大的那个框,而后挨个计算其与剩余框的IOU,若是其值大于必定阈值(重合度太高),那么就将该框剔除;而后对剩余的检测框重复上述过程,直处处理完全部的检测框。Yolo预测过程也须要用到NMS算法。

下面就来分析Yolo的预测过程,这里咱们不考虑batch,认为只是预测一张输入图片。根据前面的分析,最终的网络输出是7*7*30,可是咱们能够将其分割成三个部分:类别几率部分为[7,7,20],置信度部分为[7,7,2,2],而边界框部分为[7,7,2,4](对于这部分不要忘记根据原始图片计算出其真实值)。而后将前两项相乘能够获得类别置信度值为[7,7,2,20],这里总共预测了7*7*2=98边界框。
全部的准备数据已经获得了,那么咱们先说第一种策略来获得检测框的结果,我认为这是最正常与天然的处理。首先,对于每一个预测框根据类别置信度选取置信度较大的那个类别做为其预测标签,通过这层处理咱们获得各个预测框的预测类别及对应的置信度值,其大小都是[7,7,2]。通常状况下,会设置置信度阈值,就是将置信度小于该阈值的box过滤掉,因此通过这层处理,剩余的是置信度比较高的预测框。最后再对这些预测框使用NMS算法,最后留下来的就是检测结果。一个值得注意的点是NMS是对全部预测框一视同仁,仍是区分每一个类别,分别使用NMS。Ng在deeplearning.ai中讲应该区分每一个类别分别使用NMS,可是看了不少实现,其实仍是同等对待全部的框,我以为多是不一样类别的目标出如今相同位置这种几率很低吧。
七、算法性能分析
这里看一下Yolo算法在PASCAL VOC 2007数据集上的性能,这里Yolo与其它检测算法作了对比,包括DPM,R-CNN,Fast R-CNN以及Faster R-CNN。其对比结果如表1所示。与实时性检测方法DPM对比,能够看到Yolo算法能够在较高的mAP上达到较快的检测速度,其中Fast Yolo算法比快速DPM还快,并且mAP是远高于DPM。可是相比Faster R-CNN,Yolo的mAP稍低,可是速度更快。因此。Yolo算法算是在速度与准确度上作了折中。
Yolo在PASCAL VOC 2007上与其余算法的对比 框架

如今来总结一下Yolo的优缺点。首先是优势,Yolo采用一个CNN网络来实现检测,是单管道策略,其训练与预测都是end-to-end,因此Yolo算法比较简洁且速度快。第二点因为Yolo是对整张图片作卷积,因此其在检测目标有更大的视野,它不容易对背景误判。其实我以为全链接层也是对这个有贡献的,由于全链接起到了attention的做用。另外,Yolo的泛化能力强,在作迁移时,模型鲁棒性高。
最后不得不谈一下Yolo的缺点,首先Yolo各个单元格仅仅预测两个边界框,并且属于一个类别。对于小物体,Yolo的表现会不如人意。这方面的改进能够看SSD,其采用多尺度单元格。也能够看Faster R-CNN,其采用了anchor boxes。Yolo对于在物体的宽高比方面泛化率低,就是没法定位不寻常比例的物体。固然Yolo的定位不许确也是很大的问题。