yolov4的全面详解

一. 前言

作者AlexeyAB大神! YOLOv4 拥有43.5%mAP+65FPS ,达到了精度速度最优平衡,

作者团队:Alexey Bochkovskiy&中国台湾中央研究院

论文链接:

https://arxiv.org/pdf/2004.10934.pdf

代码链接:

GitHub – AlexeyAB/darknet: YOLOv4 / Scaled-YOLOv4 / YOLO – Neural Networks for Object Detection (Windows and Linux version of Darknet )
————————————————

在讲YOLOv4之前,先介绍一下两个包:Bag of Freebies(免费包)和Bag-of-Specials(特赠包)

Bag of Freebies:指的是那些不增加模型复杂度,也不增加推理的计算量的训练方法技巧,来提高模型的准确度

Bag-of-Specials:指的是那些增加少许模型复杂度或计算量的训练技巧,但可以显著提高模型的准确度

YOLOv4主要的贡献:

①构建了一个简单且高效的目标检测模型,该算法降低了训练门槛,这使得普通人员都可以使用 1080Ti 或 2080 Ti GPU 来训练一个超快,准确的(super fast and accurate)目标检测器。

②验证了最先进的 Bag-of-Freebies 和 Bag-of-Specials 方法在训练期间的影响

BoF指的是

1)数据增强:图像几何变换(随机缩放,裁剪,旋转),Cutmix,Mosaic等

2)网络正则化:Dropout,Dropblock等

3) 损失函数的设计:边界框回归的损失函数的改进 CIOU

BoS指的是

1)增大模型感受野:SPP、ASPP等

2)引入注意力机制:SE、SAM

3)特征集成:PAN,BiFPN

4)激活函数改进:Swish、Mish

5)后处理方法改进:soft NMS、DIoU NMS

③修改了最先进的方法,并且使其更为有效,适合单GPU训练。包括 CBN,PAN, SAM等,从而使得 YOLO-v4 能够在一块 GPU 上就可以训练起来。

二.yolov4的创新点

输入端的创新点:训练时对输入端的改进,主要包括Mosaic数据增强、cmBN、SAT自对抗训练

BackBone主干网络:各种方法技巧结合起来,包括:CSPDarknet53、Mish激活函数、Dropblock

Neck:目标检测网络在BackBone和最后的输出层之间往往会插入一些层,比如Yolov4中的SPP模块、FPN+PAN结构

Prediction:输出层的锚框机制和Yolov3相同,主要改进的是训练时的回归框位置损失函数 CIOU_Loss,以及预测框筛选的nms变为DIOU_nms

2.1输入端创新

Yolov4对训练时的输入端进行改进,使得训练时在单张GPU上跑的结果也蛮好的。比如数据增强Mosaic、cmBN、SAT自对抗训练。

2.1.1数据增强

Yolov4中使用的 Mosaic是参考2019年底提出的 CutMix数据增强的方式,但 CutMix只使用了两张图片进行拼接,而 Mosaic数据增强则采用了4张图片, 随机缩放、随机裁剪、随机排布的方式进行拼接。

yolov4的全面详解

为什么要进行 Mosaic数据增强呢?

在平时项目训练时, 小目标的AP一般比中目标和大目标低很多。而Coco数据集中也包含大量的小目标,但比较麻烦的是小目标的分布 并不均匀。Coco数据集中小目标占比达到 41.4%,数量比中目标和大目标都要多。但在所有的训练集图片中,只有 52.3%的图片有小目标,而中目标和大目标的分布相对来说更加均匀一些。

针对这种状况,Yolov4的作者采用了 Mosaic数据增强的方式。

主要有2个优点:

  1. 丰富数据集:随机使用 4张图片,随机缩放,再随机分布进行拼接,大大丰富了检测数据集,特别是随机缩放增加了很多小目标,让网络的鲁棒性更好。
  2. batch不需要很大:Mosaic增强训练时,可以直接计算4张图片的数据,使得Mini-batch大小并不需要很大,一个GPU就可以达到比较好的效果。

2.1.2 cmBN

深度学习中的 BN_CBN_CMBN

BN:

反向传播时经过该层的梯度是要乘以该层的参数的,即前向有:

yolov4的全面详解

yolov4的全面详解

