YOLOv4 模型原理及代码解析
四,YOLOv4
因为
YOLOv1-v3的作者不再更新YOLO框架,所以Alexey Bochkovskiy接起了传承YOLO的重任。相比于它的前代,YOLOv4不再是原创性且让人眼前一亮的研究,但是却集成了目标检测领域的各种实用tricks和即插即用模块 ,称得上是基于YOLOv3框架的各种目标检测tricks的集大成者。
本文章不会对原论文进行一一翻译,但是做了系统性的总结和关键部分的翻译。
1,摘要及介绍
我们总共使用了:WRC、CSP、CmBN、SAT、Mish 激活和 Mosaic 数据增强、CIoU 损失方法,并组合其中的一部分,使得最终的检测模型在 MS COCO 数据集、Tesla V100 显卡上达到了 43.5% AP 精度 和 65 FPS 速度。

我们的主要贡献在于:
- 构建了简单高效的
YOLOv4检测器,修改了CBN、PAN、SAM方法使得YOLOv4能够在一块1080Ti上就能训练。 - 验证了当前最先进的
Bag-of-Freebies和Bag-of-Specials方法在训练期间的影响。
目前的目标检测网络分为两种:一阶段和两阶段。检测算法的组成:Object detector = backbone + neck + head,具体结构如下图所示。

2,相关工作
2.1,目标检测方法
按照检测头的不同(head)将目标检测模型分为:两阶段检测和一阶段检测模型,各自代表是 Faster RCNN 和 YOLO 等,最近也出了一些无 anchor 的目标检测器,如 CenterNet 等。近几年来的检测器会在Backbone网络(backbone)和头部网络(head)之间插入一些网络层,主要作用是收集不同阶段的特征。,称其为检测器的颈部(neck)。 neck 通常由几个自下而上(bottom-up)的路径和几个自上而下(top-down)的路径组成。 配备此机制的网络包括特征金字塔网络(FPN)[44],路径聚合网络(PAN)[49],BiFPN [77]和NAS-FPN [17]。
一般,目标检测器由以下几部分组成:

