YOLO目标检测系列(一):
OD-Model【5】:YOLOv1
YOLO目标检测系列(二):
OD-Model【6】:YOLOv2
YOLO目标检测系列(三):
OD-Model【7】:YOLOv3
YOLO目标检测系列(四):
OD-Model【8】:YOLOv4
YOLO目标检测系列(五):
OD-Model【9】:YOLOv5
YOLOv5 并未正式发表过论文,所以本文主要参考源码及网上的高浏览博文进行总结学习
本文参考的 YOLOv5 的版本为 v6.1
YOLOv5 是一种单阶段目标检测算法,该算法在 YOLOv4 的基础上添加了一些新的改进思路,使其速度与精度都得到了极大的性能提升。虽很多人考虑到 YOLOv5 的创新性不足,对算法是否能够进化,称得上 YOLOv5 而议论纷纷。
本文主要根据网上的各位大佬写的博客以及有关源码进行学习并记录得此博客
YOLOv5 几种针对输入图片尺寸为
640
×
640
640 \times 640
640×640 的版本的速度与精度如下图所示:

该版本模型的最大池化下采样率为32倍,预设特征层为3层
YOLOv5 几种针对输入图片尺寸为 1280 × 1280 1280 \times 1280 1280×1280 的版本的速度与精度如下图所示:

该版本模型的最大池化下采样率为64倍,预设特征层为4层
网络结构主要由以下几部分组成:

上图是 YOLOv5l 对应的网络结构图。YOLOv5针对不同大小(n, s, m, l, x)的网络整体架构都是一样的,只不过会在每个子模块中采用不同的深度和宽度。
在 YOLOv5 的源代码中,作者使用 Focus 层去替换了前 3 个 YOLOv3 层,所以总的来说在保证了下采样时不丢失休息的同时,在一定程度上降低了参数量、提高了运算的速度
Focus层的主要目的是减少图层,减少参数,减少FLOPS,减少CUDA内存,提高前进和向后速度,同时最大限度地减少对mAP的影响

将每个
2
×
2
2 \times 2
2×2 的相邻像素划分为一个 patch,然后将每个 patch 中相同位置(同一颜色)像素给拼在一起就得到了4个 feature map,然后再接上一个
3
×
3
3 \times 3
3×3 大小的卷积层。

这个操作类似于邻近下采样,这样就拿到了四张图片,四张图片互补,但是没有信息丢失。这样一来,将 W、H 信息集中到了通道空间,输入通道扩充了4倍,即拼接起来的图片相对于原先的 RGB 3 通道模式变成了 12 个通道。最后将得到的新图片再经过卷积操作,最终得到了没有信息丢失情况下的二倍下采样特征图。
Focus 模块与 6 × 6 6 \times 6 6×6 是等效的。到了 v6.1 发现,将 Focus 模块替换成 6 × 6 6 \times 6 6×6 的普通卷积层,可以提高效率
两个关键概念:
对比普通下采样与 Focus:
YOLOv5 的 CSP 结构是将原输入分成两个分支,分别进行卷积操作使得通道数减半,然后一个分支进行 Bottleneck * N 操作,然后 concat 两个分支,使得 BottlenneckCSP 的输入与输出是一样的大小,这样是为了让模型学习到更多的特征。
在 backbone 中,使用 CSP1_X 结构

组件说明:
将输入分为两个分支,一个分支先通过CBS,再经过多个残差结构(Bottleneck * N),再进行一次卷积;另一个分支直接进行卷积;然后两个分支进行 concat,再经过一个 BN 层和一次 SiLU 激活,最后通过一个 CBS
CSP1_X 应用于 backbone 主干网络部分。backbone 是较深的网络,增加残差结构可以增加层与层之间反向传播的梯度值,避免因为加深而带来的梯度消失,从而可以提取到更细粒度的特征并且不用担心网络退化
将 YOLOv4 中使用的SPP替换成了 SPPF,两者的作用是一样的,但后者效率更高
SPP 结构如下图所示,是将输入并行通过多个不同大小的 MaxPool,然后做进一步融合,能在一定程度上解决目标多尺度问题。

而 SPPF 结构是将输入串行通过多个
5
×
5
5 \times 5
5×5 大小的 MaxPool 层,这里需要注意的是串行两个
5
×
5
5 \times 5
5×5 大小的 MaxPool 层是和一个
9
×
9
9 \times 9
9×9 大小的 MaxPool 层计算结果是一样的,串行三个
5
×
5
5 \times 5
5×5 大小的 MaxPool 层是和一个
13
×
13
13 \times 13
13×13 大小的 MaxPool 层计算结果是一样的(计算量更小,效率更高)。

YOLOv5 的 CSP 结构是将原输入分成两个分支,分别进行卷积操作使得通道数减半,然后一个分支进行 Bottleneck * N 操作,然后 concat 两个分支,使得 BottlenneckCSP 的输入与输出是一样的大小,这样是为了让模型学习到更多的特征。
在 neck 中,使用 CSP2_X 结构(相比于 CSP1_X 没有了残差结构,因为不需要处理比较深的网络结构)

