YOLOv4 补充

在这里插入图片描述

考虑到很多同学GPU显卡数量并不是很多,Yolov4对训练时的输入端进行改进,使得训练在单张GPU上也能有不错的成绩。比如数据增强Mosaic、cmBN、SAT自对抗训练
但感觉cmBN和SAT影响并不是很大,所以这里主要讲解Mosaic数据增强。

Mosaic数据增强

Yolov4中使用的Mosaic是参考2019年底提出的CutMix数据增强的方式,但CutMix只使用了两张图片进行拼接,而Mosaic数据增强则采用了4张图片,随机缩放、随机裁剪、随机排布的方式进行拼接。
在这里插入图片描述
这里首先要了解为什么要进行Mosaic数据增强呢?
在平时项目训练时,小目标的AP一般比中目标和大目标低很多。而Coco数据集中也包含大量的小目标,但比较麻烦的是小目标的分布并不均匀。
首先看下小、中、大目标的定义:
2019年发布的论文《Augmentation for small object detection》对此进行了区分
在这里插入图片描述
可以看到小目标的定义是目标框的长宽0×0~32×32之间的物体。
在这里插入图片描述
但在整体的数据集中,小、中、大目标的占比并不均衡。
如上表所示,Coco数据集中小目标占比达到41.4%,数量比中目标和大目标都要多。
但在所有的训练集图片中,只有52.3%的图片有小目标,而中目标和大目标的分布相对来说更加均匀一些。
针对这种状况,Yolov4的作者采用了Mosaic数据增强的方式。

主要有几个优点:
a. 丰富数据集:随机使用4张图片,随机缩放,再随机分布进行拼接,大大丰富了检测数据集,特别是随机缩放增加了很多小目标,让网络的鲁棒性更好。
b. 减少GPU:可能会有人说,随机缩放,普通的数据增强也可以做,但作者考虑到很多人可能只有一个GPU。
因此Mosaic增强训练时,可以直接计算4张图片的数据,使得Mini-batch大小并不需要很大,一个GPU就可以达到比较好的效果。
此外,发现另一研究者的训练方式也值得借鉴,采用的数据增强和Mosaic比较类似,也是使用4张图片(不是随机分布),但训练计算loss时,采用“缺啥补啥”的思路:
如果上一个iteration中,小物体产生的loss不足(比如小于某一个阈值),则下一个iteration就用拼接图;否则就用正常图片训练,也很有意思。
参考链接:https://www.zhihu.com/question/390191723?rf=390194081

CSPDarknet53

CSPDarknet53是在Yolov3主干网络Darknet53的基础上,借鉴2019年CSPNet的经验,产生的Backbone结构,其中包含了5个CSP模块
在这里插入图片描述
每个CSP模块前面的卷积核的大小都是3×3,步长为2,因此可以起到下采样的作用。
因为Backbone有5个CSP模块,输入图像是608*608,所以特征图变化的规律是:608->304->152->76->38->19
经过5次CSP模块后得到19x19大小的特征图。
而且作者只在Backbone中采用了Mish激活函数,网络后面仍然采用Leaky_relu激活函数。

我们再看看下作者为啥要参考2019年的CSPNet,采用CSP模块?
CSPNet论文地址:https://arxiv.org/pdf/1911.11929.pdf
CSPNet全称是Cross Stage Paritial Network,主要从网络结构设计的角度解决推理中从计算量很大的问题
CSPNet的作者认为推理计算过高的问题是由于网络优化中的梯度信息重复导致的。
因此采用CSP模块先将基础层的特征映射划分为两部分,然后通过跨阶段层次结构将它们合并,在减少了计算量的同时可以保证准确率。

因此Yolov4在主干网络Backbone采用CSPDarknet53网络结构,主要有三个方面的优点
优点一:增强CNN的学习能力,使得在轻量化的同时保持准确性。
优点二:降低计算瓶颈
优点三:降低内存成本

Mish激活函数

Mish激活函数是2019年下半年提出的激活函数
论文地址:https://arxiv.org/abs/1908.08681
leaky_relu激活函数的图形对比如下:
在这里插入图片描述
Yolov4的Backbone中都使用了Mish激活函数,而后面的网络则还是使用Leaky_relu函数。
在这里插入图片描述
Yolov4作者实验测试时,使用CSPDarknet53网络在ImageNet数据集上做图像分类任务,发现使用了Mish激活函数的TOP-1和TOP-5的精度比没有使用时都略高一些。
因此在设计Yolov4目标检测任务时,主干网络Backbone还是使用Mish激活函数。

Dropblock