2.2,Bag of freebies(免费技巧)
不会改变模型大小,主要是针对输入和
loss等做的优化工作,一切都是为了让模型训练得更好。
最常用的方式是数据增强(data augmentation),目标是为了提升输入图像的可变性(variability),这样模型在不同环境中会有更高的鲁棒性。常用的方法分为两类:光度失真和几何失真(photometric distortions and geometric distortions)。在处理光度失真时,我们调整了图像的亮度、对比度、色调、饱和度和噪声;对于几何失真,我们添加随机缩放,裁剪,翻转和旋转。
上述数据增强方法都是逐像素调整的,并且保留了调整区域中的所有原始像素信息。此外,也有些研究者将重点放在模拟对象遮挡的问题上,并取得了一些成果。例如随机擦除(random-erase)[100] 和 CutOut [11] 方法会随机选择图像中的矩形区域,并填充零的随机或互补值。而捉迷藏(hide-and-seek)[69] 和网格遮罩(grid-mask)[6] 方法则随机或均匀地选择图像中的多个矩形区域,并将它们替换为所有的 zeros。这个概念有些类似于 Dropout、DropConnect 和 DropBlock 这些在 feature 层面操作的方法,如 。此外,一些研究人员提出了使用多个图像一起执行数据增强的方法。 例如,MixUp 方法使用两个图像以不同的系数比值相乘后叠加,然后使用这些叠加的比值来调整标签。 对于 CutMix,它是将裁切后的图像覆盖到其他图像的矩形区域,并根据混合区域的大小调整标签。 除了以上方法之外,还有 style transfer GAN 方法用于数据扩充、减少 CNN 所学习的纹理偏差。
MIX-UP:Mix-up在分类任务中,将两个图像按照不同的比例相加,例如 ,那么 的label就是 。在目标检测中的做法就是将一些框相加,这些label中就多了一些不同置信度的框。
上面的方法是针对数据增强目标,第二类方法是针对解决数据集中语义分布可能存在偏差的问题(semantic distribution in the dataset may have bias)。在处理语义分布偏差问题时,类别不平衡(imbalance between different classes)问题是其中的一个关键,在两阶段对象检测器中通常通过困难负样本挖掘(hard negative example mining)或在线困难样本挖掘(online hard example mining,简称 OHEM)来解决。但样本挖掘方法并不能很好的应用于一阶段检测器,因为它们都是密集检测架构(dense prediction architecture)。因此,何凯明等作者提出了 Focal Loss 用来解决类别不平衡问题。 另外一个关键问题是,很难用 one-hot hard representation 来表达不同类别之间的关联度的关系,但执行标记时又通常使用这种表示方案。 因此在(Rethinking the inception architecture for computer vision)论文中提出标签平滑(label smoothing)的概念,将硬标签转换为软标签进行训练,使模型更健壮。为了获得更好的软标签,论文(Label refinement network for coarse-to-fine semantic segmentation)介绍了知识蒸馏的概念来设计标签细化网络。
最后一类方法是针对边界框(BBox)回归的目标函数。传统的目标检测器通常使用均方误差(
)对BBox 的中心点坐标以及高度和宽度直接执行回归,即
或者
坐标。如果基于锚的方法,则估计相应的偏移量,例如
或者
。这些直接估计 BBox 的各个点的坐标值的方法,是将这些点视为独立的变量,但是实际上这没有考虑对象本身的完整性。为了更好的回归 BBox,一些研究者提出了 IOU 损失[90]。顾名思义,IoU 损失既是使用 Ground Truth 和预测 bounding box(BBox)的交并比作为损失函数。因为 IoU 是尺度不变的表示,所以可以解决传统方法计算
的
或
损失时,损失会随着尺度增加的问题。 最近,一些研究人员继续改善 IoU 损失。 例如,GIoU 损失除了覆盖区域外还包括对象的形状和方向,GIoU 损失的分母为同时包含了预测框和真实框的最小框的面积。DIoU 损失还考虑了对象中心的距离,而CIoU 损失同时考虑了重叠区域,中心点之间的距离和纵横比。 CIoU 损失在 BBox 回归问题上可以实现更好的收敛速度和准确性。
[90] 论文: An advanced object detection network.
2.3,Bag of specials(即插即用模块+后处理方法)
对于那些仅增加少量推理成本但可以显著提高目标检测器准确性的插件模块或后处理方法,我们将其称为 “Bag of specials”。一般而言,这些插件模块用于增强模型中的某些属性,例如扩大感受野,引入注意力机制或增强特征集成能力等,而后处理是用于筛选模型预测结果的方法。
增大感受野模块。用来增强感受野的常用模块有 SPP、ASPP 和 RFB。SPP 起源于空间金字塔匹配(SPM),SPM 的原始方法是将特征图分割为几个
个相等的块,其中
可以为
,从而形成空间金字塔。SPP 将 SPM 集成到 CNN 中,并使用最大池化操作(max pooling)替代 bag-of-word operation。原始的 SPP 模块是输出一维特征向量,这在 FCN 网络中不可行。
引入注意力机制。在目标检测中经常使用的注意力模块,通常分为 channel-wise 注意力和 point-wise 注意力。代表模型是 SE 和 SAM(Spatial Attention Module )。虽然 SE 模块可以提高 ReSNet50 在 ImageNet 图像分类任务 1% 的 top-1 准确率而计算量只增加 2%,但是在 GPU 上,通常情况下,它会将增加推理时间的 10% 左右,所以更适合用于移动端。但对于 SAM,它只需要增加 0.1% 的额外的推理时间,就可以在 ImageNet 图像分类任务上将 ResNet50-SE 的top-1 准确性提高 0.5%。 最好的是,它根本不影响 GPU 上的推理速度。
特征融合或特征集成。早期的实践是使用 skip connection 或 hyper-column 将低层物理特征集成到高层语义特征。 由于诸如 FPN 的多尺度预测方法已变得流行,因此提出了许多集成了不同特征金字塔的轻量级模块。 这种模块包括 SFAM,ASFF和 BiFPN。 SFAM 的主要思想是使用 SE 模块在多尺度级联特征图上执行通道级级别的加权。 对于 ASFF,它使用softmax 作为逐点级别权重,然后添加不同比例的特征图。在BiFPN 中,提出了多输入加权残差连接以执行按比例的级别重新加权,然后添加不同比例的特征图。
激活函数。良好的激活函数可以使梯度在反向传播算法中得以更有效的传播,同时不会引入过多的额外计算成本。2010 年 Nair 和 Hinton 提出的 ReLU 激活函数,实质上解决了传统的tanh 和 sigmoid 激活函数中经常遇到的梯度消失问题。随后,随后,LReLU,PReLU,ReLU6,比例指数线性单位(SELU),Swish,hard-Swish 和 Mish等激活函数也被提出来,用于解决梯度消失问题。LReLU 和 PReLU 的主要目的是解决当输出小于零时 ReLU 的梯度为零的问题。而 ReLU6 和 Hard-Swish 是专门为量化网络设计的。同时,提出了 SELU 激活函数来对神经网络进行自归一化。 最后,要注意 Swish 和 Mish 都是连续可区分的激活函数。
后处理。最开始常用 NMS 来剔除重复检测的 BBox,但是 NMS 会不考虑上下文信息(可能会把一些相邻检测框框给过滤掉),因此 Girshick 提出了 Soft NMS,为相邻检测框设置一个衰减函数而非彻底将其分数置为零。而 DIoU NMS 则是在 soft NMS 的基础上将中心距离的信息添加到 BBox 筛选过程中。值得一提的是,因为上述后处理方法都没有直接涉及捕获的图像特征,因此在后续的 anchor-free 方法中不再需要 NMS 后处理。
3,方法
我们的基本目标是在生产系统中快速对神经网络进行操作和并行计算优化,而不是使用低计算量理论指示器(BFLOP)。 我们提供了两种实时神经网络:
- 对于
GPU,我们在卷积层中使用少量分组(1-8):如CSPResNeXt50 / CSPDarknet53 - 对于
VPU,我们使用分组卷积,但是我们避免使用SE-特别是以下模型:EfficientNet-lite / MixNet [76] / GhostNet [21] / MobiNetNetV3
3.1,架构选择
我们的目标是在输入图像分辨率、卷积层数量、参数量、层输出(滤波器)数量之间找到最优平衡。我们大量的研究表面,在 ILSVRC2012(ImageNet) 分类数据集上,CSPResNext50 网络优于 CSPDarknet,但是在 MS COCO 目标检测数据集上,却相反。
这是为什么呢,两种网络,一个分类数据集表现更好,一个检测数据集表现更好。