与 YOLOv4 中使用的 Mosaic 数据增强方法一样,在我的另一篇 blog OD-Model【8】:YOLOv4 中有非常详细的讲解。

Copy-paste 有生成很多新的训练数据方法:
这些都会影响copy-paste的结果,下图就是各种各样的copy-paste方法:

具体实现方法:
需要注意的是:数据要有 segments 数据才行,即每个目标的实例分割信息
随机进行仿射变换:Rotation,Scale,Translation,Shear

mixup 是一种对图像进行混类增强的算法,它可以将不同类之间的图像以线性插值的方式进行混合,从而构建新的训练样本,扩充训练数据集
x ~ = λ x i + ( 1 − λ ) x j y ~ = λ y i + ( 1 − λ ) y j \tilde{x} = \lambda x_i + (1 - \lambda)x_j \\ \tilde{y} = \lambda y_i + (1 - \lambda)y_j x~=λxi+(1−λ)xjy~=λyi+(1−λ)yj
其中, ( x i , y i ) (x_i, y_i) (xi,yi) 和 ( x j , y j ) (x_j, y_j) (xj,yj) 是从训练数据中随机抽取的两个样本,且 λ ∈ [ 0 , 1 ] \lambda \in [0, 1] λ∈[0,1]
实现步骤:

随机调整色度,饱和度以及明度
HSV(Hue, Saturation, Value)是根据颜色的直观特性由 A. R. Smith 在1978年创建的一种颜色空间, 也称六角锥体模型(Hexcone Model)
这个模型中颜色的参数分别是:色调(Hue),饱和度(Saturation),明度(Saturation)
用下面这个圆柱体来表示 HSV 颜色空间,圆柱体的横截面可以看做是一个极坐标系 ,H 用极坐标的极角表示,S 用极坐标的极轴长度表示,V 用圆柱中轴的高度表示

随机水平翻转

在我的上一篇 blog OD-Model【8】:YOLOv4中,有关于消除 Grid 敏感度优化的讲解

在原来 YOLOv3 中,关于计算预测的目标中心坐标计算公式是:
b
x
=
σ
(
t
x
)
+
c
x
b
y
=
σ
(
t
y
)
+
c
y
b_x = \sigma(t_x) + c_x \\ b_y = \sigma(t_y) + c_y
bx=σ(tx)+cxby=σ(ty)+cy
其中:
对偏移量进行了缩放从原来的 ( 0 , 1 ) (0, 1) (0,1) 缩放到 ( − 0.5 , 1.5 ) (-0.5, 1.5) (−0.5,1.5);通过引入一个大于一的系数,让网络的预测值能够很容易达到0或者1,此时最终预测的目标中心点的坐标的计算公式为:
b x = ( σ ( t x ) ⋅ 2 − 0.5 ) + c x b x = ( σ ( t y ) ⋅ 2 − 0.5 ) + c y b_x = (\sigma(t_x) \cdot 2 - 0.5) + c_x \\ b_x = (\sigma(t_y) \cdot 2 - 0.5) + c_y bx=(σ(tx)⋅2−0.5)+cxbx=(σ(ty)⋅2−0.5)+cy
在 YOLOv5 中除了调整预测Anchor相对Grid网格左上角 ( c x , c y ) (c_x, c_y) (cx,cy) 偏移量以外,还调整了预测目标高宽的计算公式:
原本的:
b w = p w ⋅ e t w b h = p h ⋅ e t h b_w = p_w \cdot e^{t_w} \\ b_h = p_h \cdot e^{t_h} bw=pw⋅etwbh=ph⋅eth
此时 e x e^x ex 不受限,可能出现指数爆炸的情况,也就会导致损失为 NaN 以及训练不稳定的情况
调整过后的:
b w = p w ⋅ ( 2 ⋅ σ ( t w ) ) 2 b h = p w h ⋅ ( 2 ⋅ σ ( t h ) ) 2 b_w = p_w \cdot (2 \cdot \sigma(t_w))^2 \\ b_h = p_wh\cdot (2 \cdot \sigma(t_h))^2 bw=pw⋅(2⋅σ(tw))2bh=pwh⋅(2⋅σ(th))2

很明显调整后倍率因子被限制在 ( 0 , 4 ) (0, 4) (0,4) 之间
YOLOv5 和 YOLOv4 在匹配正样本上大致相同,主要的区别在于GT Box与Anchor Templates模板的匹配方式:
如果 GT Box 和对应的 Anchor Template 的 r m a x r^{max} rmax 小于阈值 anchor_t(在源码中默认设置为4.0,由上一小节我们也可以知道,在消除 grid 敏感度的同时,已经将网络预测的相对于 anchor 模版的缩放因子限制在了对应的值内),即 GT Box 和对应的 Anchor Template 的高、宽比例相差不算太大,则将 GT Box 分配给该 Anchor Template 模板。
假设对某个 GT Box 而言,其实只要 GT Box 满足在某个 Anchor Template 宽和高的 × 0.25 \times 0.25 ×0.25 倍和 × 4.0 \times 4.0 ×4.0 倍之间就算匹配成功。