Yolov4中使用的Dropblock,其实和常见网络中的Dropout功能类似,也是缓解过拟合的一种正则化方式。
Dropblock在2018年提出,论文地址:https://arxiv.org/pdf/1810.12890.pdf

传统的Dropout很简单,一句话就可以说的清:随机删除减少神经元的数量,使网络变得更简单。
在这里插入图片描述
而Dropblock和Dropout相似,比如下图:
在这里插入图片描述
中间Dropout的方式会随机的删减丢弃一些信息,但Dropblock的研究者认为,卷积层对于这种随机丢弃并不敏感.

因为卷积层通常是三层连用:卷积+激活+池化层,池化层本身就是对相邻单元起作用。

而且即使随机丢弃,卷积层仍然可以从相邻的激活单元学习到相同的信息。因此,在全连接层上效果很好的Dropout在卷积层上效果并不好

所以右图Dropblock的研究者则干脆整个局部区域进行删减丢弃。
这种方式其实是借鉴2017年的Cutout数据增强的方式,cutout是将输入图像的部分区域清零,而Dropblock则是将Cutout应用到每一个特征图。而且并不是用固定的归零比率,而是在训练时以一个小的比率开始,随着训练过程线性的增加这个比率。
在这里插入图片描述
Dropblock的研究者与Cutout数据增强对训练效果进行对比验证时,发现有几个优点:
优点一:Dropblock的效果优于Cutout
优点二:cutout只能作用于输入层,而Dropblock则是将Cutout应用到网络中的每一个特征图上
优点三:Dropblock可以定制各种组合,在训练的不同阶段可以修改删减的概率,从空间层面和时间层面,和cutout相比都有更精细的改进。
Yolov4中直接采用了更优的Dropblock,对网络的正则化过程进行了全面的升级改进。

Neck创新

在目标检测领域,为了更好的提取融合特征,通常在Backbone和输出层,会插入一些层,这个部分称为Neck。相当于目标检测网络的颈部,也是非常关键的。
Yolov4的Neck结构主要采用了SPP模块、FPN+PAN的方式。

SPP模块

SPP模块,其实在Yolov3中已经存在了,在yolov3的作用是多重感受野融合,在Yolov4的C++代码文件夹中有一个Yolov3_spp版本,但有的同学估计从来没有使用过,在Yolov4中,SPP模块仍然是在Backbone主干网络之后:
在这里插入图片描述
作者在SPP模块中,使用k={1×1,5×5,9×9,13×13}的最大池化的方式,再将不同尺度的特征图进行Concat操作。
注意:这里最大池化采用padding操作,移动的步长为1,比如13×13的输入特征图,使用5×5大小的池化核池化,padding=2,因此池化后的特征图仍然是13×13大小。

采用SPP模块的方式,比单纯的使用k×k最大池化的方式,更有效的增加主干特征的接收范围,显著的分离了最重要的上下文特征。

Yolov4的作者在使用608×608大小的图像进行测试时发现,在COCO目标检测任务中,以0.5%的额外计算代价将AP50增加了2.7%,因此Yolov4中也采用了SPP模块。

FPN+PAN

PAN结构比较有意思,看了网上Yolov4关于这个部分的讲解,大多都是讲的比较笼统的,而PAN是借鉴2018年图像分割领域PANet的创新点,有些同学可能不是很清楚。这个部分拆解开来,看下Yolov3和Yolov4中是如何设计的。

Yolov3各个网络结构
在这里插入图片描述
可以看到经过几次下采样,三个紫色箭头指向的地方,输出分别是76×76、38×38、19×19。
以及最后的Prediction中用于预测的三个特征图①19×19×255、②38×38×255、③76×76×255 [注:255表示80类别 (1+4+80)×3=255]。
我们将Neck部分用立体图画出来,更直观的看下两部分之间是如何通过FPN结构融合的。
在这里插入图片描述
如图所示,FPN自顶向下的,将高层的特征信息通过上采样的方式进行传递融合,得到进行预测的特征图。

Yolov4各个网络结构
而Yolov4中Neck这部分除了使用FPN外,还在此基础上使用了PAN结构。
在这里插入图片描述

前面CSPDarknet53中讲到,每个CSP模块前面的卷积核都是3×3大小,相当于下采样操作。
因此可以看到三个紫色箭头处的特征图是76×76、38×38、19×19。
以及最后Prediction中用于预测的三个特征图:①76×76×255,②38×38×255,③19×19×255。

我们也看下Neck部分的立体图像,看下两部分是如何通过FPN+PAN结构进行融合的。
在这里插入图片描述
和Yolov3的FPN层不同,Yolov4在FPN层的后面还添加了一个自底向上的特征金字塔