在分类问题上表现最优的参考模型并不一定总是在检测问题上也表现最优。与分类器相比,检测器需要满足以下条件:
- 更高的输入网络尺寸(分辨率),用于检测多个小型物体。
- 更多的网络层,用以得到更高的感受野以覆盖更大的输入网络尺寸。
- 更多参数,用以得到更大的模型容量,从而可以在单个图像中检测到多个不同大小的对象。
表1 显示了 CSPResNeXt50,CSPDarknet53 和EfficientNet B3 网络的信息。CSPResNext50 仅包含16 个
卷积层,最大感受野为
和网络参数量为 20.6 M,而 CSPDarknet53 包含 29 个
卷积层,最大感受野为
感受野和参数量为 27.6 M。理论上的论证再结合作者的大量实验结果,表面 CSPDarknet53 更适合作为目标检测器的 backbone。
不同大小的感受野的影响总结如下:
- 达到对象大小 - 允许查看整个对象
- 达到网络大小 - 允许查看对象周围的上下文环境
- 超过网络规模 - 增加图像点和最终激活之间的连接
我们在 CSPDarknet53 上添加了 SPP 模块,因为它显著增加了感受野,分离出最重要的上下文特征,并且几乎没有降低网络运行速度。 我们使用 PANet 作为针对不同检测器级别的来自不同backbone 级别的参数聚合方法,而不是 YOLOv3中使用的FPN。
最后,我们的 YOLOv4 架构体系如下:
backbone:CSPDarknet53+SPPneck:PANethead:YOLOv3的head
3.2,Selection of BoF and BoS
为了更好的训练目标检测模型,CNN 通常使用如下方法:
- 激活函数:
ReLU,leaky-ReLU,parameter-ReLU,ReLU6,SELU,Swish或Mish; - 边界框回归损失:
MSE,IoU,GIoU,CIoU,DIoU损失; - 数据扩充:
CutOut,MixUp,CutMix - 正则化方法:
DropOut,DropPath,空间DropOut或DropBlock - 通过均值和方差对网络激活进行归一化:批归一化(BN),交叉-GPU 批处理规范化(
CGBN或SyncBN),过滤器响应规范化(FRN)或交叉迭代批处理规范化(CBN); - 跳跃连接:残差连接,加残差连接,多输入加权残差连接或跨阶段局部连接(
CSP)
以上方法中,我们首先提出了难以训练的 PRELU 和 SELU,以及专为量化网络设计的 ReLU6 激活。因为 DropBlock 作者证明了其方法的有效性,所以正则化方法中我们使用 DropBlock。
3.3,额外的改进
这些方法是作者对现有方法做的一些改进。
为了让 YOLOv4 能更好的在单个 GPU 上训练,我们做了以下额外改进:
- 引入了新的数据增强方法:
Mosaic和自我对抗训练self-adversarial training(SAT)。 - 通过遗传算法选择最优超参数。
- 修改了
SAM、PAN和CmBN。
Mosaic 是一种新的数据增强方法,不像 cutmix 仅混合了两张图片,它混合了
张训练图像,从而可以检测到超出其正常上下文的对象。 此外,BN 在每层上计算的激活统计都是来自 4 张不同图像,这大大减少了对大 batch size 的需求。

