首页IT科技yolov3开源代码(YOLOv5源码逐行超详细注释与解读(5)——配置文件yolov5s.yaml)

yolov3开源代码(YOLOv5源码逐行超详细注释与解读(5)——配置文件yolov5s.yaml)

时间2025-06-15 23:41:32分类IT科技浏览4214
导读:前言 在YOLOv5中网络结构采用...

前言

在YOLOv5中网络结构采用yaml作为配置文件             ,之前我们也介绍过                    ,YOLOv5配置了4种不同大小的网络模型      ,分别是YOLOv5s             、YOLOv5m                   、YOLOv5l       、YOLOv5x      ,这几个模型的结构基本一样                    ,不同的是depth_multiple模型深度和width_multiple模型宽度这两个参数             。 就和我们买衣服的尺码大小排序一样             ,YOLOv5s网络是YOLOv5系列中深度最小      ,特征图的宽度最小的网络                   。其他的三种都是在此基础上不断加深                   ,不断加宽       。所以             ,这篇文章我们就以yolov5s.yaml为例来介绍             。

yaml这个文件在models文件夹下,我们了解这个文件还是很重要的                   ,如果未来我们想改进算法的网络结构                   ,需要通过yaml这种形式定义模型结构,也就是说需要先修改该文件中的相关参数             ,然后再修改common.py与yolo.py中的相关代码                   。(这两个文件下一篇会具体介绍噢~)

文章代码逐行手打注释                   ,每个模块都有对应讲解      ,一文帮你梳理整个代码逻辑!

友情提示:可以先点再慢慢看哦~

源码下载地址:mirrors / ultralytics / yolov5 · GitCode

     🍀本人YOLOv5源码详解系列: 

YOLOv5源码逐行超详细注释与解读(1)——项目目录结构解析

​​​​​​YOLOv5源码逐行超详细注释与解读(2)——推理部分detect.py

YOLOv5源码逐行超详细注释与解读(3)——训练部分train.py

YOLOv5源码逐行超详细注释与解读(4)——验证部分val(test).py

YOLOv5源码逐行超详细注释与解读(6)——网络结构(1)yolo.py

YOLOv5源码逐行超详细注释与解读(7)——网络结构(2)common.py

目录 

前言

目录 

🚀一             、什么是YAML

🚀二                   、参数配置

🚀三       、先验框配置

🚀四      、backbone部分

🚀五                   、Head部分

🚀六             、整体模型 ​编辑

🚀七      、YOLOv5s                   、YOLOv5m             、YOLOv5l、YOLOv5x对比

🚀一                   、什么是YAML

YAML             ,即“ YAML Ain’t a Markup Language(YAML 不是一种标记语言)             ”的递归缩写       。YAML真实意思是 “Yet Another Markup Language(仍是一种标记语言)                    ”      。是专门用来写配置文件的语言                    ,能很好的与当下的编程语言的一些任务相互协作      ,非常简洁和强大                   。

官网上的解释是:

“YAML is a human-friendly data serialization language for all programming languages.      ”

翻译:YAML 是一种适用于所有编程语言的人性化数据序列化语言             。

提到数据序列化语言      ,我们之前可能比较熟悉的是JSON 和 XML                    ,YAML与它们类似             ,但它主要强调这种语言是以数据为中心      ,而不是以标记为中心                   ,像 XML 语言就使用了大量的标记      。并且远比这俩方便和更具可读性                   。

YAML的使用:

YAML的使用包括了两部分:一个是YAML数据的定义             ,一个是它在其他程序里如何被使用             。

YAML 的基础语法:

大小写敏感 使用缩进表示层级关系 不允许使用tab,只允许空格 缩进的空格数量不重要                   ,只要层级相同的元素左对齐即可 ‘#’ 表示注释

🚀二                   、参数配置

# 1、参数配置 # Parameters nc: 80 # 所判断目标类别的种类                   ,此处80类 depth_multiple: 0.33 # 模型层数因子 控制模型的深度(BottleneckCSP个数) width_multiple: 0.50 # 模型通道数因子 控制Conv通道channel个数(卷积核数量)

这段代码有三个参数:

