-
介绍:
model文件夹下的yaml文件为网络模型的配置文件,从github下载下来的代码中会给出不同的模型,从yolov5n、yolov5s、yolov5m、yolov5l、yolov5x,网络的模型依次变大。根据网上给的资料说这几个配置文件没有多大区别,控制模型大小的只有以下两个参数。
# Parameters
nc: 80 # number of classes
depth_multiple: 0.33 # model depth multiple
width_multiple: 0.50 # layer channel multiple
-
概述
整个yaml文件包括配置的backbone(主干)和head(头部)。这个网络就是各种各样的卷积、C3、concat(连接)、上采样等层组合到一起。可以从网上找一张yolov5的结构图,跟着yaml中的层一步一步走。图片如下,
引用:找不到原帖
对yaml的解析
Yolov5s.yaml 原文
# Parameters
nc: 80 # number of classes
depth_multiple: 0.33 # model depth multiple
width_multiple: 0.50 # 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
# 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
]
# 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)
]
注:这里depth_multiple和width_multiple为便于计算都认为是1,这只是一个系数。
第0层:[-1, 1, Conv, [64, 6, 2, 2]]
输入:输入的图片 640*640*3(长*宽*通道)输出:320*320*64
过程:第一个参数是这一层的输入(-1代表上一层);第二个参数是这个层循环几次,需要和depth_multiple这个系数相乘得到最终数值;第三个参数是这个层是啥,Conv是卷积;第四个参数是卷积参数,[64, 6, 2, 2]为例,第一个参数64是输出通道数需要与width_multiple相乘,第二个参数6,代表卷积核大小,第三个2是填充大小,第四个2是卷积核移动的步长。
第1层: [-1, 1, Conv, [128, 3, 2]],
输入:320*320*64 输出:160*160*128
过程:这里只有三个参数,第0层是四个参数,只是少了一个填充。所以[128, 3, 2]代表输出通道为128,卷积核是3,卷积核移动步长是2。带入上述公式可计算出输出是160*160*128。
第2层 [-1, 3, C3, [128]],
输入:160*160*128 输出:160*160*128
过程:-1:输入来自上一层
3:该层执行三次
C3:名字
[128]: 输出通道数128
第3层 [-1, 1, Conv, [256, 3, 2]]
输入:160*160*128 输出:80*80*256
过程:256:输出通道;3:卷积核大小;2:移动步长
第4层 [-1, 6, C3, [256]]
输入:80*80*256输出:80*80*256
过程:256:输出通道
第5层 [-1, 1, Conv, [512, 3, 2]]
输入:80*80*256输出:40*40*512
过程:512:输出通道;3:卷积核大小;2:移动步长
第6层 [-1, 9, C3, [512]]
输入:40*40*512输出:40*40*512
过程:512:输出通道;
第7层 [-1, 1, Conv, [1024, 3, 2]]
输入:40*40*512输出:20*20*1024
过程:1024:输出通道;3:卷积核大小;2:移动步长
第8层 [-1, 3, C3, [1024]]
输入:20*20*1024输出:20*20*1024
过程:1024:输出通道;
第9层 [-1, 1, SPPF, [1024, 5]]
输入:20*20*1024输出:20*20*1024
过程:1024:输出通道;5:池化大小
第10层 [-1, 1, Conv, [512, 1, 1]]
输入:20*20*1024输出:20*20*512
过程:512:输出通道;1:卷积核大小;1:移动步长
第11层 [-1, 1, nn.Upsample, [None, 2, "nearest"]]
输入:20*20*512输出:40*40*512
过程: 2:上采样数倍,直接用倍数与原图长宽相乘
第12层 [[-1, 6], 1, Concat, [1]]
输入:40*40*512+40*40*512输出:40*40*1024
过程:[-1, 6]连接上一层和第6层
第13层 [-1, 3, C3, [512, False]]
输入:40*40*1024 输出:40*40*512
过程:512:输出通道;False:没有残差模块
第14层 [-1, 1, Conv, [256, 1, 1]]
输入:40*40*512 输出:40*40*256
过程:256:输出通道;1:卷积核大小;1:移动步长
第15层 [-1, 1, nn.Upsample, [None, 2, "nearest"]]
输入: 40*40*256 输出:80*80*256
过程:2:上采样数倍,直接用倍数与原图长宽相乘
第16层 [[-1, 4], 1, Concat, [1]]
输入:80*80*256+80*80*256输出:80*80*512
过程:[-1, 4]连接上一层和第4层
第17层 [-1, 3, C3, [256, False]]
输入:80*80*512输出:80*80*256
过程:256:输出通道;False:没有残差模块
第18层 [-1, 1, Conv, [256, 3, 2]]
输入:80*80*256 输出:40*40*256
过程:256:输出通道;3:卷积核大小;2:移动步长
第19层 [[-1, 14], 1, Concat, [1]]
输入:40*40*256+40*40*256 输出:40*40*512
过程:[-1, 14]连接上一层和第14层
第20层 [-1, 3, C3, [512, False]]
输入:40*40*512 输出:40*40*512
过程:512:输出通道;False:没有残差模块
第21层 [-1, 1, Conv, [512, 3, 2]]
输入:40*40*512 输出:20*20*512
过程:512:输出通道;3:卷积核大小;2:移动步长
第22层 [[-1, 10], 1, Concat, [1]]
输入:20*20*512+20*20*512输出:20*20*1024
过程:[-1, 10]连接上一层和第10层
第23层 [-1, 3, C3, [1024, False]]
输入:20*20*1024输出:20*20*1024
过程:1024:输出通道;False:没有残差模块
第24层 [[17, 20, 23], 1, Detect, [nc, anchors]]
输入:17层、20层、23层 输出:Detect
过程:nc:检测种类数目,anchors:使用的锚框的数量