CmBN 仅收集单个批次中的 mini-batch 之间的统计信息。

我们将 SAM 从 spatial-wise attentation 改为 point-wise attention,并将 PAN 的 shortcut 连接改为 concatenation(拼接),分别如图 5 和图 6 所示。

3.4 YOLOv4
YOLOv4 网络由以下部分组成:
Backbone:CSPDarknet53Neck:SPP,PANHead:YOLOv3
同时,YOLO v4 使用了:
- 用于
backbone的BoF:CutMix和Mosaic数据增强,DropBlock正则化,类标签平滑。 - 用于
backbone的BoS:Mish激活,跨阶段部分连接(CSP),多输入加权残余连接(MiWRC)。 - 用于检测器的
BoF:CIoU损失,CmBN,DropBlock正则化,mosaic数据增强,自我对抗训练,消除网格敏感性,在单个ground-truth上使用多个anchor,余弦退火调度器,最佳超参数,随机训练形状。 - 用于检测器
BoS:Mish激活,SPP模块,SAM模块,PAN路径聚集块,DIoU-NMS。
4,实验
4.1,实验设置
略
4.2,对于分类器训练过程中不同特性的影响
图 7 可视化了不同数据增强方法的效果。

表 2 的实验结果告诉我们,CutMix 和 Mosaic 数据增强,类别标签平滑及 Mish 激活可以提高分类器的精度,尤其是 Mish 激活提升效果很明显。

4.3,对于检测器训练过程中不同特性的影响
-
:
Eliminate grid sensitivit。原来的 ,因为sigmoid函数值域范围是 而不是 ,所以 不能取到grid的边界位置。为了解决这个问题,作者提出将 乘以一个超过 的系数,如 , 的公式类似。 -
:之前的
YOLOv3是 个anchor负责一个GT,现在YOLOv4改用多个anchor负责一个GT。对于GT来说,只要 ,就让 去负责 。 -
:使用了
GIoU,CIoU,DIoU,MSE这些误差算法来实现边框回归,验证出CIoU损失效果最好。 - 略