nc:  数据集类别个数 depth_multiple:  用于控制层的重复的次数(深度)。通过深度参数 depth gain 在搭建每一层的时候,子模块数量=int(number*depth)             ,这样就可以起到一个动态调整模型深度的作用                   。 width_multiple:  用于控制输出特征图的通道数(宽度)                   。在模型中间层的每一层的卷积核的数量=int(number*width)                   ,这样也可以起到一个动态调整模型宽度的作用。

这三个参数      ,我们会在下一篇模型搭建 yolo.py 文件介绍中见到             ,先混个眼熟吧:

🚀三             、先验框配置

# 2                   、先验框配置 # anchors anchors: # 9个anchor                    ,其中P表示特征图的层级      ,P3/8该层特征图缩放为1/8,是第3层特征 - [10,13, 16,30, 33,23] # P3/8 FPN接主干网络下采样8倍后的anchor大小,检测小目标,10,13是一组尺寸      ,总共三组检测小目标 - [30,61, 62,45, 59,119] # P4/16 FPN接主干网络下采样4倍后的anchor大小,检测中目标                    ,共三组 - [116,90, 156,198, 373,326] # P5/32 FPN接主干网络下采样2倍后的anchor大小,检测大目标             ,共三组

YOLOv5使用k-means聚类法来初始化了9个anchors      ,任意地选择了9个聚类和3个尺度                   ,然后在各个尺度上均匀地划分聚类             。在COCO数据集上             ,这9个聚类是(10 × 13),(16 × 30)                   ,(33 × 23)                   ,(30 × 61),(62 × 45)             ,(59 × 119)                   ,(116 × 90)      ,(156 × 198)             ,(373 × 326)                   。

这9个anchor分别在三个Detect层的feature map中使用                    ,每个feature map的每个grid_cell 都有三个anchor进行预测       。

尺度越大的freature map分辨率越大      ,相对于原图的下采样越小      ,其感受野也就越小                    ,那么设置的anchors自然越小             ,如[10,13, 16,30, 33,23]      ,因此对原始图像中的小物体预测较好; 尺度越小的freature map分辨率越小                   ,相对于原图的下采样越大             ,其感受野越大,设置的anchors自然也就越大                   ,如[116, 90, 156,198, 373,326]                   ,因此对原始图像中的大物体预测较好             。

如下图所示:

🚀四       、backbone部分

# 3             、backbone部分 # YOLOv5 v6.0 backbone backbone: # [from, number, module, args] [[-1, 1, Conv, [64, 6, 2, 2]], # 0-P1/2 [3, 32, 6, 2, 2] [-1, 1, Conv, [128, 3, 2]], # 1-P2/4 [32, 64, 3, 2] [-1, 3, C3, [128]], # 2 [64, 64, 1] [-1, 1, Conv, [256, 3, 2]], # 3-P3/8 [64, 128, 3, 2] [-1, 6, C3, [256]], # 4 [128, 128, 2] [-1, 1, Conv, [512, 3, 2]], # 5-P4/16 [128, 256, 3, 2] [-1, 9, C3, [512]], # 6 [256, 256, 3] [-1, 1, Conv, [1024, 3, 2]], # 7-P5/32 [256, 512, 3, 2] [-1, 3, C3, [1024]], # 8 [512, 512, 1] [-1, 1, SPPF, [1024, 5]], # 9 [512, 512, 5] ]

这段代码是YOLOv5s的backbone部分, 首先介绍四个参数:

[from, number, module, args]

from :   表示当前模块的输入来自那一层的输出             ,-1表示将上一层的输出当做自己的输入(第0层的-1表示输入的图像)                   。 number:  表示当前模块的重复次数                   ,实际的重复次数还要由上面的参数depth_multiple共同决定      ,决定网络模型的深度       。 module:  表示该层模块的名称             ,这些模块写在common.py中                    ,进行模块化的搭建网络      。 args:  表示类的初始化参数      ,用于解析作为 moudle 的传入参数      ,会在网络搭建过程中根据不同层进行改变                    ,我们后面具体分析                   。

另外             ,注释中的#0-P1/2表示该层为第0层      ,输出后会变成原图的1/2

我们来解释一下每个层参数含义以及图片变化:

原始输入图片:640*640*3

第0层:Conv层  [-1, 1, Conv, [64, 6, 2, 2]]

