在YOLOv5之前的版本中,普遍采用cfg文件对其各种配置参数进行控制。从YOLOv5版本开始,正式采用了yaml配置文件格式。YOLOv5的配置文件在其源代码目录的models子目录下,该目录默认情况下包含多个模型配置文件,分别对应各个不同规模的模型结构。
从这个配置文件的结构上看,YOLOv5的配置参数信息可以分为全局参数部分和网络结构参数部分,而网络结构参数部分又可以分为backbone和head两个子部分。
全局参数
配置文件的全局参数部分如下所示:
# Parameters
nc: 80 # number of classes
depth_multiple: 1.0 # model depth multiple
width_multiple: 1.0 # layer channel multiple
anchors:
- [10, 13, 16, 30, 33, 23] # P3/8
- [30, 61, 62, 45, 59, 119] # P4/16
- [116, 90, 156, 198, 373, 326] # P5/32
nc (number of classes)
这个参数用于定义模型需要检测的目标类别数量。因为YOLOv5模型默认是使用COCO数据集训练的,所以这里默认的80就是COCO数据集所支持的目标类别数量。如果要使用自定义数据集对YOLOv5模型进行从头训练的话,nc对应为自己数据集所支持的类别数量(在数据集配置文件中设置并覆盖网络模型配置文件中的nc设置值)。
depth_multiple
depth_multiple是一个缩放因子,用于控制网络深度,具体来说是控制主干网络和颈部网络中每个C3模块(在YOLOv5 v6.0中,CSPBlock被称为C3模块)内Bottleneck残差块数量的乘数。
与depth_multiple参数相关的计算代码如下:
n = max(round(n * depth_multiple), 1) if n > 1 else n # depth gain
其中的n是在配置文件中预设的模块重复次数,max()函数用于确保计算后的模块数是一个不小于1的整数。以YOLOv5s为例,主干网络部分第三个CSP Layer的配置为[-1, 9, C3, [512]],即这个CSP Layer预设包含9个残差块。YOLOv5s的depth_multiple为0.33,因此在该模型中该层实际的残差块数量为:max(round(9 * 0.33), 1) = max(round(2.97), 1) = 3。
width_multiple
width_multiple的逻辑与depth_multiple类似,它是一个乘数因子,控制着网络中所有卷积层和C3模块(包括主干网络和颈部网络部分)的输出通道数(即特征图的卷积核数量)。在模型构建过程中,该参数会与配置文件中的预设通道数相乘,然后通过make_divisible函数确保结果是8的倍数(为了GPU计算效率):
c2 = make_divisible(c2 * width_multiple, 8)
以YOLOv5s的第一个卷积层为例,配置文件中预设的通道数为[64, 6, 2, 2](输出通道数默认为64),其width_multiple参数为0.50,因此该层实际输出的通道数为:64 × 0.50 = 32。
anchors (锚框)
与YOLOv3和v4版本相同,YOLOv5同样通过Anchor锚框机制来预设目标检测边界框的尺寸,以帮助模型更准确地定位和识别目标。YOLOv5的主干网络会输出大、中、小三种分辨率的特征图,每个特征图的每个网格会预设三个不同尺寸和长宽比的anchor框:
anchors:
- [10,13, 16,30, 33,23] # P3/8 - 小目标检测
- [30,61, 62,45, 59,119] # P4/16 - 中目标检测
- [116,90, 156,198, 373,326] # P5/32 - 大目标检测
- 配置文件中的anchor配置信息总共三行,分别对应不同尺度的特征图:P3/8、P4/16、P5/32。
- 每行包含3组宽高值,每组代表一个anchor的
[width, height]。
- 小特征图(P5/32)使用大anchor检测大目标,中特征图(P4/16)使用中等anchor检测中等目标,大特征图(P3/8)使用小anchor检测小目标。
配置文件中所设置的anchor框尺寸是基于COCO数据集的。实际上,在使用自定义数据集进行训练时,YOLOv5模型会启用一个名为“自动学习边界框锚点(Auto Learning Bounding Box Anchors)”的机制。 该机制会检查自定义数据集的anchor先验框尺寸与配置文件中的默认值是否匹配。如果不匹配,就会使用k-means方法重新计算适用于该数据集的anchor,并在后续训练中使用。
与数据集配置选项的冲突
在调用train.py进行自定义数据训练时,除了模型配置文件,还需设置数据集的配置文件(位于data目录下)。而数据集的配置文件中同样包含nc或anchors等配置选项,那么它们与模型配置文件中的选项是什么关系呢?
答案是:YOLO训练脚本会优先采用数据配置文件中的配置选项。如果模型配置文件中的nc值与数据集配置文件中的不同,终端会打印警告信息,例如:Overriding model.yaml nc=80 with nc=5。这表示程序正在将模型输出层的类别数从默认值(如COCO数据集的80类)覆盖为训练数据集的实际类别数(如5类)。
在yolo.py的DetectionModel类中,有相应代码确保当数据集配置文件提供了nc和anchors参数时,会覆盖模型配置文件中的对应值。
网络结构参数
YOLOv5的网络结构通过一个列表来定义每一层,格式为:[from, number, module, args]。以下是对各个参数的详细解释:
- from: 指定当前层的输入源。
- 在主干网络(backbone)中,通常设为
-1,表示接收上一层的输出。
- 在头部网络(head)中,会出现类似
[-1, 6]的设置,这表示将当前层(通常是上采样结果)与骨干网络中索引为6的特征图进行拼接(Concat),以实现多尺度特征融合。
- number: 定义当前模块需要重复堆叠的次数。
- 对于Conv、SPPF等无需重复的结构,该值设为1。
- 对于C3模块,该值与
depth_multiple参数协同决定最终堆叠次数:最终次数 = number × depth_multiple(结果四舍五入取整,且至少为1)。
- module: 指定该层所使用的网络模块类型,例如
Conv、C3、SPPF、Upsample、Concat、Detect等。
- args: 一个列表,用于定义模块所需的参数,具体含义取决于模块类型。例如,对于
Conv模块,args可能包含[输出通道数, 卷积核大小, 步长]。
在配置文件中,网络结构参数部分通过Backbone和Head两个段落来定义主干网络和颈部网络。
Backbone (主干网络)
主干网络结构的配置如下所示:
# YOLOv5 v6.0 backbone
backbone:
# [from, number, module, args]
[
[-1, 1, Conv, [64, 6, 2, 2]], # 0-P1/2
[-1, 1, Conv, [128, 3, 2]], # 1-P2/4
[-1, 3, C3, [128]],
[-1, 1, Conv, [256, 3, 2]], # 3-P3/8
[-1, 6, C3, [256]],
[-1, 1, Conv, [512, 3, 2]], # 5-P4/16
[-1, 9, C3, [512]],
[-1, 1, Conv, [1024, 3, 2]], # 7-P5/32
[-1, 3, C3, [1024]],
[-1, 1, SPPF, [1024, 5]], # 9
]
结合配置文件与网络结构图,可以清晰地理解主干网络的层级递进关系,它通过卷积进行下采样,并交替使用C3模块进行特征提取。
Head (头部网络)
Head部分主要定义了YOLOv5的颈部网络(Neck)和检测头(Detect)的结构。以下是默认配置:
# YOLOv5 v6.0 head
head:
[
[-1, 1, Conv, [512, 1, 1]],
[-1, 1, nn.Upsample, [None, 2, "nearest"]],
[[-1, 6], 1, Concat, [1]], # cat backbone P4
[-1, 3, C3, [512, False]], # 13
[-1, 1, Conv, [256, 1, 1]],
[-1, 1, nn.Upsample, [None, 2, "nearest"]],
[[-1, 4], 1, Concat, [1]], # cat backbone P3
[-1, 3, C3, [256, False]], # 17 (P3/8-small)
[-1, 1, Conv, [256, 3, 2]],
[[-1, 14], 1, Concat, [1]], # cat head P4
[-1, 3, C3, [512, False]], # 20 (P4/16-medium)
[-1, 1, Conv, [512, 3, 2]],
[[-1, 10], 1, Concat, [1]], # cat head P5
[-1, 3, C3, [1024, False]], # 23 (P5/32-large)
[[17, 20, 23], 1, Detect, [nc, anchors]], # Detect(P3, P4, P5)
]
头部网络的结构比主干网络稍复杂,其核心是特征金字塔网络(FPN)和路径聚合网络(PAN)的结合。它通过上采样(Upsample)和拼接(Concat)操作,将深层的高语义特征与浅层的高分辨率特征进行融合,从而构建出具有丰富信息的多尺度特征图。
配置文件中的最后一行 [[17, 20, 23], 1, Detect, [nc, anchors]] 至关重要。它表示检测头(Detect) 将接收来自第17、20、23层的输出(分别对应P3、P4、P5三个尺度的特征图),并最终在这三个尺度上预测目标的边界框、置信度和类别概率,这是模型优化和算法应用中的关键步骤。