在YOLOv1提出之前,R-CNN系列算法在目标检测领域独占鳌头。R-CNN系列检测精度高,但是由于其网络结构是双阶段(two-stage)的特点,使得它的检测速度不能满足实时性,饱受诟病。为了打破这一僵局,设计一种速度更快的目标检测器是大势所趋。
2016年,Joseph Redmon、Santosh Divvala、Ross Girshick等人提出了一种单阶段(one-stage)的目标检测网络。它的检测速度非常快,每秒可以处理45帧图片,能够轻松地实时运行。由于其速度之快和其使用的特殊方法,作者将其取名为:You Only Look Once(也就是我们常说的YOLO的全称),并将该成果发表在了CVPR 2016上,从而引起了广泛地关注。
YOLO 的核心思想就是把目标检测转变成一个回归问题,利用整张图作为网络的输入,仅仅经过一个神经网络,得到bounding box(边界框) 的位置及其所属的类别。
现在看来,YOLOv1的网路结构非常明晰,是一种传统的one-stage的卷积神经网络:
(1)检测策略
YOLOv1采用的是“分而治之”的策略,将一张图片平均分成7×7个网格,每个网格分别负责预测中心点落在该网格内的目标。回忆一下,在Faster R-CNN中,是通过一个RPN来获得目标的感兴趣区域,这种方法精度高,但是需要额外再训练一个RPN网络,这无疑增加了训练的负担。在YOLOv1中,通过划分得到了7×7个网格,这49个网格就相当于是目标的感兴趣区域。通过这种方式,我们就不需要再额外设计一个RPN网络,这正是YOLOv1作为单阶段网络的简单快捷之处!
具体实现过程如下:
在实际过程中,YOLOv1把一张图片划分为了7×7个网格,并且每个网格预测2个Box(Box1和Box2),20个类别。所以实际上,S=7,B=2,C=20。那么网络输出的shape也就是:7×7×30。
(2)目标损失函数
(1)优点:
(2)局限:
2017年,作者 Joseph Redmon 和 Ali Farhadi 在 YOLOv1 的基础上,进行了大量改进,提出了 YOLOv2 和 YOLO9000。重点解决YOLOv1召回率和定位精度方面的不足。
YOLOv2 是一个先进的目标检测算法,比其它的检测器检测速度更快。除此之外,该网络可以适应多种尺寸的图片输入,并且能在检测精度和速度之间进行很好的权衡。
相比于YOLOv1是利用全连接层直接预测Bounding Box的坐标,YOLOv2借鉴了Faster R-CNN的思想,引入Anchor机制。利用K-means聚类的方法在训练集中聚类计算出更好的Anchor模板,大大提高了算法的召回率。同时结合图像细粒度特征,将浅层特征与深层特征相连,有助于对小尺寸目标的检测。
YOLO9000 使用 WorldTree 来混合来自不同资源的训练数据,并使用联合优化技术同时在ImageNet和COCO数据集上进行训练,能够实时地检测超过9000种物体。由于 YOLO9000 的主要检测网络还是YOLOv2,所以这部分以讲解应用更为广泛的YOLOv2为主。
YOLOv2 采用 Darknet-19 作为特征提取网络,其整体结构如下:
改进后的YOLOv2: Darknet-19,总结如下:
注:如果想了解降维的思想,可以戳戳:TF2.0深度学习实战(六):搭建GoogLeNet卷积神经网络,对文章中1×1卷积核降维部分细看。
为了更好的说明,这里我将 Darknet-19 与 YOLOv1、VGG16网络进行对比:
(1)Batch Normalization
Batch Normalization 简称 BN ,意思是批量标准化。2015年由 Google 研究员在论文《Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift》中提出。
BN 对数据进行预处理(统一格式、均衡化、去噪等)能够大大提高训练速度,提升训练效果。基于此,YOLOv2 对每一层输入的数据都进行批量标准化,这样网络就不需要每层都去学数据的分布,收敛会变得更快。
BN算法实现:
在卷积或池化之后,激活函数之前,对每个数据输出进行标准化,实现方式如下图所示:
如上图所示,前三行是对Batch进行数据归一化(如果一个Batch中有训练集每个数据,那么同一Batch内数据近似代表了整体训练数据),第四行引入了附加参数 γ 和 β,这两个参数的具体取值可以参考上面提到的 Batch Normalization 这篇论文。
想更深入了解 Batch Normalization 的原理和应用,可以参见我的:深度学习理论专栏——Batch Normalization
(2)引入 Anchor Box 机制
在YOLOv1中,作者设计了端对端的网路,直接对边界框的位置(x, y, w, h)进行预测。这样做虽然简单,但是由于没有类似R-CNN系列的推荐区域,所以网络在前期训练时非常困难,很难收敛。于是,自YOLOv2开始,引入了 Anchors box 机制,希望通过提前筛选得到的具有代表性先验框Anchors,使得网络在训练时更容易收敛。
在 Faster R-CNN 算法中,是通过预测 bounding box 与 ground truth 的位置偏移值 t x , t y t_x, t_yt**x,t**y,间接得到bounding box的位置。其公式如下:
这个公式是无约束的,预测的边界框很容易向任何方向偏移。因此,每个位置预测的边界框可以落在图片任何位置,这会导致模型的不稳定性。
因此 YOLOv2 在此方法上进行了一点改变:预测边界框中心点相对于该网格左上角坐标( C x , C y ) (C_x, C_y)(C**x,C**y)的相对偏移量,同时为了将bounding box的中心点约束在当前网格中,使用 sigmoid 函数将 t x , t y t_x, t_yt**x,t**y 归一化处理,将值约束在0-1,这使得模型训练更稳定。
下图为 Anchor box 与 bounding box 转换示意图,其中蓝色的是要预测的bounding box,黑色虚线框是Anchor box。
YOLOv2 在最后一个卷积层输出 13×13 的 feature map,意味着一张图片被分成了13×13个网格。每个网格有5个anchor box来预测5个bounding box,每个bounding box预测得到5个值:t x 、 t y 、 t w 、 t h t_x、t_y、t_w、t_ht**x、t**y、t**w、t**h 和 t o t_ot**o(类似YOLOv1的confidence)。引入Anchor Box 机制后,通过间接预测得到的 bounding box 的位置的计算公式为:
置信度 t o t_ot**o的计算公式为:
(3)Convolution With Anchor Boxes
YOLOv1 有一个致命的缺陷就是:一张图片被分成7×7的网格,一个网格只能预测一个类,当一个网格中同时出现多个类时,就无法检测出所有类。针对这个问题,YOLOv2做出了相应的改进:
(4)聚类方法选择Anchors
Faster R-CNN 中 Anchor Box 的大小和比例是按经验设定的,不具有很好的代表性。若一开始就选择了更好的、更有代表性的先验框Anchor Boxes,那么网络就更容易学到准确的预测位置了!
YOLOv2 使用 K-means 聚类方法得到 Anchor Box 的大小,选择具有代表性的尺寸的Anchor Box进行一开始的初始化。传统的K-means聚类方法使用标准的欧氏距离作为距离度量,这意味着大的box会比小的box产生更多的错误。因此这里使用其他的距离度量公式。聚类的目的是使 Anchor boxes 和临近的 ground truth boxes有更大的IOU值,因此自定义的距离度量公式为 :
到聚类中心的距离越小越好,但IOU值是越大越好,所以使用 1 - IOU;这样就保证距离越小,IOU值越大。具体实现方法如下:
如下图所示,是论文中的聚类效果,其中紫色和灰色也是分别表示两个不同的数据集,可以看出其基本形状是类似的。
从下表可以看出,YOLOv2采用5种 Anchor 比 Faster R-CNN 采用9种 Anchor 得到的平均 IOU 还略高,并且当 YOLOv2 采用9种时,平均 IOU 有显著提高。说明 K-means 方法的生成的Anchor boxes 更具有代表性。为了权衡精确度和速度的开销,最终选择K=5。
(5)Fine-Grained Features
细粒度特征,可理解为不同层之间的特征融合。YOLOv2通过添加一个Passthrough Layer,把高分辨率的浅层特征连接到低分辨率的深层特征(把特征堆积在不同Channel中)而后进行融合和检测。具体操作是:先获取前层的26×26的特征图,将其同最后输出的13×13的特征图进行连接,而后输入检测器进行检测(而在YOLOv1中网络的FC层起到了全局特征融合的作用),以此来提高对小目标的检测能力。
Passthrough层与ResNet网络的shortcut类似,以前面更高分辨率的特征图为输入,然后将其连接到后面的低分辨率特征图上。前面的特征图维度是后面的特征图的2倍,passthrough层抽取前面层的每个2×2的局部区域,然后将其转化为channel维度,对于26×26×512的特征图,经Passthrough层处理之后就变成了13×13×2048的新特征图(特征图大小降低4倍,而channles增加4倍),这样就可以与后面的13×13×1024特征图连接在一起形成13×13×3072的特征图,然后在此特征图基础上卷积做预测。示意图如下:
在VOC2007数据集上进行测试,YOLOv2在速度为67fps时,精度可以达到76.8的mAP;在速度为40fps时,精度可以达到78.6
的mAP 。可以很好的在速度和精度之间进行权衡。下图是YOLOv1在加入各种改进方法后,检测性能的改变。可见在经过多种改进方法后,YOLOv2在原基础上检测精度具有很大的提升!
2018年,作者 Redmon 又在 YOLOv2 的基础上做了一些改进。特征提取部分采用darknet-53网络结构代替原来的darknet-19,利用特征金字塔网络结构实现了多尺度检测,分类方法使用逻辑回归代替了softmax,在兼顾实时性的同时保证了目标检测的准确性。
从YOLOv1到YOLOv3,每一代性能的提升都与backbone(骨干网络)的改进密切相关。在YOLOv3中,作者不仅提供了darknet-53,还提供了轻量级的tiny-darknet。如果你想检测精度与速度兼具,可以选择darknet-53作为backbone;如果你希望达到更快的检测速度,精度方面可以妥协,那么tiny-darknet是你很好的选择。总之,YOLOv3的灵活性使得它在实际工程中得到很多人的青睐!
相比于 YOLOv2 的 骨干网络,YOLOv3 进行了较大的改进。借助残差网络的思想,YOLOv3 将原来的 darknet-19 改进为darknet-53。论文中给出的整体结构如下:
Darknet-53主要由1×1和3×3的卷积层组成,每个卷积层之后包含一个批量归一化层和一个Leaky ReLU,加入这两个部分的目的是为了防止过拟合。卷积层、批量归一化层以及Leaky ReLU共同组成Darknet-53中的基本卷积单元DBL。因为在Darknet-53中共包含53个这样的DBL,所以称其为Darknet-53。
为了更加清晰地了解darknet-53的网络结构,可以看下面这张图:
为了更好的理解此图,下面我将主要单元进行说明:
与darknet-19对比可知,darknet-53主要做了如下改进:
YOLOv3最大的改进之处还在于网络结构的改进,由于上面已经讲过。因此下面主要对其它改进方面进行介绍:
(1)多尺度预测
为了能够预测多尺度的目标,YOLOv3 选择了三种不同shape的Anchors,同时每种Anchors具有三种不同的尺度,一共9种不同大小的Anchors。在COCO数据集上选择的9种Anchors的尺寸如下图红色框所示:
借鉴特征金字塔网的思想,YOLOv3设计了3种不同尺度的网络输出Y1、Y2、Y3,目的是预测不同尺度的目标。由于在每一个尺度网格都负责预测3个边界框,且COCO数据集有80个类。所以网络输出的张量应该是:N ×N ×[3∗(4 + 1 + 80)]。由下采样次数不同,得到的N不同,最终Y1、Y2、Y3的shape分别为:[13, 13, 255]、[26, 26, 255]、[52, 52, 255]。可见参见原文:
(2)损失函数
对于神经网络来说,损失函数的设计也非常重要。但是YOLOv3这篇文中并没有直接给出损失函数的表达式。下面通过对源码的分析,给出YOLOv3的损失函数表达式:
对比YOLOv1中的损失函数很容易知道:位置损失部分并没有改变,仍然采用的是sum-square error的损失计算方法。但是置信度损失和类别预测均由原来的sum-square error改为了交叉熵的损失计算方法。对于类别以及置信度的预测,使用交叉熵的效果应该更好!
(3)多标签分类
YOLOv3在类别预测方面将YOLOv2的单标签分类改进为多标签分类,在网络结构中将YOLOv2中用于分类的softmax层修改为逻辑分类器。在YOLOv2中,算法认定一个目标只从属于一个类别,根据网络输出类别的得分最大值,将其归为某一类。然而在一些复杂的场景中,单一目标可能从属于多个类别。
比如在一个交通场景中,某目标的种类既属于汽车也属于卡车,如果用softmax进行分类,softmax会假设这个目标只属于一个类别,这个目标只会被认定为汽车或卡车,这种分类方法就称为单标签分类。如果网络输出认定这个目标既是汽车也是卡车,这就被称为多标签分类。
为实现多标签分类就需要用逻辑分类器来对每个类别都进行二分类。逻辑分类器主要用到了sigmoid函数,它可以把输出约束在0到1,如果某一特征图的输出经过该函数处理后的值大于设定阈值,那么就认定该目标框所对应的目标属于该类。
如下图所示,是各种先进的目标检测算法在COCO数据集上测试结果。很明显,在满足检测精度差不都的情况下,YOLOv3具有更快的推理速度!
如下表所示,对不同的单阶段和两阶段网络进行了测试。通过对比发现,YOLOv3达到了与当前先进检测器的同样的水平。检测精度最高的是单阶段网络RetinaNet,但是YOLOv3的推理速度比RetinaNet快得多。
今年(2020年)YOLO系列的作者Redmon在推特上发表声明,出于道德方面的考虑,从此退出CV界。听到此消息的我,为之震惊!本以为YOLOv3已经是YOLO系列的终局之战。没想到就在今年,Alexey Bochkovskiy等人与Redmon取得联系,正式将他们的研究命名为YOLOv4。
YOLOv4对深度学习中一些常用Tricks进行了大量的测试,最终选择了这些有用的Tricks:WRC、CSP、CmBN、SAT、 Mish activation、Mosaic data augmentation、CmBN、DropBlock regularization 和 CIoU loss。
YOLOv4在传统的YOLO基础上,加入了这些实用的技巧,实现了检测速度和精度的最佳权衡。实验表明,在Tesla V100上,对MS COCO数据集的实时检测速度达到65 FPS,精度达到43.5%AP。
YOLOv4的独到之处在于:
最简单清晰的表示: YOLOv4 = CSPDarknet53(主干) + SPP附加模块(颈) + PANet路径聚合(颈) + YOLOv3(头部)
完整的网络结构图如下:
YOLOv4的网络结构是由 CSPDarknet53、 SPP、 PANet、YOLOv3头部等组成,下面对各部分逐一讲解:
(1)CSPDarknet53
在YOLOv4中,将CSPDarknet53作为主干网络。在了解CSPDarknet53之前,需要先介绍下CSPNet。
CSPNet来源于这篇论文:《CSPNET: A NEW BACKBONE THAT CAN ENHANCE LEARNING CAPABILITY OF CNN》
CSPNet开源地址: https://github.com/WongKinYiu/CrossStagePartialNetworks
CSPNet全称是Cross Stage Partial Network,在2019年由Chien-Yao Wang等人提出,用来解决以往网络结构需要大量推理计算的问题。作者将问题归结于网络优化中的重复梯度信息。CSPNet在ImageNet dataset和MS COCO数据集上有很好的测试效果,同时它易于实现,在ResNet、ResNeXt和DenseNet网络结构上都能通用。
CSPNet的主要目的是能够实现更丰富的梯度组合,同时减少计算量。这个目标是通过将基本层的特征图分成两部分,然后通过一个跨阶段的层次结构合并它们来实现的。
而在YOLOv4中,将原来的Darknet53结构换为了CSPDarknet53,这在原来的基础上主要进行了两项改变:
(2)SPP
SPP来源于这篇论文:Spatial Pyramid Pooling in Deep Convolutional Networks for Visual Recognition
SPP最初的设计目的是用来使卷积神经网络不受固定输入尺寸的限制。在YOLOv4中,作者引入SPP,是因为它显著地增加了感受野,分离出了最重要的上下文特征,并且几乎不会降低的YOLOv4运行速度。如下图所示,就是SPP中经典的空间金字塔池化层。
在YOLOv4中,具体的做法就是:分别利用四个不同尺度的最大池化对上层输出的feature map进行处理。最大池化的池化核大小分别为13x13、9x9、5x5、1x1,其中1x1就相当于不处理。
(3)PANet
论文链接:《Path Aggregation Network for Instance Segmentation》
这篇文章发表于CVPR2018,它提出的Path Aggregation Network (PANet)既是COCO2017实例分割比赛的冠军,也是目标检测比赛的第二名。PANet整体上可以看做是在Mask R-CNN上做多处改进,充分利用了特征融合,比如引入Bottom-up path augmentation结构,充分利用网络浅特征进行分割;引入Adaptive feature pooling使得提取到的ROI特征更加丰富;引入Fully-conneFcted fusion,通过融合一个前背景二分类支路的输出得到更加精确的分割结果。
下图是PANet的示意图,主要包含FPN、Bottom-up path augmentation、Adaptive feature pooling、Fully-connected fusion四个部分。
在YOLOv4中,作者使用PANet代替YOLOv3中的FPN作为参数聚合的方法,针对不同的检测器级别从不同的主干层进行参数聚合。并且对原PANet方法进行了修改, 使用张量连接(concat)代替了原来的捷径连接(shortcut connection)。
(4)YOLOv3 Head
在YOLOv4中,继承了YOLOv3的Head进行多尺度预测,提高了对不同size目标的检测性能。YOLOv3的完整结构在上文已经详细介绍,下面我们截取了YOLOv3的Head进行分析:
YOLOv4学习了YOLOv3的方式,采用三个不同层级的特征图进行融合,并且继承了YOLOv3的Head。从上图可以看出,在COCO数据集上训练时,YOLOv4的3个输出张量的shape分别是:(19,19,225)、(38,38,255)、(76,76,225)。这是因为COCO有80个类别,并且每一个网格对应3个Anchor boxes,而每个要预测的bounding box对应的5个值(t x 、 t y 、 t w 、 t h t_x、t_y、t_w、t_ht**x、t**y、t**w、t**h 、t o t_ot**o),所以有:3 x (80+5)=255 。
作者将所有的Tricks可以分为两类:
下面分别对这两类技巧进行介绍。
(1)免费包
以数据增强方法为例,虽然增加了训练时间,但不增加推理时间,并且能让模型泛化性能和鲁棒性更好。像这种不增加推理成本,还能提升模型性能的方法,作者称之为"免费包",非常形象。下面总结了一些常用的数据增强方法:
常见的正则化方法有:
平衡正负样本的方法有:
除此之外,还有回归 损失方面的改进:
(2)特价包
增大感受野技巧:
注意力机制:
特征融合集成:
更好的激活函数:
后处理非极大值抑制算法:
除了下面已经提到的各种Tricks,为了使目标检测器更容易在单GPU上训练,作者也提出了5种改进方法:
(1)Mosaic
这是作者提出的一种新的数据增强方法,该方法借鉴了CutMix数据增强方式的思想。CutMix数据增强方式利用两张图片进行拼接,但是Mosaic使利用四张图片进行拼接。如下图所示:
Mosaic数据增强方法有一个优点:拥有丰富检测目标的背景,并且在BN计算的时候一次性会处理四张图片!
(2)SAT
SAT是一种自对抗训练数据增强方法,这一种新的对抗性训练方式。在第一阶段,神经网络改变原始图像而不改变网络权值。以这种方式,神经网络对自身进行对抗性攻击,改变原始图像,以制造图像上没有所需对象的欺骗。在第二阶段,用正常的方法训练神经网络去检测目标。
(3)CmBN
CmBN的全称是Cross mini-Batch Normalization,定义为跨小批量标准化(CmBN)。CmBN 是 CBN 的改进版本,它用来收集一个batch内多个mini-batch内的统计数据。BN、CBN和CmBN之间的区别具体如下图所示:
(4)修改过的SAM
作者在原SAM(Spatial Attention Module)方法上进行了修改,将SAM从空间注意修改为点注意。如下图所示,对于常规的SAM,最大值池化层和平均池化层分别作用于输入的feature map,得到两组shape相同的feature map,再将结果输入到一个卷积层,接着是一个 Sigmoid 函数来创建空间注意力。
将SAM(Spatial Attention Module)应用于输入特征,能够输出精细的特征图。
在YOLOv4中,对原来的SAM方法进行了修改。如下图所示,修改后的SAM直接使用一个卷积层作用于输入特征,得到输出特征,然后再使用一个Sigmoid 函数来创建注意力。作者认为,采用这种方式创建的是点注意力。
(5)修改过的PAN
作者对原PAN(Path Aggregation Network)方法进行了修改, 使用张量连接(concat)代替了原来的快捷连接(shortcut connection)。如下图所示:
注:想具体了解原PANet网络结构,可参考上文中的PANet介绍部分。
如下图所示,在COCO目标检测数据集上,对当前各种先进的目标检测器进行了测试。可以发现,YOLOv4的检测速度比EfficientDet快两倍,性能相当。同时,将YOLOv3的AP和FPS分别提高10%和12%,吊打YOLOv3!
综合以上分析,总结出YOLOv4带给我们的优点有: