You Only Look Once: Unified, Real-Time Object Detection
YOLOv1
早期检测任务是用分类的方法来做定位,一般分为两个阶段。YOLOv1直接把检测问题作为回归问题来做,在一次推断中直接能端到端(一阶段)得到边界框(bounding boxes)和分类概率。Fast YOLO的速度是当时其他实时检测网络的n倍,mAP也是至少2倍。YOLOv1在艺术品检测方面比DPM和R-CNN好,不过作者承认自己总体检测精度和SOTA的相比还是稍微有点落后。
本文提及R-CNN先使用region proposal方法来得到潜在的边界框,然后对这些框进行分类,再后面进行坐标值的微调,重新计算框的得分,使得结果更加精确。但是R-CNN有个缺点就是训练是分多个步骤进行的,相比之下YOLOv1可以直接端到端训练一个神经网络即可。YOLOv1的推断速度非常快,即使不使用batch运算,在一块 Titan X GPU上的运行速度是45 fps,而Fast YOLO版本能达到150 fps。
YOLOv1最主要是思想是,网络的输出的特征形状是 S × S S\times S S×S个像素点(先不考虑channel),其可以对应到输入图像的 S × S S\times S S×S的格子(grid,其中每个grid包含一片像素区域,简单理解就是最终输出的像素点映射到输入就是一小片像素区域,这里一定要好好理解一下,不然下面都看不懂!),如果某个物体的中心落在某个格子中,那么就由这个格子来负责检测这个物体。每个格子负责B个边界框和格子的自信度(confidence),自信度可以理解为这里多大概率是可以预测到这个物体。自信度的计算方法是 r ( O b j e c t ) ∗ I O U p r e d t r u t h {r(Object)*IOU^{truth}_{pred}} r(Object)∗IOUpredtruth,如果不存在物体这个值就是0。
每个格子有5个预测值,即(x, y, w, h, confidence),其中(x, y)表示落在这个grid单元的物体中心。(w, h)就表示这个物体的宽高,最后的(confidence)就表示上面提到的自信度。除此了前面提到的5种值,每个grid还会预测 C C C个类各自的概率 P ( 物 体 属 于 哪 个 类 ) P(物体属于哪个类) P(物体属于哪个类),对于每个grid,无论设置的框个数 B B B为多少,YOLOv1只预测一次这个概率(这个也是YOLOv1一个很大的缺陷,对于图像中有密集型物体,基本无能为力)。
如上图所示第一张图有 S × S S\times S S×S的格子,注意事实上YOLOv1用的是一种没那么直观的映射方法,其不是实际在输入图上进行了格子划分,而是认为一个 S × S S\times S S×S的输出恰好就完成了这种划分任务。比如假设原图尺寸是 448 × 448 × 3 448\times 448\times 3 448×448×3,那么经过网络的各种池化、卷积,最终在网络末端生成了 S × S × ( B ∗ 5 + C ) S\times S\times(B*5+C) S×S×(B∗5+C)维度的特征映射层,实际上就是假想是对原图了进行了一个grid的划分(再次注意实际上并没做任何预处理,网络是end to end的)。从最终的输出层看,每个grid(实际维度是 1 × 1 × ( B ∗ 5 + C ) 1\times 1\times(B*5+C) 1×1×(B∗5+C),共有 S × S S\times S S×S个)根据比例缩放关系,负责回原图对应格子上的物体检测任务。
YOLOv1在 PASCAL VOC上设定 B = 2 B=2 B=2, S = 7 S=7 S=7,由于该数据集共有20个类,所以网络的输出是一个 7 × 7 × 30 7\times 7\times 30 7×7×30的向量(每个 1 × 1 × 30 1\times 1\times 30 1×1×30的向量相当于负责输入图像的一个grid,共有 7 × 7 7\times 7 7×7个这种向量,每个向量与输入图像具有很强的对应关系)。
YOLOv1的网络结构是参考了GoogLeNet,前面用了24个卷积层,后面连了两个全连接层,除了最后一层用的普通线性激活单元,其余层用的是泄露值为0.1的leaky RELU。作者顺便训练了一个Fast YOLO版本,但只是把24个卷积层换成了9个,其它参数设定和训练过程均与YOLOv1 baseline的设定都是一样的。
网络在实际训练的时候用了在ImageNet上训练过的模型作为预训练模型,图像的输入分辨率为
224
×
224
224\times 224
224×224,只训练了前20个卷积层,用的是自己写的Darknet框架。在fine tune的时候又在20个层的基础上添加了剩余的4个卷积层,而且分辨率也扩大到
448
×
448
448\times 448
448×448。这里有个细节,生成的边界框的(w, h)是图像宽高的一个比值,所以其大小在0和1之间。另外边界框的(x, y)坐标也是某个对应grid的补偿,所以这个值也是在0和1之间。
在计算loss的时候,用的是平方和误差,因为这个误差简单粗暴好优化。不过也有一些缺点,不如对定位误差和分类误差采取相同的误差计算方式并不太合适。而且如果一个grid不包含任何物体,这个格子的confidence就是0,其在计算梯度时有碾压那些包含有物体的趋势。为了进行减少这种失衡,作者减少了confidence计算的权重。另外还有一个问题,这种误差计算对于大物体和小物体采取的策略仍旧是一样的,而实际上需要使得在大物体中的小偏差的影响要小于在小物体中的偏差。因此在计算(w,h)的loss的时候,作者直接对宽高取了根号。整体的loss计算方式如下:
里面个那个
1
i
o
b
j
1^{obj}_{i}
1iobj表示物体是否出现在了第i个格子,而
1
i
j
o
b
j
1^{obj}_{ij}
1ijobj则表示第i个格子中的第j个box。前面的
λ
\lambda
λ系数就是表示某种的加权,如坐标损失加权、是否有物体加权。在训练的时候YOLOv1有用上dropout策略,而数据增强采用的是随机缩放(最大到1.2倍),还有在HSV颜色域随机调整因子为1.5的曝光度和饱和度。
在推断的时候,由于多个格子可能对同一相同都进行了预测,这里采用了R-CNN中使用的非极大值抑制策略(NMS),删除了冗余的边界框,使得结果更加清晰精准。
如前面提到,YOLOv1有一个很大缺陷就是不管某个grid的预测了几个box,最终只输出一个,如果实际图片的物体分布很密集,这个算法就会有很大概率漏检。而且YOLOv1很难处理诸如鸟群这种小物体,因此其还有一个很主要的缺点就是错误定位,因为一般来讲同样的偏差大小对于小物体往往比对大物体更有毁灭影响。
在提到一些相关工作时,作者解释传统物体检测方法的第一步一般是先提取一些鲁棒特征,如Haar、SIFT、HOG、卷积特征等,然后才进行分类和定位。这些分类器或者定位器要么是用在滑动窗口上,要么是用于部分通过各种办法挑选好的候选区域。而YOLOv1则直接把这两个步骤合二为一,只用一个神经网络就解决一切,极大加快了计算速度。
除了用上诉提到的baseline网络,本文作者也尝试用VGG-16训练了一个版本,其推断速度当然更慢,所以他们主要还是把中心聚焦于自己提出来的版本。下面这个表是几个代表算法在PASCAL VOC 2007上的检测效果:
YOLOv1在预测背景上要比R-CNN好一些,作者尝试把R-CNN检测后的结果再用YOLO跑一遍,mAP有所提升。
文章具体的一些结果细节就不进行展开了。
YOLOv1总体上还是一篇很具有开创性的文章,其提出了一阶段的检测思想,虽然总体的效果略逊色于二阶段的网络,但其无敌的推断速度,还是具有很强的实用场景。