-1:  输入是图片 1:网络模块数量为1 Conv: 该层的网络层名字是Conv [64, 6, 2, 2]: Conv层的四个参数 64:channel=64 6:kernel_size=6 2:padding=2 2:stride=2 输出图片:320*320*64

 第1层:Conv层  [-1, 1, Conv, [128, 3, 2]]

-1:  输入是上一层的输出 1:网络模块数量为1 Conv: 该层的网络层名字是Conv [128, 3, 2]: Conv层的三个参数 128:channel=128 3:kernel_size=3 2:stride=2 输出图片:160*160*128

  第2层:C3层  [-1, 3, C3, [128]]

-1:  输入是上一层的输出 3:网络模块数量为3 C3: 该层的网络层名字是C3 [128]: C3层的参数 128:channel=128 输出图片:160*160*128

 第3层:Conv层  [-1, 1, Conv,  [256, 3, 2]]

-1:  输入是上一层的输出 1:网络模块数量为1 Conv: 该层的网络层名字是Conv [256, 3, 2]: Conv层的三个参数 256:channel=256 3:kernel_size=3 2:stride=2 图片变化:80*80*256

  第4层:C3层  [-1, 6, C3,  [256]]

-1:  输入是上一层的输出 6:网络模块数量为6 C3: 该层的网络层名字是C3 [256]: C3层的参数 256:channel=256 图片变化:80*80*256

 第5层:Conv层  [-1, 1, Conv, [512, 3, 2]]

-1:  输入是上一层的输出 1:网络模块数量为1 Conv: 该层的网络层名字是Conv [512, 3, 2]: Conv层的三个参数 512:channel=512 3:kernel_size=3 2:stride=2 输出图片:40*40*512

  第6层:C3层  [-1, 9, C3,  [512]]

-1:  输入是上一层的输出 9:网络模块数量为9 C3: 该层的网络层名字是C3 [512]: C3层的参数 512:channel=512 输出图片:40*40*512

 第7层:Conv层  [-1, 1, Conv, [1024, 3, 2]]

-1:  输入是上一层的输出 1:网络模块数量为1 Conv: 该层的网络层名字是Conv [1024, 3, 2]: Conv层的三个参数 1024:channel=1024 3:kernel_size=3 2:stride=2 输出图片:20*20*1024

 第8层:C3层  [-1, 3, C3, [1024]]

-1:  输入是上一层的输出 3:网络模块数量为3 C3: 该层的网络层名字是C3 [1024]: C3层的参数 1024:channel=1024 输出图片:20*20*1024

 第9层:SPPF层  [-1, 1, SPPF, [1024, 5]]

主要是对不同尺度特征图的融合 -1:  输入是上一层的输出 1:网络模块数量为1 SPPF: 该层的网络层名字是SPPF [1024, 5]: SPPF层的两个参数 1024:channel=1024 5:kernel_size=5 输出图片:20*20*1024

到第9层为止                   ,backbone部分就结束了             ,这个部分会形成三个接口:

第4层的输出:80*80*256 第6层的输出:40*40*512 第9层的输出:20*20*1024

结构示意图如下: 

(图片来源:【YOLO系列】YOLOv5                   、YOLOX       、YOOv6      、YOLOv7网络模型结构_DearAlbert的博客) 

 🚀五                   、Head部分