最后的

yolov4的全面详解 就是xi 归一化(BN)后的值,归一化后所有值满足均值为0方差为1

接着

yolov4的全面详解又进行了scale加上shift操作(y=scale*x+shift),每个神经元增加了两个参数scale和shift参数,这两个参数是通过训练学习到的,意思是通过scale和shift把这个值从标准正态分布左移或者右移一点并长胖一点或者变瘦一点,每个实例挪动的程度不一样,这样等价于非线性函数的值从正中心周围的线性区往非线性区移动。

在测试中使用BN:

在训练中使用BN是要计算均值

yolov4的全面详解和方差yolov4的全面详解的,而这两个统计量是随着样本不同而变化的。如果在测试中依然遵循这样的方式,那么无疑同一个样本在不同的batch中预测会得到不一样的概率值,这显然是不对的。
在测试中,BN根据训练过程中计算的均值和方差,使用滑动平均去记录这些值。在测试的时候统一使用记录下来的滑动平均值,这一点可以从源码中看出来。所以在TensorFlow或者Pytorch中,BN的代码分别有is_training 和 self.training字段,就是为了区别使用行为的。

举个例子。(这里方差=标准差的平方)
在训练过程的第t次迭代中,我们得到了均值u和方差

yolov4的全面详解。那么u和yolov4的全面详解将使用如下方式保存下来。

初始化

yolov4的全面详解=1,yolov4的全面详解=0,初始化yolov4的全面详解=[0,0] ,方差yolov4的全面详解=[1,1] ,他们的的个数是与特征图的channel深度相同的

yolov4的全面详解

CBN:

batch比较小时候,BN在batch维度统计不准确,导致准确率下降。在无法扩大batch训练的前提下,CBN通过收集最近几次迭代信息来更新当前迭代时刻的均值和方差,这样就变向实现了扩大batch目的。我们知道在当前迭代时刻,参数已经更新了N次,存储的前几个迭代的参数肯定无法直接和当前迭代次数进行合并计算,也就是由于网络权重的变化,不同迭代产生的网络激活无法相互比较。故需要找到一种解决办法。一种可行的方法就是利用当前和先前迭代的均值和方差。

然而t-

yolov4的全面详解次轮的统计值yolov4的全面详解yolov4的全面详解对应的网络权重是yolov4的全面详解,当前轮的网络权重是yolov4的全面详解。因此,直接利用多次迭代的统计值进行估计,会使估计的统计量不准确,导致性能的明显的下降。

yolov4的全面详解

对于某一层L,假设当前迭代时刻为t,则t-

yolov4的全面详解时刻中的统计量yolov4的全面详解yolov4的全面详解,在第t时刻的参数yolov4的全面详解,对于t-yolov4的全面详解时刻的统计值,可以在yolov4的全面详解处展开,yolov4的全面详解为权重参数

yolov4的全面详解

yolov4的全面详解

yolov4的全面详解

CMBN:

CmBN的做法和前面两个都不一样,其把大batch内部的4个mini batch当做一个整体,对外隔离,主要改变在于BN层的统计量计算方面,具体流程是:假设当前是第t次迭代时刻,也是mini-batch的起点,

(1) 在第t时刻开始进行梯度累加操作

(2) 在第t时刻开始进行BN统计量汇合操作,这个就是和CBN的区别,CBN在第t时刻,也会考虑前3个时刻的统计量进行汇合,而CmBN操作不会,其仅仅在mini batch内部进行汇合操作

(3) 就是正常的应用BN,对输入进行变换输出即可

(4) 在mini batch的最后一个时刻,进行参数更新和可学习参数更新

可以明显发现CmBN是CBN的简化版本,其唯一差别就是在计算第t时刻的BN统计量时候,CBN会考虑前一个mini batch内部的统计量,而CmBN版本,所有计算都是在mini batch内部。有人认为这种做法是为了减少内存消耗,提高训练速度,既然大家都是近似,差距应该不大,而且本身yolo训练时候,batch也不会特别小,不至于是1-2,所以 CmBN的做法应该是为了yolov4专门设计的,属于实践性改进

Cmbn的过程:

yolov4的全面详解

2.2 BackBone创新