同时实验证明,当使用 SPP,PAN 和 SAM 时,检测器将获得最佳性能。
4.4,不同骨干和预训练权重对检测器训练的影响
综合各种改进后的骨干网络对比实验,发现 CSPDarknet53 比 CSPResNext 模型显示出提高检测器精度的更大能力。

4.5,不同小批量的大小对检测器训练的影响
实验证明,在使用了 BoF 和 BoS 训练策略后,小批量大小(mini-batch sizes)对检测器的性能几乎没有影响。实验结果对比表格就不放了,可以看原论文。
5,结果
与其他 state-of-the-art 目标检测算法相比,YOLOv4 在速度和准确性上都表现出了最优。详细的比较实验结果参考论文的图 8、表 8和表 9。
6,YOLOv4 主要改进点
例举出一些我认为比较关键且值得重点学习的改进点。
6.1,Backbone 改进
后续所有网络的结构图来都源于江大白公众号,之后不再一一注明结构图来源。
Yolov4 的整体结构可以拆分成四大板块,结构图如下图所示。

YOLOv4 的五个基本组件如下:
- CBM:
Yolov4网络结构中的最小组件,由Conv+Bn+Mish激活函数三者组成。 - CBL:由
Conv+Bn+Leaky_relu激活函数三者组成。 - Res unit:借鉴
Resnet网络中的残差结构思想,让网络可以构建的更深,和ResNet的basic block由两个CBL(ReLU)组成不同,这里的Resunit由2个CBM组成。 - CSPX:借鉴
CSPNet网络结构,由三个卷积层和X个Res unint模块Concate组成。 - SPP:采用
1×1,5×5,9×9,13×13的最大池化的方式,进行多尺度融合。
其他基础操作:
- Concat:张量拼接,会扩充维度。
- add:逐元素相加操作,不改变维度(
element-wise add)。
因为每个 CSPX 模块有
个卷积层,因此整个 backbone 中共有
个卷积层
这里卷积层的数目
72虽然不等同于YOLOv3中53,但是backbone依然是由 [1、2、8、8、4] 个卷积模块组成的,只是这里的YOLOv4中的卷积模块替换为了CSPX卷积模块,猜想是这个原因所以YOLOv4的作者这里依然用来Darknet53命名后缀。
6.1.1,CSPDarknet53
YOLOv4 使用 CSPDarknet53 作为 backbone,它是在 YOLOv3 的骨干网络 Darknet53 基础上,同时借鉴 2019 年的 CSPNet 网络,所产生的新 backbone。
CSPDarknet53 包含 5 个 CSP 模块,CSP 中残差单元的数量依次是
,这点和 Darknet53 类似。每个 CSP 模块最前面的卷积核的大小都是
,stride=2,因此可以起到下采样的作用(特征图大小缩小一倍)。因为 backbone 总共有 5 个 CSP模块,而输入图像是
,所以特征图大小变化是:608->304->152->76->38->19,即经过 bckbone 网络后得到
大小的特征图。CSPDarknet53 网络结构图如下图所示。

CSPNet作者认为,MobiletNet、ShuffleNet系列模型是专门为移动端(CPU)平台上设计的,它们所采用的深度可分离卷积技术(DW+PW Convolution)并不兼容用于边缘计算的ASIC芯片。
CSP 结构是一种思想,它和ResNet、DenseNet 类似,可以看作是 DenseNet 的升级版,它将 feature map 拆成两个部分,一部分进行卷积操作,另一部分和上一部分卷积操作的结果进行concate。
CSP 结构主要解决了四个问题:
- 增强 CNN 的学习能力,能够在轻量化的同时保持着准确性;
- 降低计算成本;
- 降低内存开销。CSPNet 改进了密集块和过渡层的信息流,优化了梯度反向传播的路径,提升了网络的学习能力,同时在处理速度和内存方面提升了不少。
- 能很好的和
ResNet、DarkNet等网络嵌入在一起,增加精度的同时减少计算量和降低内存成本。
6.1.2,Mish 激活
在 YOLOv4 中使用 Mish 函数的原因是它的低成本和它的平滑、非单调、无上界、有下界等特点,在表 2 的对比实验结果中,和其他常用激活函数如 ReLU、Swish 相比,分类器的精度更好。
Mish 激活函数是光滑的非单调激活函数,定义如下:
Mish 函数曲线图和 Swish 类似,如下图所示。