# 4             、head部分 # YOLOv5 v6.0 head head: # 前两个阶段是向上concat [[-1, 1, Conv, [512, 1, 1]], # 10 [512, 256, 1, 1] # nn.upsample不改变channel但是会把图片宽和高都变为2[-1, 1, nn.Upsample, [None, 2, nearest]], # 11 [None, 2, nearest] # 与上面backbone中的 P4阶段的最后一个输出做一个concat # 进行concat的两层必须大小相同      、通道数相同 concat之后通道翻倍 [[-1, 6], 1, Concat, [1]], # 12 cat backbone P4 [1] [-1, 3, C3, [512, False]], # 13 [512, 256, 1, False] [-1, 1, Conv, [256, 1, 1]], # 14 [256, 128, 1, 1] [-1, 1, nn.Upsample, [None, 2, nearest]], #15 [None, 2, nearest] [[-1, 4], 1, Concat, [1]], # 16 cat backbone P3 [1] [-1, 3, C3, [256, False]], # 17 (P3/8-small) [256, 128, 1, False] # 后两个阶段是向下concat [-1, 1, Conv, [256, 3, 2]], # 18 [128, 128, 3, 2] [[-1, 14], 1, Concat, [1]], # 19 cat head P4 [1] [-1, 3, C3, [512, False]], # 20 (P4/16-medium) [256, 256, 1, False] [-1, 1, Conv, [512, 3, 2]], # 21 [256, 256, 3, 2] [[-1, 10], 1, Concat, [1]], # 22 cat head P5 [1] [-1, 3, C3, [1024, False]], # 23 (P5/32-large) [512, 512, 1, False] # 有三个检测层,分别是在17层下面                   、20层下面             、23层下面 [[17, 20, 23], 1, Detect, [nc, anchors]], # 24 [80                   ,[[10                   ,13,16             ,30                   ,33      ,23]             ,[30                    ,61.[128.256.512]1 ]

YOLOv5中的Head包括NeckDetect两部分             。

Neck采用了FPN+PAN结构      ,Detect结构和YOLOv3中的Head一样      。其中BottleNeckCSP带有False      ,说明没有使用残差结构                    ,而是采用的backbone中的Conv                   。

四个参数和上面backbone一样就不再解释了             ,我们来继续解释一下每个层参数含义以及图片变化:

上一个阶段输出大小:20*20*1024

首先前两个阶段是向上concat

第10层:Conv层  [-1, 1, Conv, [512, 1, 1]]

-1:  输入是上一层的输出 1:网络模块数量为1 Conv: 该层的网络层名字是Conv [512, 1, 1]: Conv层的三个参数 512:channel=512 1:kernel_size=1 1:stride=1 输出图片:20*20*512

 第11层:Upsample层  [-1, 1, nn.Upsample, [None, 2, nearest]]