Backbone:采用的主干网络为 CSPDarknet53,CSPDarknet53是在Yolov3主干网络Darknet53的基础上,借鉴2019年CSPNet的经验,产生的Backbone结构,其中包含了5个CSP模块

yolov4的全面详解

每个CSP模块前面的卷积核的大小都是3*3,stride=2,因此可以起到下采样的作用。

因为Backbone有5个 CSP模块,输入图像是 608*608,所以特征图变化的规律是: 608->304->152->76->38->19 经过5次CSP模块后得到1919大小的特征图。而且作者只在Backbone中采用了 Mish激活函数,网络后面仍然采用 Leaky_relu激活函数。 YOLOv3的主干网络采用的是darknet53*,yolov4的Backbone:采用的主干网络为 CSPDarknet53

YOLOv4的作者是根据参考2019年的 CSPNet的做法而改进的darknet53网络

CSPNet论文地址:https://arxiv.org/pdf/1911.11929.pdf

CSPNet全称是Cross Stage Paritial Network,主要从网络结构设计的角度解决推理中从计算量很大的问题。

CSPNet的作者认为推理计算过高的问题是由于网络优化中的 梯度信息重复导致的。

这是因为类似于DenseNet的网络一样,更新权重的值反向传播,会造成重复计算梯度

因此采用CSP模块先将基础层的特征映射划分为两部分,然后通过跨阶段层次结构将它们合并,在减少了计算量的同时可以保证准确率。

Mish激活函数

Mish激活函数是 2019年下半年提出的激活函数

论文地址:https://arxiv.org/abs/1908.08681

Leaky_relu激活函数的图形对比如下:

yolov4的全面详解

从图中可以看出该激活函数,在负值时并不是完全截断,而允许比较小的负梯度流入从而保证了信息的流动(因为梯度为负值时,作为relu激活函数,大多数神经元没有更新)

mish激活函数无边界,这让他避免了饱和(有下界,无上界)且每一点连续平滑且非单调性,从而使得梯度下降更好。

yolov4的全面详解

Dropblock

Yolov4中使用的 Dropblock,其实和常见网络中的Dropout功能类似,也是缓解过拟合的一种正则化方式。

Dropblock在2018年提出,论文地址:https://arxiv.org/pdf/1810.12890.pdf

传统的Dropout很简单,一句话就可以说的清: 随机删除减少神经元的数量,使网络变得更简单。

dropout主要作用在全连接层,而dropblock可以作用在任何卷积层之上

yolov4的全面详解

而Dropblock和Dropout相似,比如下图:

yolov4的全面详解

中间Dropout的方式会随机的删减丢弃一些信息,但 Dropblock的研究者认为,卷积层对于这种随机丢弃并不敏感,因为卷积层通常是三层连用: 卷积+激活+池化层,池化层本身就是对相邻单元起作用。而且即使随机丢弃,卷积层仍然可以从相邻的激活单元学习到 相同的信息

因此,在全连接层上效果很好的Dropout在卷积层上 效果并不好

所以 右图Dropblock的研究者则干脆整个局部区域进行删减丢弃。

这种方式其实是借鉴 2017年的cutout数据增强的方式,cutout是将输入图像的部分区域清零,而Dropblock则是将Cutout应用到每一个特征图。而且并不是用固定的归零比率,而是在训练时以一个小的比率开始,随着训练过程 线性的增加这个比率

在特征图上一块一块的进行归0操作,去促使网络去学习更加鲁棒的特征

为了保证Dropblock后的特征图与原先特征图大小一致,需要和dropout一样,进行rescale操作

Dropblock的研究者与 Cutout进行对比验证时,发现有几个特点:

优点一:Dropblock的效果优于Cutout

优点二:Cutout只能作用于输入层,而Dropblock则是将Cutout应用到网络中的每一个特征图上

优点三:Dropblock可以定制各种组合,在训练的不同阶段可以修改删减的概率,从空间层面和时间层面,和Cutout相比都有更精细的改进。

Yolov4中直接采用了更优的 Dropblock,对网络的正则化过程进行了全面的升级改进。

2.3 Neck创新

在目标检测领域,为了更好的提取融合特征,通常在 Backbone输出层,会插入一些层,这个部分称为Neck。相当于目标检测网络的颈部,也是非常关键的。

