1、YOLO v4网络结构
图 1 YOLO v4网络结构图
由上图可知,YOLO v4主要由1输入端、backone、Neck以及Head组成。其中:
(1) 输入端通常包含图片预处理阶段,即将输入图像缩放到网络的输入大小并进行归一化等。在网络训练阶段,YOLO v4使用Mosaic数据增强提升了模型的训练速度和网络精度;利用cmBN和SAT自对抗训练提升网络的泛化性能。
(2) Backone网络主要是分类网络,提取通用的特征表示。YOLO v4中使用了CSPDarkNet53作为基准网络。并利用Mish激活函数代替原始RELU激活函数,同时增加Dropblock模块进一步提升模型的泛化能力。
(3) Neck网络进一步提升特征的多样性和鲁棒性。YOLO v4利用SPP模块融合不同尺度大小的特征图。并利用自顶向下的FPN特征金字塔与自底向上的PAN特征金字塔提升网络的特征提取能力。
(4) Head用来完成目标检测结果的输出。YOLOv4利用CIOU_Loss来代替Smooth L1 Loss函数,并利用DIOU_nms来代替传统的NMS操作,从而进一步提升算法的检测精度。
下面介绍YOLO v4中的基础组件:
CBM是Yolov4网络结构中的最小组件,由Conv+BN+Mish激活函数组成。
CB模块由Conv+BN+Leaky_relu激活函数组成。
Res unit借鉴ResNet网络中的残差结构,用来构建深层网络,CBM是残差模块中的子模块
CSPX借鉴CSPNet网络结构,由卷积层和X个Res unint模块Concate组成而成。
SPP采用1×1、5×5、9×9和13×13的最大池化方式,进行多尺度特征融合。
2、输入端
2.1 Mosaic数据增强
Mosaic数据增强利用四张图片,并且按照随机缩放、随机裁剪和随机排布的方式对四张图片进行拼接,每一张图片都有其对应的框,将四张图片拼接之后就获得一张新的图片,同时也获得这张图片对应的框,然后我们将这样一张新的图片传入到神经网络当中去学习,相当于一下子传入四张图片进行学习了。该方法极大地丰富了检测物体的背景,且在标准化BN计算的时候一下子计算四张图片的数据。在丰富数据集的同时可以极大地提升网络的训练速度并降低模型的内存需求。
2.2 cmBN
由上图可知:
BN是对当前mini-batch进行归一化。但当batch_size较小时,BN效果很差。其主要原因是数据太少不足以近似整个训练集的BN参数。
CBN对当前以及当前往前数三个mini-batch的结果进行归一化。即当前iteration的BN参数由当前batch数据求出的BN参数和保存的前几次的BN参数共同推算得出。
CMBN在整个批次中使用Cross min-batch Normalization 收集统计数据,而非在单独的mini-batch中收集统计数据。每N个batch 设置为一组,每组的第一个Batch 只用一个batch,第二个用两个batch 进行BN,...,第n个batch用前n个batch 进行BN,第n+1个batch 用2到n+1个进行BN。
2.3 SAT自对抗训练(Self-adversarial-training,SAT)
自对抗训练(SAT)是一种新的数据增强方法,它包括两个阶段。第一个阶段中,神经网络更改原始图像;第二阶段中,训练神经网络以正常方式在修改后的图像上执行目标检测任务。
3、Backone
3.1 CSPDarkNet53
CSPDarknet53是在YOLO v3主干网络Darknet53的基础上,借鉴了CSPNet算。其包含了5个CSP模块。CSP模块可以先将基础层的特征映射划分为两部分,然后通过跨阶段层次结构将它们合并起来,这样不仅减少了计算量,而且可以保证模型的准确率。
它的优点包括:(1)增强CNN网络的学习能力,轻量化模型的同时保持模型的精度;(2)降低整个模型的计算瓶颈;(3)降低算法的内存成本。
3.2 Mish激活函数
该函数是在Leaky_relu算法的基础上改进而来的。如下图所示,当x>0时,Leaky_relu与Mish激活函数基本相同;当x<0时,Mish函数基本为0,而Leaky_relu函数为λx。Mish函数更加平滑一些,可以进一步提升模型的精度。
YOLOv4的Backbone中均使用了Mish激活函数,而后面的Neck网络中则使用了leaky_relu激活函数。
图2 Mish激活函数
图3 Leaky_relu激活函数
3.3 Dropblock
Dropblock是一种解决模型过拟合的正则化方法,它的作用与Dropout基本相同。Dropout的主要思路是随机的使网络中的一些神经元失活,从而形成一个新的网络。如下图所示,最左边表示原始的输入图片,中间表示经过Dropout操作之后的结果,它使得图像中的一些位置随机失活。但由于卷积层通常是三层结构,即卷积+激活+池化层,池化层本身就是对相邻单元起作用,因而卷积层对于这种随机丢弃并不敏感。除此之外,即使是随机丢弃,卷积层仍然可以从相邻的激活单元学习到相同的信息。该操作直接对整个局部区域进行失活(连续的几个位置)。
其整体流程如下:
(1)输入特征层A,block_size,γ,模式(训练,测试)
(2,3,4)如果是测试,直接返回特征层A
(5)根据输入的概率γ,使用伯努利函数对生成的随机数mask矩阵进行drop,最终该步骤得到的mask只有0,1值。如下图(a)。
伯努利概率分布为0-1分布,或者两点分布,公式如下
(6)对上一步得到的mask进行max pooling操作(stride=1,kernel_size=block_size),得到最终需要使用的mask。如图(b)。
(7)输入矩阵和Mask矩阵相乘,得到输出矩阵
(8)将上一步的输出矩阵进行归一化操作,保证做DropBlock 之前和做DropBlock 之后,该层都具体相同的均值,方差。
4、Neck
4.1 SPP
SPP模块通过融合不同大小的最大池化层来获得鲁棒的特征表示,YOLOv4中的k={1*1,5*5,9*9,13*13}包含这4种形式。这里的最大池化层采用padding操作,移动步长为1,比如输入特征图的大小为13x13,使用的池化核大小为5x5,padding=1,因此池化后的特征图大小仍然是13×13。其与单纯使用最大池化方式相比,采用SPP模块的方式能够更有效的增加主干特征的接收范围,显著的分离了最重要的上下文特征。
4.2 FPN-PAN
FPN层自顶向下可以捕获强语义特征,而PAN则通过自底向上传达强定位特征,通过组合这两个模块,可以很好的完成目标定位的功能。
5、Head
参考YOLO v5算法详解_一顿能吃五大海碗啊啊啊的博客-CSDN博客中head部分