-1:  输入是上一层的输出 1:网络模块数量为1 nn.Upsample: 该层的网络层名字是Upsample [None, 2, nearest] Upsample层的三个参数 Nonesize=None(指定输出的尺寸大小) 2scale_factor=2(指定输出的尺寸是输入尺寸的倍数) nearestmode=nearest(默认: ‘nearest’ 输出图片:通过该层之后特征图不改变通道数      ,特征图的长和宽会增加一倍——40*40*512

  第12层:Concat层  [[-1, 6], 1, Concat, [1]]

[-1, 6]:  输入是上一层和第6层的输出 1:网络模块数量为1 Concat: 该层的网络层名字是Concat [1]: Concat层的参数 [1]:拼接的维度=1 输出图片:通过该层之后特征图与第6层(p4阶段)的输出进行特征图的融合——40*40*1024(即输出40×40×512contact40×40×512=40×40×1024)

 第13层:C3层  [-1, 3, C3, [512, False]]

-1:  输入是上一层的输出 3:网络模块数量为1 C3: 该层的网络层名字是C3 [512, False] C3层的两个参数 512:channel=512 False没有残差模块 输出图片:40*40*512

  第14层:Conv层  [-1, 1, Conv, [256, 1, 1]]

-1:  输入是上一层的输出 1:网络模块数量为1 Conv: 该层的网络层名字是Conv [256, 1, 1]: Conv层的三个参数 256:channel=256 1:kernel_size=1 1:stride=1 输出图片:40*40*256

 第15层:Upsample层  [-1, 1, nn.Upsample, [None, 2, nearest]]

-1:  输入是上一层的输出 1:网络模块数量为1 nn.Upsample: 该层的网络层名字是Upsample [None, 2, nearest] Upsample层的三个参数 Nonesize=None(指定输出的尺寸大小) 2scale_factor=2(指定输出的尺寸是输入尺寸的倍数) nearestmode=nearest(默认: ‘nearest’ 输出图片:通过该层之后特征图不改变通道数                   ,特征图的长和宽会增加一倍——80*80*256

  第16层:Concat层  [[-1, 4], 1, Concat, [1]]

[-1, 4]:  输入是上一层和第4层的输出 1:网络模块数量为1 Concat: 该层的网络层名字是Concat [1]: Concat层的参数 [1]:拼接的维度=1 输出图片:通过该层之后特征图与第4层(p3阶段)的输出进行特征图的融合——80*80*512(即输出80×80×256contact80×80×256=80×80×512)

 第17层:C3层  [-1, 3, C3, [256, False]]

-1:  输入是上一层的输出 3:网络模块数量为1 C3: 该层的网络层名字是Conv [256, False] C3层的两个参数 256:channel=256 False没有残差模块 输出图片:80*80*256

后两个阶段是向下concat

第18层:Conv层  [-1, 1, Conv, [256, 3, 2]]

-1:  输入是上一层的输出 1:网络模块数量为1 Conv: 该层的网络层名字是Conv [256, 1, 1]: Conv层的三个参数 256:channel=256 3:kernel_size=3 2:stride=2 输出图片:40*40*256

  第19层:Concat层  [[-1, 14], 1, Concat, [1]]

[-1, 14]:  输入是上一层和第14层的输出 1:网络模块数量为1 Concat: 该层的网络层名字是Concat [1]: Concat层的参数 [1]:拼接的维度=1 输出图片:通过该层之后特征图与第14层的输出进行特征图的融合——40*40*512(即输出40×40×256contact40×40×256=40×40×512)

 第20层:C3层  [-1, 3, C3, [512, False]]

-1:  输入是上一层的输出 3:网络模块数量为3 C3: 该层的网络层名字是C3 [512, False] C3层的两个参数 512:channel=512 False没有残差模块 输出图片:40*40*512

第21层:Conv层  [-1, 1, Conv, [512, 3, 2]]

-1:  输入是图片 1:网络模块数量为1 Conv: 该层的网络层名字是Conv [512, 3, 2]: Conv层的三个参数 512:channel=512 3:kernel_size=3 2:stride=2 输出图片:20*20*512

  第22层:Concat层  [[-1, 10], 1, Concat, [1]]

[-1, 10]:  输入是上一层和第10层的输出 1:网络模块数量为1 Concat: 该层的网络层名字是Concat [1]: Concat层的参数 [1]:拼接的维度=1 输出图片:通过该层之后特征图与第10层的输出进行特征图的融合——20*20*1024(即输出20×20×512contact20×20×512=20×20×1024)

 第23层:C3层  [-1, 3, C3, [1024, False]]

-1:  输入是上一层的输出 3:网络模块数量为3 C3: 该层的网络层名字是C3 [1024, False] C3层的两个参数 1024:channel=1024 False没有残差模块 输出图片:20*20*1024

 第24层:Detect层  [[17, 20, 23], 1, Detect, [nc, anchors]]

[17, 20, 23]:  表示把第17、20和23三层作为Detect模块的输入 1:网络模块数量为1 Detect: 该层的网络层名字是Detect [nc, anchors]: 初始化Detect模块的参数 nc:类别个数 anchors超参数 anchors的值 输出图片:20*20*1024

结构示意图如下: 

🚀六                   、整体模型 

🚀七                   、YOLOv5s、YOLOv5m             、YOLOv5l                   、YOLOv5x对比

精确度对比

配置对比 

YOLOv5s YOLOv5m YOLOv5l YOLOv5x depth_multiple  0.33          0.67  1.0  1.33 width_multiple         0.50      0.75   1.0 1.25

BottleneckCSP数

BCSPn(True)

1             ,3,3 2                   ,6                   ,6  3,9             ,9  4                   ,12      ,12 BottleneckCSP数BCSPn(False) 1 2 3 4 Conv卷积核数量

32,64,128,

256,512

48,96,192,

384,768

64,128,256,

512,1024

80,160,320,

640,1280

深度对比 

 宽度对比 

本文到这里就结束了             ,有很多参数具体如何使用可以参见下一篇yolo.py的介绍(点这里直达!

另外                    ,想更加深入学习yaml文件的话      ,推荐看这篇→CSDN独家首发!万字长文      ,YOLOv5/v7/v8算法模型yaml文件史上最详细解析与教程!小白也能看懂!掌握了这个就掌握了魔改YOLO的核心!_迪菲赫尔曼的博客-CSDN博客

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
react.createelement()(【React】使用Next.js构建并部署个人博客) 网创的全称(什么的网创最正规-什么是网创?)