Yolov4的Neck结构主要采用了 SPP模块FPN+PAN的方式

作者在SPP模块中,使用k={11,55,99,1313}的最大池化的方式,再将不同尺度的特征图进行Concat操作。spp模块是YOLOv4中在YOLOv3的基础上加了的模块,而PAN则也是YOLOv4的创新模块。

YOLOv3中的neck只有自顶向下的FPN,对特征图进行特征融合,而YOLOv4中则是FPN+PAN的方式对特征进一步的融合

下面是YOLOv3的neck中的FPN

yolov4的全面详解

如图所示,FPN是自顶向下的,将高层的特征信息通过 上采样的方式进行传递融合,得到进行预测的特征图。

而YOLOv4中的neck如下:

yolov4的全面详解

原本的PANet网络的 PAN结构中,两个特征图结合是采用 shortcut操作,而Yolov4中则采用 concat(route)操作,特征图融合后的尺寸发生了变化

yolov4的全面详解

2.4 检测头的loss创新

损失函数=box位置损失+类别损失+置信度损失

YOLO V4用CIOU损失代替了YOLOv3的box位置损失,取代了预测框和真实框的中心点坐标以及宽高信息设定MSE(均方误差)损失函数或者BCE损失函数,其他部分损失没改变

yolov4的全面详解

三.yolov4流程详解

3.1网络结构图

yolov4的全面详解

图1 网络结构

3.2 YOLOv4的方法

Yolo-v4:主要由三部分组成: Backbone,Neck和Head

3.2.1 Backbone

采用的主干网络为 CSPDarknet53,CSPDarknet53是在Yolov3主干网络Darknet53的基础上,借鉴2019年CSPNet的经验,产生的Backbone结构,其中包含了1个CBM和5个CSP模块

骨干部分图如下:

yolov4的全面详解

①CBM:

Yolov4网络结构中的最小组件,由Conv+Bn+Mish激活函数三者组成。

② CSP模块:

借鉴了CSPNet网络结构,由CBM组件和X个Res unint模块Concate组成。

第一个CSP模块:由CBM组件和1个Res unint模块Concate组成。

将CBM组件处理后的特征图60860832的F_conv2传入第一个CSP1模块进行处理(其中只有1个残差单元)

yolov4的全面详解

第二个CSP模块:由CBM组件和2个Res unint模块Concate组成。

将第一个csp模块处理后的30430464特征图,传入到第二个CSP模块处理

同理经过下采样后变成了152152128的特征图,然后分别经过两个1164的s=1的卷积后得到两个分支,其中一个分支的特征块进入残差模块进行处理后,再与另一个分支进行拼接,最后第二个csp模块的最后输出是152152128 (残差模块中的卷积层:1164和3364)

第三个CSP模块:由8个Res unint模块和CBM组件Concate组成。

将第二个csp模块处理后的152152128的特征图,传入到第三个个CSP模块处理

同理也是经过同样的操作,最后第三个csp模块的最后输出是7676256 (残差模块中的卷积层:11128和33128),这个模块后又分为两个分支,一个分支继续进行csp模块处理,另一个分支直接进入到neck处理

第四个CSP模块:由8个Res unint模块和CBM组件Concate组成。

将第三个csp模块的一个分支7676256的特征图,传入到第四个CSP模块处理

同理也是经过同样的操作,最后第四个csp模块的最后输出是3838512 (残差模块中的卷积层:11256和33256),这个模块后又分为两个分支,一个分支继续进行csp模块处理,另一个分支直接进入到neck处理

第五个CSP模块:由4个Res unint模块和CBM组件Concate组成。

将第四个csp模块的一个分支3838512的特征图,传入到第五个CSP模块处理

同理也是经过同样的操作,最后第五个csp模块的最后输出是19191024 (残差模块中的卷积层:11512和33512),这个模块输出结果直接进入到neck处理

3.2.2 Neck:

特征增强模块,主要由CBL组件,SPP模块和FPN+PAN的方式组成

yolov4的全面详解

① CBL组件:

由Conv+Bn+Leaky_relu激活函数三者组成

将第五个csp4模块的输出结果19191024的特征图,传入到CBL组件中处理

yolov4的全面详解