剩下的步骤和 YOLOv4 中一致,想要了解 YOLOv4 中的相关知识可以看我的另一篇 blog OD-Model【8】:YOLOv4:

需要注意的是,YOLOv5 源码中扩展 Cell 时只会往上、下、左、右四个方向扩展,不会往左上、右上、左下、右下方向扩展。下面又给出了一些根据 G T x c e n t e r GT_x^{center} GTxcenter, G T y c e n t e r GT_y^{center} GTycenter 的位置扩展的一些Cell案例,其中 % 1 \% 1 %1 表示取余并保留小数部分。

模型的权重一开始训练时是随机初始化的,此时若选择较大的学习率,模型可能出现振荡,选择 Warmup 预热学习率,可使开始训练时学习率较小,模型更容易慢慢趋于稳定

从图中可以看出,前 30 个 epochs 可以认为是一个预热过程(Warmup),在预热的时候可以看到刚开始学习率非常之小,慢慢地学习率会有增加。
待模型相对稳定后,选择余弦退火调整学习率进行训练,模型收敛速度会变得更快,模型效果更佳

在训练过程中,每个批次的训练通过余弦退火的方式来更新学习率

在常用的目标检测算法中,不同的图片长宽都不相同,因此常用的方式是将原始图片统一缩放到一个标准尺寸,再送入检测网络中。
作者认为,在项目实际使用时,很多图片的长宽比不同。因此缩放填充后,两端的黑边大小都不同,而如果填充的比较多,则存在信息冗余,影响推理速度。
通过对原始图像自适应的添加最少的黑边,减少计算量,提升目标检测速度
实现步骤:
多尺度训练
假设设置输入图片的大小为 640 × 640 640 \times 640 640×640,训练时采用尺寸是在 0.5 × 640 ∼ 1.5 × 640 0.5 \times 640 ∼ 1.5 \times 640 0.5×640∼1.5×640 之间随机取值,注意取值时取得都是32的整数倍(因为网络会最大下采样32倍)
训练自己数据集时可以根据自己数据集里的目标进行重新聚类生成 Anchors 模板
在Yolo算法中,针对不同的数据集,都会有初始设定长宽的锚框。
在网络训练中,网络在初始锚框的基础上输出预测框,进而和真实框 ground truth 进行比对,计算两者差距,再反向更新,迭代网络参数。因此初始锚框也是比较重要的一部分
可以理解为给训练的参数加了一个动量,让它更新过程更加平滑
混合精度训练,能够减少显存的占用并且加快训练速度,前提是GPU硬件支持。
YOLOv5 的损失主要由三个部分组成:
平衡不同尺度损失
针对三个预测特征层上的 obj 损失采用不同的权重
L o b j = 4.0 ⋅ L o b j s m a l l + 1.0 ⋅ L o b j m e d i u m + 0.4 ⋅ L o b j l a r g e L_{obj} = 4.0 \cdot L_{obj}^{small} + 1.0 \cdot L_{obj}^{medium} + 0.4 \cdot L_{obj}^{large} Lobj=4.0⋅Lobjsmall+1.0⋅Lobjmedium+0.4⋅Lobjlarge
YOLOv5 代码中的四种网络,都是以yaml的形式来呈现。且四个文件的内容基本上都是一样的,只有最上方的 depth_multiple 和 width_multiple 两个参数不同。
每个网络结构的两个参数:




其中 depth_multiple 控制网络的深度,width_multiple 控制网络的宽度
四种结构的yaml文件中,下方的网络架构代码都是一样的。这里我们提出 Backbon 部分,讲解如何控制网络的宽度和深度。

具体使用中:

上方的代码将四种结构的 depth_multiple,width_multiple 提取出,赋值给gd,gw

YOLOv5 有两种CSP结构,CSP1和CSP2,其中CSP1结构主要应用于Backbone中,CSP2结构主要应用于Neck中(需要注意的是,四种网络结构中每个CSP结构的深度都是不同的)
控制四种网络结构的核心代码如下所示:

存在两个变量,n 和 gd。通过将 n 和 gd 带入计算,可以看到每种网络的变化结果
将 gd (height_multiple) 系数带入


如上图表格中所示,四种 YOLOv5 结构在不同阶段的卷积核的数量都是不一样的,因此也直接影响卷积后特征图的第三维度,即模型的宽度
四种不同结构的卷积核的数量不同,这也直接影响网络中比如:CSP1 结构,CSP2 等结构,以及各个普通卷积,卷积操作时的卷积核数量也同步在调整,影响整体网络的计算量
当然卷积核的数量越多,特征图的厚度,即宽度越宽,网络提取特征的学习能力也越强


将 width_multiple 系数带入

