YOLO主页 https://pjreddie.com/darknet/yolo/
YOLOv1
论文下载:http://arxiv.org/abs/1506.02640
代码下载:https://github.com/pjreddie/darknet
YOLOv2&YOLO9000
工程代码地址:http://pjreddie.com/darknet/yolo/
代码和预训练模型地址:http://pjreddie.com/yolo9000/
YOLOv3
代码下载:https://github.com/pjreddie/darknet/tree/yolov3
keras:https://github.com/qqwweee/keras-yolo3
tensorflow:https://github.com/wizyoung/YOLOv3_TensorFlow
YOLOv4
论文地址:https://arxiv.org/pdf/2004.10934.pdf
GitHub地址:https://github.com/AlexeyAB/darknet
参考文章:
https://blog.csdn.net/qq_30815237/article/details/91949543
https://blog.csdn.net/guleileo/article/details/80581858
YOLO(You Only Look Once)是一个基于深度学习技术的深度神经网络模型,对图像中目标位置定位与类别的检测,其核心思想是,利用一整张图像作为深度神经网络的输入,网络直接输出回归框(bounding box)的位置及其所属的类别。
优点:模型运行速度快;
end-2-end,直接预测位置与类别,不容易在背景上预测出错误的物体信息
对比RCNN、Fast-RCNN、Faster-RCNN:
RCNN开创性的提出了候选区(Region Proposals)的方法,先从图片中搜索出一些可能存在对象的候选区Selective Search,大概2000个左右,然后对每个候选区进行对象识别。大幅提升了对象识别和定位的效率。不过RCNN的速度依然很慢,其处理一张图片大概需要49秒。因此又有了后续的Fast RCNN 和 Faster RCNN,针对RCNN的神经网络结构和候选区的算法不断改进,Faster RCNN已经可以达到一张图片约0.2秒的处理速度。
二、YOLOv1
7.损失函数
我们输出 预测边框坐标1和 预测边框坐标2,然后计算与实际对象边框的IOU,最大的那个预测边框对应的位置处,把样本标签对应的位置填入实际对象边框
损失函数的设计目标就是让坐标(x,y,w,h)8维,confidence 2维,classification 20维这个三个方面达到很好的平衡。简单的全部采用了sum-squared error loss来做这件事会有以下不足:
bounding box的位置误差 |
|
对象分类的误差 | 公式第5行类别预测参数,意味着存在对象的网格才计入误差。 |
bounding box的置信度误差 |
|
V1 缺陷之处:
- 输入尺寸固定:由于输出层为全连接层,因此在检测时,YOLO 训练模型只支持与训练图像相同的输入分辨率。其它分辨率需要缩放成此固定分辨率;
- 占比小的目标检测效果不好:虽然每个格子可以预测 B 个 bounding box,但是最终只选择 IOU 最高的bbox作为物体检测输出,即每个格子最多只预测出一个物体。当物体占画面比例较小,如图像中包含畜群或鸟群时,每个格子包含多个物体,但却只能检测出其中一个。
针对YOLOv1的缺点进行了优化 ,提出了一种联合训练算法,这种算法是将目标检测数据集与分类数据集混合到一起,使用一种分层的观点对物体进行分类,用巨量的分类数据集数据来扩充检测数据集,从而把两种不同的数据集混合起来。联合训练算法的基本思路就是:同时在检测数据集和分类数据集上训练物体检测器(Object Detectors ),用监测数据集的数据学习物体的准确位置,用分类数据集的数据来增加分类的类别量、提升鲁棒性。
相比于YOLOv1,改进的地方见如下表格:
v1 中也大量用了 Batch Normalization,同时在定位层后边用了 dropout,v2 中取消了 dropout,在卷积层全部使用 Batch Normalization。
目前大部分的检测模型都会先在ImageNet分类数据集上预训练模型的主体部分(CNN特征提取器),ImageNet分类模型基本采用大小为 的图片作为输入,分辨率相对较低。YOLOv1在采用 分类模型预训练后,将分辨率增加至448x448 ,并使用这个高分辨率在检测数据集上finetune。但是直接切换分辨率,检测模型可能难以快速适应高分辨率。 所以YOLOv2增加了在ImageNet数据集上使用448x448输入来finetune分类网络这一中间过程(10 epochs),这可以使得模型在检测数据集上finetune之前已经适用高分辨率输入。
主要使用3x3卷积并在pooling之后channel数加倍(VGG);global average pooling替代全连接做预测分类,并在3x3卷积之间使用1x1卷积压缩特征表示(Network in Network);使用 batch normalization 来提高稳定性,加速收敛,对模型正则化。
YOLOv2去掉了YOLOv1最后的全连接层,v1中直接在卷积层之后使用全连接层预测bbox的坐标,v2借鉴Faster R-CNN的思想预测bbox的偏移,使用 Anchor Boxes 来预测 Bounding Boxes。
首先,作者去掉了后面的一个池化层以确保输出的卷积特征图有更高的分辨率。然后,通过缩减网络,让图片输入分辨率为416 * 416,这一步的目的是为了让后面产生的卷积特征图宽高都为奇数,这样就可以产生一个center cell(yolo使用pooling来下采样,有5个size=2, stride=2的max pooling,而卷积层没有降低大小,因此最后的特征是416/(2^5)=13).。作者观察到,大物体通常占据了图像的中间位置, 就可以只用中心的一个cell来预测这些物体的位置,否则就要用中间的4个cell来进行预测,这个技巧可稍稍提升效率。使用 Anchor Box 会让精确度稍微下降,但用了它能让 YOLO 能预测出大于一千个框,同时 recall 达到88%,mAP 达到 69.2%。
Faster R-CNN中anchor box 的大小和比例是按经验设定的,YOLOv2 对其做了改进,采用 k-means 在训练集 bbox 上进行聚类产生合适的先验框. 由于使用采用标准的 k-means欧氏距离会使较大的 bbox 比小的 bbox 产生更大的误差,而 IOU 与 bbox 尺寸无关, 因此使用 IOU 参与距离计算, 使得通过这些 anchor boxes 获得好的 IOU 分值。距离公式:
算法过程是:将每个bbox的宽和高相对整张图片的比例(wr,hr)进行聚类,得到k个anchor box,将这个比例值乘上卷积层的输出特征的大小.如输入是416x416,那么最后卷积层的特征是13x13。
用 Anchor Box 的方法,会让 model 变得不稳定,尤其是在最开始的几次迭代的时候。大多数不稳定因素产生自预测 Box 的(x,y)位置的时候。按照之前 YOLO的方法,网络不会预测偏移量,而是根据 YOLO 中的网格单元的位置来预测坐标,这就让 Ground Truth 的值介于 0 到 1 之间。而为了让网络的结果能落在这一范围内,网络使用一个 Logistic Activation 来对于网络预测结果进行限制,让结果介于 0 到 1 之间。 网络在每一个网格单元中预测出 5 个 Bounding Boxes,每个 Bounding Boxes 有五个坐标值 tx,ty,tw,th,t0,他们的关系见下图。假设一个网格单元对于图片左上角的偏移量是 cx、cy,Bounding Boxes Prior 的宽度和高度是 pw、ph,那么预测的结果见下图右面的公式:
看上面的网络图,添加了一个直通层(passthrough layer),将前面一层的26*26的特征图和本层13*13的特征图进行连接,与ResNet网络的shortcut类似,以前面更高分辨率的特征图为输入,然后将其连接到后面的低分辨率特征图上。在13*13的特征图上做预测,虽然对于大目标已经足够了,但对小目标不一定足够好,这里合并前面大一点的特征图可以有效的检测小目标。
具体操作:对于26*26*512的特征图,经passthrough层处理之后就变成了13*13*2048的新特征图(特征图大小变为1/4,而通道数变为以前的4倍),然后与后面的13*13*1024特征图连接在一起形成13*13*3072的特征图,最后在该特征图上卷积做预测。
每隔几次迭代后就会微调网络的输入尺寸。训练时每迭代10次,就会随机选择新的输入图像尺寸。因为YOLOv2的网络使用的下采样downsamples倍率为32,所以使用32的倍数调整输入图像尺寸{320,352,…,608}。训练使用的最小的图像尺寸为320 x 320,最大的图像尺寸为608 x 608。这使得网络可以适应多种不同尺度的输入。
各种目标检测模型速度对比如下:
改进之处:
1.多尺度预测 (类FPN)
2.更好的基础分类网络(类ResNet)和分类器 darknet-53,见下图
3.分类器-类别预测。
(1)DBL:Yolov3网络结构中的最小组件,由Conv+BN+Leaky_relu激活函数三者组成。
(2)Res unit:借鉴Resnet网络中的残差结构,让网络可以构建的更深。
(3)ResX:由一个DBL和X个残差组件构成,是Yolov3中的大组件。每个Res模块前面的CBL都起到下采样的作用,因此经过5次Res模块后,得到的特征图是608->304->152->76->38->19大小。
(4)Concat:张量拼接,会扩充两个张量的维度,例如26×26×256和26×26×512两个张量拼接,结果是26×26×768。Concat和cfg文件中的route功能一样。
(5)Add:张量相加,张量直接相加,不会扩充维度,例如104×104×128和104×104×128相加,结果还是104×104×128。add和cfg文件中的shortcut功能一样。
网络结构
检测结构
对于v3而言,在prior这里的处理有明确解释:选用的b-box priors 的k=9,对于tiny-yolo的话,k=6。priors都是在数据集上聚类得来的,有确定的数值,如下:
10,13, 16,30, 33,23, 30,61, 62,45, 59,119, 116,90, 156,198, 373,326
像v2一样,v3对b-box进行预测的时候,采用了logistic regression。每次对b-box进行预测时,输出和v2一样都是,然后通过公式1计算出绝对的(x, y, w, h, c)。
cx,cy是网格的坐标偏移量,pw,ph是预设的anchor box的边长,最终得到的预测边框坐标值是bx,by,bw,bh,而网络学习目标是tx,ty,tw,th。
v3只会对1个prior进行操作,也就是那个最佳prior。而logistic回归就是用来从9个anchor priors中找到objectness score(目标存在可能性得分)最高的那一个
9个anchor会被三个输出张量平分的。根据大中小三种size各自取自己的anchor。每种尺度预测3个box, anchor的设计方式仍然使用聚类,得到9个聚类中心,将其按照大小均分给3中尺度。
Yolov4的五个基本组件:
1. CBM:Yolov4网络结构中的最小组件,由Conv+BN+Mish激活函数三者组成。
2. CBL:由Conv+BN+Leaky_relu激活函数三者组成。
3. Res unit:借鉴Resnet网络中的残差结构,让网络可以构建的更深。
4. CSPX:借鉴CSPNet网络结构,由卷积层和X个Res unint模块Concat组成。
5. SPP:采用1×1,5×5,9×9,13×13的最大池化的方式,进行多尺度融合。
YOLOv4的创新之处:
1. 输入端:这里指的创新主要是训练时对输入端的改进,主要包括Mosaic数据增强、cmBN、SAT自对抗训练。
2. BackBone主干网络:将各种新的方式结合起来,包括:CSPDarknet53(上图网络结构)、Mish激活函数、Dropblock
3. Neck:目标检测网络在BackBone和最后的输出层之间往往会插入一些层,比如Yolov4中的SPP模块、FPN+PAN结构
4. Prediction:输出层的锚框机制和Yolov3相同,主要改进的是训练时的损失函数CIOU_Loss,以及预测框筛选的NMS变为DIOU_NMS
参考2019年底提出的CutMix数据增强的方式,但CutMix只使用了两张图片进行拼接,而Mosaic数据增强则采用了4张图片,随机缩放、随机裁剪、随机排布的方式进行拼接。
作用:
1、丰富数据集,随机使用4张图片,随机缩放,再随机分布进行拼接,大大丰富了检测数据集,特别是随机缩放增加了很多小目标,让网络的鲁棒性更好。参考论文《Augmentation for small object detection》小目标的区别定义如下:
2、减少训练GPU,4张图并为一张图训练,减少batch大小。
如上图CSPDDarknet53结构
优点一:增强CNN的学习能力,使得在轻量化的同时保持准确性。
优点二:降低计算瓶颈
优点三:降低内存成本
类似于Dropout功能,缓解过拟合的一种正则化方式:
Dropblock:
Dropout是随机丢弃一些信息,在全连接层可能起到比较好的作用,但是Darknet的网络结构舍弃了全连接层,即使随机丢弃,卷积层依然可以从相邻的激活单元学习到相同信息,所以Dropout效果并不好。
Dropblock 则是将整个局部区域丢弃,类似于数据增强中cutout的方式,将图像的部分区域直接清零,Dropblock是将cutout应用在每一个特征图中,而且并不是用固定的归零比率,而是在训练时以一个小的比率开始,随着训练过程线性的增加这个比率。
优点一:Dropblock的效果优于Cutout
优点二:cutout只能作用于输入层,而Dropblock则是将Cutout应用到网络中的每一个特征图上
优点三:Dropblock可以定制各种组合,在训练的不同阶段可以修改删减的概率,从空间层面和时间层面,和cutout相比都有更精细的改进。
SPP模块中,使用k={1×1,5×5,9×9,13×13}的最大池化的方式,再将不同尺度的特征图进行Concat操作(池化采用padding操作,维度不变)。SPP模块的方式,比单纯的使用k×k最大池化的方式,更有效的增加主干特征的接收范围,显著的分离了最重要的上下文特征。
下采样中三个尺度分别对应backbone中的两次下采样,得到76×76、38×38、19×19;最后Prediction中三个特征图分别是①19×19×255、②38×38×255、③76×76×255,将CSPDDarknet网络中的Neck部分换种方式画出,可以直观看到两部分是怎么通过FPN结构融合的:
PAN借鉴的是2018年的PANet的思想,PAN+FPN融合机构如下
和Yolov3的FPN层不同,Yolov4在FPN层的后面还添加了一个自底向上的特征金字塔。其中包含两个PAN结构。这样结合操作,FPN层自顶向下传达强语义特征,而特征金字塔则自底向上传达强定位特征,两两联手,从不同的主干层对不同的检测层进行特征聚合。
Bounding Box Regeression的Loss近些年的发展过程是:Smooth L1 Loss-> IoU Loss(2016)-> GIoU Loss(2019)-> DIoU Loss(2020)->CIoU Loss(2020)
a. IOU_loss
可以看到IOU的loss其实很简单,主要是交集/并集,但其实也存在两个问题。
问题1:即状态1的情况,当预测框和目标框不相交时,IOU=0,无法反应两个框距离的远近,此时损失函数不可导,IOU_Loss无法优化两个框不相交的情况。
问题2:即状态2和状态3的情况,当两个预测框大小相同,两个IOU也相同,IOU_Loss无法区分两者相交情况的不同。
因此2019年出现了GIOU_Loss来进行改进。
b. GIOU_loss
可以看到右图GIOU_Loss中,增加了相交尺度的衡量方式,缓解了单纯IOU_Loss时的尴尬。
但为什么仅仅说缓解呢?因为还存在一种不足:
问题:状态1、2、3都是预测框在目标框内部且预测框大小一致的情况,这时预测框和目标框的差集都是相同的,因此这三种状态的GIOU值也都是相同的,这时GIOU退化成了IOU,无法区分相对位置关系。
基于这个问题,2020年的AAAI又提出了DIOU_Loss。
c. DIOU_loss
好的目标框回归函数应该考虑三个重要几何因素:重叠面积、中心点距离,长宽比。
针对IOU和GIOU存在的问题,作者从两个方面进行考虑
一:如何最小化预测框和目标框之间的归一化距离?
二:如何在预测框和目标框重叠时,回归的更准确?
针对第一个问题,提出了DIOU_Loss(Distance_IOU_Loss)
DIOU_Loss考虑了重叠面积和中心点距离,当目标框包裹预测框的时候,直接度量2个框的距离,因此DIOU_Loss收敛的更快。
但就像前面好的目标框回归函数所说的,这时并没有考虑到长宽比。
问题:比如上面三种状态,目标框包裹预测框,本来DIOU_Loss可以起作用。
但预测框的中心点的位置都是一样的,因此按照DIOU_Loss的计算公式,三者的值都是相同的。
针对这个问题,又提出了CIOU_Loss,不对不说,科学总是在解决问题中,不断进步!!
d. CIOU_loss
CIOU_Loss和DIOU_Loss前面的公式都是一样的,不过在此基础上还增加了一个影响因子,将预测框和目标框的长宽比都考虑了进去。
其中v是衡量长宽比一致性的参数,我们也可以定义为:
这样CIOU_Loss就将目标框回归函数应该考虑三个重要几何因素:重叠面积、中心点距离,长宽比全都考虑进去了。
相似与上述方法,考虑中心点距离问题