spp前后三个CBL组件是对称的,它们的卷积分别是11512,331024和11512,步长都是1

②SPP模块:

采用1×1,5×5,9×9,13×13的最大池化的方式,进行多尺度融合

yolov4的全面详解

spp模块采用的1×1 ,5×5 padding=5 // 2,9×9 padding=9 // 2,13×13 padding=13 // 2的最大池化的方式,进行多尺度融合,从前面三个CBL组件输出的结果:1919512的特征图,将之送入spp模块中,最后的结果为19192048,再经过三个CBL组件的卷积后得到1919512的特征图

③ FPN+PAN的结构:

PAN是借鉴图像分割领域PANet的创新点

yolov4的全面详解

这样结合操作,FPN层自顶向下传达强语义特征,而PAN则自底向上传达强定位特征,两两联手,从不同的主干层对不同的检测层进行参数聚合,加速了不同尺度特征的融合,进一步提高特征提取的能力。

3.2.3 Head:

YoloHead利用获得到的特征进行预测,是一个解码的过程

在特征利用部分,YoloV4提取多尺度特征进行目标检测,一共提取三个特征层,分别位于中间层,中下层,底层,三个特征层的shape分别为(19,19,255),(38,38,255),(76,76,255) 在Yolov3的设计中,每个特征图的每个格子中,都配置3个不同的先验框,所以最后三个特征图,这里暂且reshape为19 × 19 × 3 × 85、38 × 38 × 3 × 85、76 × 76 × 3 × 85,这样更容易理解,在代码中也是reshape成这样之后更容易操作。 三张特征图就是整个Yolo输出的检测结果,检测框位置(4维)、检测置信度(1维)、类别(80维)都在其中,加起来正好是85维。特征图最后的维度85,代表的就是这些信息,而特征图其他维度N × N × 3,N × N代表了检测框的参考位置信息,3是3个不同尺度的先验框。

①先验框(anchor box)

YOLO3采用了K-means聚类得到先验框的尺寸,YOLO4延续了这种方法,为每种下采样尺度设定3种先验框,总共聚类出9种尺寸的先验框。在COCO数据集中(原始图片全部resize为608 × 608),九个框分别是 [[12, 16], [19, 36], [40, 28], [36, 75], [76, 55], [72, 146], [142, 110], [192, 243], [459, 401]],顺序为w × h。 将前三个先验框分配给7676255的特征图,中间三个框分配给3838255的特征图,最后三个框分配给1919255的特征图

②解码检测框

有了先验框与输出特征图后,就可以解码检测框 x,y,w,h。 例如:(19,19,3,85),分别对应着19*19个网格,每个网格3种anchors,85=(x,y,w,h,confident),此时box的x,y是相对于网格的偏移量,所以还需要经过一些列的处理,处理方式见下图:

yolov4的全面详解

注意:σ(tx),σ(ty)是基于bbox框中心点左上角格点坐标的偏移量

③置信度解码

物体的检测置信度,置信度在输出85维中占固定一位,由sigmoid函数解码即可,解码之后数值区间在[0,1]中。

④类别解码

COCO数据集有80个类别,所以类别数在85维输出中占了80维,每一维独立代表一个类别的置信度。使用sigmoid激活函数替代了Yolov2中的softmax,取消了类别之间的互斥,可以使网络更加灵活。

yolov4的全面详解

⑤筛选预测框

三个特征图一共可以解码出 19 × 19 × 3 + 38 × 38× 3 + 76 × 76 × 3 = 22743个box以及相应的类别、置信度。 首先,设置一个置信度阈值,筛选掉低于阈值的box,再经过DIOU_NMS(非极大值抑制)后,就可以输出整个网络的预测结果了。

DIOU_NMS的处理步骤如下:

1.遍历图片中所有识别出目标的类,对每个类的所有框进行单独分析

2.再将所有的狗的预测框按分数从大到小排序,如下图;

yolov4的全面详解

3.下一步,设狗类概率最大的框为target,依次比较它和其他非0框进行(IOU-DIOU)计算,如果计算结果大于设定的DIoU阈值(这里是ε=0.5),就将该框的狗的概率置为0,如下target和第二个框的(IOU-DIOU)明显大于阈值0.5,所以舍去第二个框,把这个框的狗类概率设为0,如下图;