其中包含两个PAN结构

这样结合操作,FPN层自顶向下传达强语义特征,而特征金字塔则自底向上传达强定位特征,两两联手,从不同的主干层对不同的检测层进行特征聚合,这样的操作确实很牛皮。

FPN+PAN借鉴的是18年CVPR的PANet,当时主要应用于图像分割领域,但Alexey将其拆分应用到Yolov4中,进一步提高特征提取的能力

不过这里需要注意几点:
注意一:
Yolov3的FPN层输出的三个大小不一的特征图①②③直接进行预测
但Yolov4的FPN层,只使用最后的一个76×76特征图①,而经过两次PAN结构,输出预测的特征图②和③。
这里的不同也体现在cfg文件中,这一点有很多同学之前不太明白。
比如Yolov3.cfg中输入时608×608,最后的三个Yolo层中,
第一个Yolo层是最小的特征图19×19,mask=6,7,8,对应最大的anchor box。
第二个Yolo层是中等的特征图38×38,mask=3,4,5,对应中等的anchor box。
第三个Yolo层是最大的特征图76×76,mask=0,1,2,对应最小的anchor box。
而Yolov4.cfg则恰恰相反
第一个Yolo层是最大的特征图76×76,mask=0,1,2,对应最小的anchor box。
第二个Yolo层是中等的特征图38×38,mask=3,4,5,对应中等的anchor box。
第三个Yolo层是最小的特征图19×19,mask=6,7,8,对应最大的anchor box。
注意二:
原本的PANet网络的PAN结构中,两个特征图结合是采用shortcut操作,而Yolov4中则采用concat(route)操作,特征图融合后的尺寸发生了变化。
在这里插入图片描述

Prediction创新

CIOU_loss

目标检测任务的损失函数一般由Classificition Loss(分类损失函数)和Bounding Box Regeression Loss(回归损失函数)两部分构成。
Bounding Box Regeression的Loss近些年的发展过程是:Smooth L1 Loss-> IoU Loss(2016)-> GIoU Loss(2019)-> DIoU Loss(2020)->CIoU Loss(2020)

DIOU_nms

nms主要用于预测框的筛选,常用的目标检测算法中,一般采用普通的nms的方式,Yolov4则借鉴上面D/CIOU loss的论文:https://arxiv.org/pdf/1911.08287.pdf

将其中计算IOU的部分替换成DIOU的方式:
再来看下实际的案例:在这里插入图片描述

在上图重叠的摩托车检测中,中间的摩托车因为考虑边界框中心点的位置信息,也可以回归出来。
因此在重叠目标的检测中,DIOU_nms的效果优于传统的nms。

注意
有读者会有疑问,这里为什么不用CIOU_nms,而用DIOU_nms?
答:因为前面讲到的CIOU_loss,实在DIOU_loss的基础上,添加的影响因子,包含groundtruth标注框的信息,在训练时用于回归。
但在测试过程中,并没有groundtruth的信息,不用考虑影响因子,因此直接用DIOU_nms即可。

总体来说,YOLOv4的论文称的上良心之作,将近几年关于深度学习领域最新研究的tricks移植到Yolov4中做验证测试,将Yolov3的精度提高了不少。
虽然没有全新的创新,但很多改进之处都值得借鉴,借用Yolov4作者的总结。

Yolov4 主要带来了 3 点新贡献:
(1)提出了一种高效而强大的目标检测模型,使用 1080Ti 或 2080Ti 就能训练出超快、准确的目标检测器。
(2)在检测器训练过程中,验证了最先进的一些研究成果对目标检测器的影响。
(3)改进了 SOTA 方法,使其更有效、更适合单 GPU 训练。

YoloV4相关代码

1 python代码
代码地址:https://github.com/Tianxiaomo/pytorch-Yolov4
作者的训练和测试推理代码都已经完成

2 C++代码
Yolov4作者Alexey的代码,俄罗斯的大神,应该是个独立研究员,更新算法的频繁程度令人佩服。
在Yolov3作者Joseph Redmon宣布停止更新Yolo算法之后,Alexey凭借对于Yolov3算法的不断探索研究,赢得了Yolov3作者的认可,发布了Yolov4。
代码地址:https://github.com/AlexeyAB/darknet

3 python版本的Tensorrt代码
目前测试有效的有tensorflow版本:weights->pb->trt
代码地址:https://github.com/hunglc007/tensorflow-Yolov4-tflite

4 C++版本的Tensorrtrt代码
代码地址:https://github.com/wang-xinyu/tensorrtx/tree/master/Yolov4
作者自定义了Mish激活函数的Plugin层,Tensorrt加速后速度还是挺快的。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值