值得注意的是 Yolov4 的 Backbone 中的激活函数都使用了Mish 激活,但后面的 neck + head 网络则还是使用leaky_relu 函数。
6.1.3,Dropblock
Yolov4 中使用的 Dropblock ,其实和常见网络中的 Dropout 功能类似,也是缓解过拟合的一种正则化方式。
传统
dropout功能是随机删除减少神经元的数量,使网络变得更简单(缓解过拟合)。
6.2,Neck 网络改进
在目标检测领域中,为了更好的融合 low-level 和 high-level 特征,通常会在 backbone 和 head 网络之间插入一些网络层,这个中间部分称为 neck 网络,典型的有 FPN 结构。
YOLOv4 的 neck 结构采用了 SPP 模块 和 FPN+PAN 结构。
先看看 YOLOv3 的 neck 网络的立体图是什么样的,如下图所示。

FPN 是自顶向下的,将高层的特征信息经过上采样后和低层的特征信息进行传递融合,从而得到进行预测的特征图 ①②③。
再看下图 YOLOv4 的 Neck 网络的立体图像,可以更清楚的理解 neck 是如何通过 FPN+PAN 结构进行融合的。

FPN 层自顶向下传达强语义特征,而特征金字塔则自底向上传达强定位特征,两两联手,从不同的主干层对不同的检测层进行参数聚合,这种正向反向同时结合的操作确实 6 啊。
值得注意的是,Yolov3 的 FPN 层输出的三个大小不一的特征图①②③直接进行预测。但Yolov4 输出特征图的预测是使用 FPN 层从最后的一个 76*76 特征图 ① 和而经过两次PAN 结构的特征图 ② 和 ③ 。
另外一点是,原本的 PANet 网络的 PAN 结构中,两个特征图结合是采用 shortcut + element-wise 操作,而 Yolov4 中则采用 concat(route)操作,特征图融合后的尺寸会变化。原本 PAN 和修改后的 PAN 结构对比图如下图所示。

6.3,预测的改进
6.3.1,使用CIoU Loss
Bounding Box Regeression 的 Loss 近些年的发展过程是:Smooth L1 Loss-> IoU Loss(2016)-> GIoU Loss(2019)-> DIoU Loss(2020)->CIoU Loss(2020)
6.3.2,使用DIoU_NMS
6.4,输入端改进
6.4.1,Mosaic 数据增强
YOLOv4 原创的 Mosaic 数据增强方法是基于 2019 年提出的 CutMix 数据增强方法做的优化。CutMix 只对两张图片进行拼接,而 Mosaic 更激进,采用 4 张图片,在各自随机缩放、裁剪和排布后进行拼接。

在目标检测器训练过程中,小目标的 AP 一般比中目标和大目标低很多。而 COCO 数据集中也包含大量的小目标,但比较麻烦的是小目标的分布并不均匀。在整体的数据集中,它们的占比并不平衡。

如上表所示,在 COCO 数据集中,小目标占比达到 41.4%,数量比中目标和大目标要大得多,但是在所有的训练集图片中,只有 52.3% 的图片有小目标,即小物体数量很多、但分布非常不均匀,而中目标和大目标的分布相对来说更加均匀一些。
少部分图片却包含了大量的小目标。
针对这种状况,Yolov4 的作者采用了 Mosaic 数据增强的方式。器主要有几个优点:
- 丰富数据集:随机使用
4张图片,随机缩放,再随机分布进行拼接,大大丰富了检测数据集,特别是随机缩放增加了很多小目标,让网络的鲁棒性更好。 - 减少训练所需
GPU数量:Mosaic增强训练时,可以直接计算4张图片的数据,使得Mini-batch大小并不需要很大,一个GPU就可以训练出较好的模型。
- 点赞
- 收藏
- 关注作者
评论(0)