yolov4的全面详解

yolov4的全面详解

yolov4的全面详解

4.继续扫描到第三个框,它与最大概率框的(IOU-DIOU)小于0.5,需要保留,继续扫描后面的框,直到所有框都与最大概率框比较完毕为止。此时保留了不少框。

5.接下来,以次大概率的框bb15(因为一开始排序过,它在顺序上也一定是保留框中最靠近上一轮的基础框的)为基础,将它后面的其它框于之比较,如下图:

yolov4的全面详解

如果bb15框(次大概率的框)和bb7框的(IOU-DIOU)大于0.5,则可以剔除第4个框:把这个框的狗类概率设置为0

  1. 假设在经历了所有的扫描之后,对Dog类别只留下了两个框,如下:

yolov4的全面详解

因为对计算机来说,图片可能出现两只Dog,保留概率不为0的框是安全的。不过代码后续设置了一定的阈值(比如0.3)来删除掉概率太低的框,这里的蓝色框在最后并没有保留,因为它在最后会因为阈值不够而被剔除。

7.上面描述了对Dog种类进行的框选择。接下来,我们还要对其它79种类别分别进行上面的操作

  1. 最后进行纵向跨类的比较(为什么?因为上面就算保留了最大概率的Dog框,但该框可能在Cat的类别也为概率最大且比Dog的概率更大,那么我们最终要判断该框为Cat而不是Dog)。判定流程和法则如下:

yolov4的全面详解

最后保留的预测框就是最终呈现的预测框

⑥Yolo-v4:损失函数

损失函数=box位置损失+类别损失+置信度损失

YOLO V4用CIOU损失代替了YOLOv3的box位置损失,取代了预测框和真实框的中心点坐标以及宽高信息设定MSE(均方误差)损失函数或者BCE损失函数,其他部分损失没改变

具体详解参考:目标检测中的IoU、GIoU、DIoU与CIoU_Runist blog-CSDN博客

深入浅出Yolo系列之Yolov3&Yolov4&Yolov5&Yolox核心基础知识完整讲解 – 知乎

则:

位置损失

目标检测的一项重要任务就是确定目标的位置,即(x, y, h, w),所以损失值的计算中包含位置损失CIOU损失 (考虑了长和宽的比值)

yolov4的全面详解

置信度损失

置信度损失分为两个部分,有目标的置信度损失,无目标的置信度损失

置信度损失:采用二元交叉熵损失

有目标的置信度损失:

yolov4的全面详解

无目标的置信度损失:

yolov4的全面详解

所以综上1919255的特征图的损失Loss1

yolov4的全面详解

Yolov4 总Loss为三个特征图Loss之和:

yolov4的全面详解

参考链接:YOLO V4 — 网络结构和损失函数解析(超级详细!) – 知乎

  1. yolov4的全面详解为权重常数,控制检测框Loss、有物体置信度Loss、没有物体的置信度Loss之间的比例,通常负例的个数是正例的几十倍以上,可以通过权重超参控制检测效果。
  2. yolov4的全面详解若是正例则输出1,否则为0;yolov4的全面详解 若是负例则输出1,否则为0;忽略样例都输出0。
  3. 置信度、类别标签由于是0,1二分类,所以使用交叉熵作为损失函数

最后:

与 SOTA 方法的比较:

yolov4的全面详解

参考链接:深入浅出Yolo系列之Yolov3&Yolov4&Yolov5&Yolox核心基础知识完整讲解 – 知乎

参考链接:YOLOv4 之CBN速读(Cross Iteration Batch Normalization) – 知乎

参考链接: 想读懂YOLOV4,你需要先了解下列技术(二) – 知乎

参考链接: 【论文解读】Yolo三部曲解读——Yolov3 – 知乎

参考链接:YOLO v3代码解读3 – 知乎

参考链接:深度学习论文翻译解析(二十):YOLOv4: Optimal Speed and Accuracy of Object Detection – 战争热诚 – 博客园

参考链接:BiFPN_申小隆的博客-CSDN博客_bifpn

Original: https://blog.csdn.net/hgnuxc_1993/article/details/120724812
Author: 无尽的沉默
Title: yolov4的全面详解

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/625156/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球