资源
论文题目《YOLOv4: Optimal Speed and Accuracy of Object Detection》
论文地址:https://arxiv.org/abs/2004.10934
论文代码:https://github.com/AlexeyAB/darknet
作者:AlexeyAB
论文链接:https://arxiv.org/pdf/2004.10934.pdf
代码链接:https://github.com/AlexeyAB/darknet
地位
Paper Scaled-YOLOv4 (CVPR 2021): https://openaccess.thecvf.com/content/CVPR2021/html/Wang_Scaled-YOLOv4_Scaling_Cross_Stage_Partial_Network_CVPR_2021_paper.html
source code Scaled-YOLOv4 - Pytorch (use to reproduce results): https://github.com/WongKinYiu/ScaledYOLOv4
YOLOv4 拥有43.5%mAP+65FPS ,达到了精度速度最优平衡
背景
偶然发现,csp的yolov4 的检测性能还挺好,激发了兴趣。
文章目录
- 资源
- 地位
- 背景
- 1 先看论文
- 1.1 BoF指的是
- 1.2 BoS指的是
- 2 再总结
- 2.1 YOLOv4中的backbone——CSP-DarkNet
- 2.1.1 Mish激活函数
- 2.1.1.1 softplus 激活函数
- 定义
- 2.1.1.2 Mish激活函数
- 2.1.2 CSP结构和DarkNet
- 2.1.2.1 CSP 结构
- 2.1.2.2 CSPDarknet53 结构
- 2.1.2.2 CSPDarknet53 复现
- 2.1.3 YOLOv4 同时出现 CSP 和 Mish 并协同工作
- 2.2 YOLOv4中的数据增强
- 2.2.1 数据增强Mosaic
- 2.2.1.1【数据增强Mosaic】
- 2.2.1.3【SAT自对抗训练】
- 2.2.1.3【cmBN】
- 2.2.1.4 [Label Smoothing]
- 2.3 Dropblock 的采用(可以作用在任何卷积层)
- 2.3.1 dropout 方案
- 2.3.2 dropblock 方案
- 2.3.3 对比
- 2.4 SPP、 FPN+PAN以及SAM方案
- 2.4.1 SPP
- 2.4.2 PAN
- 2.4.3 【SAM】
- 2.5 Head头
- 2.5.1【loss创新】
- 2.5.2【NMS创新】
- 2.5.3【SOFT-NMS】
- 再看代码
- yolov4 以及转换到tensorrt (cuda),不依赖tensorrt更好
- 参考
1 先看论文
Bag of Freebies(免费包)和Bag-of-Specials(特赠包)
Bag of Freebies:指的是那些不增加模型复杂度,也不增加推理的计算量的训练方法技巧,来提高模型的准确度
Bag-of-Specials:指的是那些增加少许模型复杂度或计算量的训练技巧,但可以显著提高模型的准确度
1.1 BoF指的是
-
1)数据增强:图像几何变换(随机缩放,裁剪,旋转),Cutmix,Mosaic等
-
2)网络正则化:Dropout,Dropblock等
-
3) 损失函数的设计:边界框回归的损失函数的改进 CIOU
1.2 BoS指的是
-
1)增大模型感受野:SPP、ASPP等
-
2)引入注意力机制:SE、SAM
-
3)特征集成:PAN,BiFPN
-
4)激活函数改进:Swish、Mish
-
5)后处理方法改进:soft NMS、DIoU NMS
YOLO_v4主要就是利用这两个包,修改了最先进的方法,并且使其更为有效。当然,还运用到了CBN,PAN, SAM等方法,从而使得 YOLO-v4 能够在一块 GPU 上就可以训练起来。
2 再总结
YOLOv4在使用YOLO Loss的基础上,使用了新的backbone,并且集成了很多新的优化方法及模型策略,如Mosaic,PANet,CmBN,SAT训练,CIoU loss,Mish激活函数,label smoothing等等。可谓集SoAT之大成,也实现了很好的检测精度和速度。
YOLOv4backboneCSPDarkNet_53">2.1 YOLOv4中的backbone——CSP-DarkNet
主要讨论YOLOv4中的backbone——CSP-DarkNet,以及其实现的所必需的Mish激活函数,CSP结构和DarkNet。
2.1.1 Mish激活函数
参考
激活函数是为了提高网络的学习能力,提升梯度的传递效率。CNN常用的激活函数也在不断地发展,早期网络常用的有ReLU,LeakyReLU,softplus等,后来又有了Swish,Mish等。Mish激活函数的计算复杂度比ReLU要高不少,如果你的计算资源不是很够,可以考虑使用LeakyReLU代替Mish。在介绍之前,需要先了解softplus和tanh函数。
2.1.1.1 softplus 激活函数
Softplus激活函数是一种在神经网络中广泛使用的非线性激活函数,它的定义和特性如下:
定义
Softplus激活函数定义为:
softplus ( x ) = log ( 1 + e x ) \text{softplus}(x) = \log(1 + e^x) softplus(x)=log(1+ex)
这个函数可以看作是ReLU(Rectified Linear Unit,修正线性单元)函数的平滑版本。ReLU函数在输入小于等于0时输出为0,而Softplus函数在所有输入下都输出非负值,且在x小于等于0时也能产生非零的输出,这使得Softplus函数更加平滑。
优点:
- 平滑性:Softplus函数在输入值较大或较小时,其导数不会接近于零,从而避免了梯度消失的问题。
- 可微性:Softplus函数在整个实数范围内都是可微的,这使得它在训练神经网络时更加稳定。
缺点:
- 计算量大:由于Softplus函数包含自然对数和指数运算,计算量相对较大,可能会影响训练速度。
- 输出范围有限:Softplus函数的输出范围在(0, +∞),这可能在某些需要全范围输出的应用中不适用。
Softplus激活函数适用于以下场景:
- 隐藏层激活函数:在神经网络的隐藏层中使用Softplus函数,可以避免梯度消失问题,从而提高模型的训练效果。
- 需要平滑过渡的场景:由于Softplus函数的平滑性质,它在需要平滑过渡的场景中表现良好,例如图像处理、自然语言处理等任务。
为了求Softplus函数的导数,我们需要对Softplus函数的定义式进行求导。
Softplus函数的定义是:
softplus ( x ) = log ( 1 + e x ) \text{softplus}(x) = \log(1 + e^x) softplus(x)=log(1+ex)
利用链式法则和对数函数、指数函数的导数知识,我们可以对Softplus函数进行求导。
首先,令 u = 1 + e x u = 1 + e^x u=1+ex,则 softplus ( x ) = log ( u ) \text{softplus}(x) = \log(u) softplus(x)=log(u)。
对 u u u 求导,得到:
d u d x = d d x ( 1 + e x ) = 0 + e x = e x \frac{du}{dx} = \frac{d}{dx}(1 + e^x) = 0 + e^x = e^x dxdu=dxd(1+ex)=0+ex=ex
然后,对 log ( u ) \log(u) log(u) 求导,得到:
d d u ( log ( u ) ) = 1 u \frac{d}{du}(\log(u)) = \frac{1}{u} dud(log(u))=u1
最后,利用链式法则,将两者结合起来,得到Softplus函数的导数:
d d x ( softplus ( x ) ) = d d x ( log ( 1 + e x ) ) = 1 1 + e x ⋅ d d x ( 1 + e x ) = 1 1 + e x ⋅ e x \frac{d}{dx}(\text{softplus}(x)) = \frac{d}{dx}(\log(1 + e^x)) = \frac{1}{1 + e^x} \cdot \frac{d}{dx}(1 + e^x) = \frac{1}{1 + e^x} \cdot e^x dxd(softplus(x))=dxd(log(1+ex))=1+ex1⋅dxd(1+ex)=1+ex1⋅ex
进一步化简,得到:
d d x ( softplus ( x ) ) = e x 1 + e x \frac{d}{dx}(\text{softplus}(x)) = \frac{e^x}{1 + e^x} dxd(softplus(x))=1+exex
这个导数表达式展示了Softplus函数在任意点 x x x 上的斜率,它总是正的,并且随着 x x x 的增大而趋近于1(因为 e x e^x ex 在 x x x 趋于正无穷时远大于1)。
上图是其输出曲线,softplus和ReLU的曲线具有相似性,但是其比ReLU更为平滑。
2.1.1.2 Mish激活函数
Mish(2019)激活函数,论文地址:https://arxiv.org/abs/1908.08681
首先,我们来明确tanh
(双曲正切)函数的公式。tanh
函数是神经网络中常用的一种激活函数,它的数学表达式为:
tanh ( x ) = e x − e − x e x + e − x \tanh(x) = \frac{e^x - e^{-x}}{e^x + e^{-x}} tanh(x)=ex+e−xex−e−x
这个函数将任意实数映射到区间 ( − 1 , 1 ) (-1, 1) (−1,1)内,并且它是关于原点对称的。
接下来,我们来看Mish激活函数的公式。Mish激活函数是一种相对较新的激活函数,它在某些任务上表现出了比ReLU及其变体更好的性能。Mish函数的数学表达式为:
Mish ( x ) = x ⋅ tanh ( ln ( 1 + e x ) ) \text{Mish}(x) = x \cdot \tanh(\ln(1 + e^x)) Mish(x)=x⋅tanh(ln(1+ex))
或者,更常见地,由于 ln ( 1 + e x ) \ln(1 + e^x) ln(1+ex)可以重写为 softplus ( x ) \text{softplus}(x) softplus(x)(即Softplus函数的输出),因此Mish函数也可以表示为:
Mish ( x ) = x ⋅ tanh ( softplus ( x ) ) \text{Mish}(x) = x \cdot \tanh(\text{softplus}(x)) Mish(x)=x⋅tanh(softplus(x))
这里, softplus ( x ) = log ( 1 + e x ) \text{softplus}(x) = \log(1 + e^x) softplus(x)=log(1+ex),是一个平滑的、非负的激活函数,它在所有输入上都产生非负输出,并且当输入趋于负无穷时,输出渐近地趋近于0。
综上所述,tanh
和Mish激活函数都是神经网络中用于增加非线性的重要工具,但它们具有不同的数学表达式和特性。
和Leaky_relu激活函数的图形对比如下:
从图中可以看出该激活函数,在负值时并不是完全截断,而允许比较小的负梯度流入从而保证了信息的流动(因为梯度为负值时,作为relu激活函数,大多数神经元没有更新)
mish激活函数无边界,这让他避免了饱和(有下界,无上界)且每一点连续平滑且非单调性,从而使得梯度下降更好。
2.1.2 CSP结构和DarkNet
CSP和DarkNet的结构
2.1.2.1 CSP 结构
【CSP论文的笔记】CSP论文中的思路,我开始认为的CSP结构应该是这样的——特征输入之后,通过一个比例将其分为两个部分(CSPNet中是二等份),然后再分别输入block结构,以及后面的Partial transition处理。这样符合CSPNet论文中的理论思路。
实际的结构在输入后没有按照通道划分成两个部分,而是直接用两路的1x1卷积将输入特征进行变换。 可以理解的是,将全部的输入特征利用两路1x1进行transition,比直接划分通道能够进一步提高特征的重用性,并且在输入到resiudal block之前也确实通道减半,减少了计算量。虽然不知道这是否吻合CSP最初始的思想,但是其效果肯定是比我设想的那种情况更好的。
2.1.2.2 CSPDarknet53 结构
最终的 CSPDarknet53 的结构(右)和原版结构(左)对比
2.1.2.2 CSPDarknet53 复现
这部分的代码复现可阅读笔记。
YOLOv4__CSP__Mish__182">2.1.3 YOLOv4 同时出现 CSP 和 Mish 并协同工作
CSP(Cross Stage Partial)和Mish函数在深度学习领域,尤其是卷积神经网络(CNN)中,虽然各自扮演着不同的角色,但在某些情况下(如YOLOv4等模型中)会同时出现并协同工作。
协同工作:在YOLOv4等模型中,CSP结构和Mish函数是协同工作的。CSP结构负责改进特征提取过程,而Mish函数则作为激活函数,提高网络的学习能力和梯度传递效率。
相互补充:CSP结构通过跨阶段的部分连接减少了计算量,而Mish函数则通过其平滑、无边界的特性提高了模型的性能。两者相互补充,共同提升了模型的整体表现。
YOLOv4_196">2.2 YOLOv4中的数据增强
2.2.1 数据增强Mosaic
数据增强Mosaic、cmBN、SAT自对抗训练。
2.2.1.1【数据增强Mosaic】
Yolov4中使用的Mosaic是参考2019年底提出的CutMix数据增强的方式,但CutMix只使用了两张图片进行拼接,而Mosaic数据增强则采用了4张图片,随机缩放、随机裁剪、随机排布的方式进行拼接。
为什么要进行Mosaic数据增强呢?
在平时项目训练时,小目标的AP一般比中目标和大目标低很多。而Coco数据集中也包含大量的小目标,但比较麻烦的是小目标的分布并不均匀。Coco数据集中小目标占比达到41.4%,数量比中目标和大目标都要多。但在所有的训练集图片中,只有52.3%的图片有小目标,而中目标和大目标的分布相对来说更加均匀一些。
针对这种状况,Yolov4的作者采用了Mosaic数据增强的方式。
主要有2个优点:
丰富数据集:随机使用4张图片,随机缩放,再随机分布进行拼接,大大丰富了检测数据集,特别是随机缩放增加了很多小目标,让网络的鲁棒性更好。
batch不需要很大:Mosaic增强训练时,可以直接计算4张图片的数据,使得Mini-batch大小并不需要很大,一个GPU就可以达到比较好的效果。
2.2.1.3【SAT自对抗训练】
自对抗训练(SAT)也代表了一种新的数据增加技术,在两个前后阶段操作。
- 在第一阶段,神经网络改变原始图像而不是网络权值。通过这种方式,神经网络对自己执行一种对抗性攻击,改变原始图像,以制造图像上没有期望对象的假象。
- 在第二阶段,神经网络以正常的方式对这个修改后的图像进行检测。具体的可以参考这篇文章:https://blog.csdn.net/hgnuxc_1993/article/details/120724812
2.2.1.3【cmBN】
CmBN表示CBN修改后的版本,定义为交叉微批标准化(Cross mini-Batch Normalization, CmBN)。这只在单个批内的小批之间收集统计信息。具体的可以参考这篇文章
2.2.1.4 [Label Smoothing]
2.3 Dropblock 的采用(可以作用在任何卷积层)
Dropblock在2018年提出,论文地址:https://arxiv.org/pdf/1810.12890.pdf
传统的Dropout很简单,一句话就可以说的清:随机删除减少神经元的数量,使网络变得更简单。
yolov4中使用的Dropblock,其实和常见网络中的Dropout功能类似,也是缓解过拟合的一种正则化方式。
2.3.1 dropout 方案
Dropout的方式会随机的删减丢弃一些信息
2.3.2 dropblock 方案
丢弃策略
- 块大小(block_size):dropblock的丢弃策略首先确定要丢弃的块的大小。这个大小是一个超参数,可以根据具体任务和网络结构进行调整。块的大小决定了每次丢弃的特征区域的范围。
- 丢弃概率(γ):除了块大小外,dropblock还通过另一个超参数γ来控制丢弃的激活单元的比例。γ的值决定了在特征图中哪些区域会被丢弃,以及这些区域的大小和位置。
- 计算γ:在实际应用中,γ的值通常是根据dropout保留元素的概率(keep_prob)和特征图的大小(feat_size)来计算的。具体计算方式可能因实现而异,但目标是确保dropblock丢弃的元素数与传统dropout方法相当。
2.3.3 对比
dropout主要作用在全连接层,而dropblock可以作用在任何卷积层之上。
而Dropblock和Dropout相似,比如下图:
中间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.4 SPP、 FPN+PAN以及SAM方案
Yolov4的Neck结构主要采用了SPP模块、FPN+PAN、SAM的方式
- (Space Pyramid Pool, SPP)模块
- 路径聚合网络【增强】(Path Aggregation Network, PANet)的结构
2.4.1 SPP
参考
作者在SPP模块中,使用k={11,55,99,1313}的最大池化的方式,再将不同尺度的特征图进行Concat操作。spp模块是YOLOv4中在YOLOv3的基础上加了的模块,而PAN则也是YOLOv4的创新模块。
yolo v4 颈部网络采用了空间金字塔池化(Space Pyramid Pool, SPP)模块和路径聚合网络(Path Aggregation Network, PANet)的结构。
主要是用于对特征进行融合。SPP网络作为Neck的附加模块,采用四种不同尺度的最大化操作:1×1,5×5,9×9,13×13,对上层输出的feature map进行处理,再将不同尺度的特征图进行Concat操作。该模块显著的增加了主干特征的接收范围,并且将上下文特征信息分离出来。
FPN+PAN结构,FPN是自顶向下,将高层的特征通过上采用的方式进行传递融合,得到进行预测的特征图。而Neck这部分,除了FPN外,还在此基础上添加了一个自底向上的特征金字塔,其中包含两个PAN结构。避免了在传递的过程中出现信息丢失的问题,提高了网络预测的准确性。
2.4.2 PAN
YOLOv3中的neck只有自顶向下的FPN,对特征图进行特征融合,而YOLOv4中则是FPN+PAN的方式对特征进一步的融合
下面是YOLOv3的neck中的FPN
如图所示,FPN是自顶向下的,将高层的特征信息通过上采样的方式进行传递融合,得到进行预测的特征图。
而YOLOv4中的neck如下:
是18年CVPR的PANet,当时主要应用于图像分割领域,但Alexey将其拆分应用到Yolov4中,进一步提高特征提取的能力
原本的PANet网络的PAN结构中,两个特征图结合是采用shortcut操作,而Yolov4中则采用**concat(route)**操作,特征图融合后的尺寸发生了变化
2.4.3 【SAM】
论文中提到的SAM是修改后的SAM版本,启发于CBAM。注意Modified SAM 是和点量权重相乘。
2.5 Head头
2.5.1【loss创新】
YOLO V4用CIOU损失代替了YOLOv3的box位置损失,取代了预测框和真实框的中心点坐标以及宽高信息设定MSE(均方误差)损失函数或者BCE损失函数,其他部分损失没改变。
2.5.2【NMS创新】
三个特征图一共可以解码出 19 × 19 × 3 + 38 × 38× 3 + 76 × 76 × 3 = 22743个box以及相应的类别、置信度。 首先,设置一个置信度阈值,筛选掉低于阈值的box,再经过DIOU_NMS(非极大值抑制)后,就可以输出整个网络的预测结果了。
DIOU_NMS的处理步骤如下:
1.遍历图片中所有识别出目标的类,对每个类的所有框进行单独分析
2.再将所有的狗的预测框按分数从大到小排序,如下图:
3.下一步,设狗类概率最大的框为target,依次比较它和其他非0框进行(IOU-DIOU)计算,如果计算结果大于设定的DIoU阈值(这里是ε=0.5),就将该框的狗的概率置为0,如下target和第二个框的(IOU-DIOU)明显大于阈值0.5,所以舍去第二个框,把这个框的狗类概率设为0,如下图;
4.依次迭代,假设在经历了所有的扫描之后,对Dog类别只留下了两个框,如下:
因为对计算机来说,图片可能出现两只Dog,保留概率不为0的框是安全的。不过代码后续设置了一定的阈值(比如0.3)来删除掉概率太低的框,这里的蓝色框在最后并没有保留,因为它在最后会因为阈值不够而被剔除。
5.上面描述了对Dog种类进行的框选择。接下来,我们还要对其它79种类别分别进行上面的操作
6.最后进行纵向跨类的比较(为什么?因为上面就算保留了最大概率的Dog框,但该框可能在Cat的类别也为概率最大且比Dog的概率更大,那么我们最终要判断该框为Cat而不是Dog)。
2.5.3【SOFT-NMS】
作者除了提到了上述的NMS方法,还提到了如下的方式:
再看代码
回顾 yolo 发展过程:
- yolo v1 创新性提出了目标检测新框架,即 yolo 横空出世,那时候性能还很薄弱;
- yolo v2 通过加入各种技巧,使得 yolo 性能有了跟其它主流目标检测网络较劲的底气;
- yolo v3 基础网络的改变,大大提高了其性能,同时构建出了 yolo 的经典框架;至此,大厦已立。
基于这样的背景,yolo v4 就是集技巧之大成者,调参之经典例。
- 输入端的创新点:训练时对输入端的改进,主要包括Mosaic数据增强、cmBN、SAT自对抗训练
- BackBone主干网络:各种方法技巧结合起来,包括:CSPDarknet53、Mish激活函数、Dropblock
- Neck:目标检测网络在BackBone和最后的输出层之间往往会插入一些层,比如Yolov4中的SPP模块、FPN+PAN结构
- Head:输出层的锚框机制和Yolov3相同,主要改进的是训练时的回归框位置损失函数CIOU_Loss,以及预测框筛选的nms变为DIOU_nms
yolov4 以及转换到tensorrt (cuda),不依赖tensorrt更好
代码:https://gitee.com/hiyanyx/scaled-yolov4-tensor-rt
参考
https://blog.csdn.net/weixin_43702653/article/details/124260237
https://www.cnblogs.com/chentiao/p/16788325.html