赞
踩
在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
前言
目录
一、什么是YAML
二、参数配置
三、先验框配置
四、backbone部分
五、Head部分
六、整体模型 编辑
七、YOLOv5s、YOLOv5m、YOLOv5l、YOLOv5x对比
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 的基础语法:
# 1、参数配置
# Parameters
nc: 80 # 所判断目标类别的种类,此处80类
depth_multiple: 0.33 # 模型层数因子 控制模型的深度(BottleneckCSP个数)
width_multiple: 0.50 # 模型通道数因子 控制Conv通道channel个数(卷积核数量)
这段代码有三个参数:
这三个参数,我们会在模型搭建 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进行预测。
如下图所示:
# 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]
另外,注释中的**#0-P1/2**表示该层为第0层,输出后会变成原图的1/2
我们来解释一下每个层参数含义以及图片变化:
原始输入图片: 6406403
第0层:Conv层 [-1, 1, Conv, [64, 6, 2, 2]]
-1: 输入是图片
**1:**网络模块数量为1
Conv: 该层的网络层名字是Conv
[64, 6, 2, 2]:
Conv层的四个参数
**输出图片:**32032064
第1层:Conv层 [-1, 1, Conv, [128, 3, 2]]
-1: 输入是上一层的输出
**1:**网络模块数量为1
Conv: 该层的网络层名字是Conv
[128, 3, 2]:
Conv层的三个参数
**输出图片:**160160128
第2层:C3层 [-1, 3, C3, [128]]
-1: 输入是上一层的输出
**3:**网络模块数量为3
C3: 该层的网络层名字是C3
[128]:
C3层的参数
**输出图片:**160160128
第3层:Conv层 [-1, 1, Conv, [256, 3, 2]]
-1: 输入是上一层的输出
**1:**网络模块数量为1
Conv: 该层的网络层名字是Conv
[256, 3, 2]:
Conv层的三个参数
**图片变化:**8080256
第4层:C3层 [-1, 6, C3, [256]]
-1: 输入是上一层的输出
**6:**网络模块数量为6
C3: 该层的网络层名字是C3
[256]:
C3层的参数
**图片变化:**8080256
第5层:Conv层 [-1, 1, Conv, [512, 3, 2]]
-1: 输入是上一层的输出
**1:**网络模块数量为1
Conv: 该层的网络层名字是Conv
[512, 3, 2]:
Conv层的三个参数
**输出图片:**4040512
第6层:C3层 [-1, 9, C3, [512]]
-1: 输入是上一层的输出
**9:**网络模块数量为9
C3: 该层的网络层名字是C3
[512]:
C3层的参数
**输出图片:**4040512
第7层:Conv层 [-1, 1, Conv, [1024, 3, 2]]
-1: 输入是上一层的输出
**1:**网络模块数量为1
Conv: 该层的网络层名字是Conv
[1024, 3, 2]:
Conv层的三个参数
**输出图片:**20201024
第8层:C3层 [-1, 3, C3, [1024]]
-1: 输入是上一层的输出
**3:**网络模块数量为3
C3: 该层的网络层名字是C3
[1024]:
C3层的参数
**输出图片:**20201024
第9层:SPPF层 [-1, 1, SPPF, [1024, 5]]
主要是对不同尺度特征图的融合
-1: 输入是上一层的输出
**1:**网络模块数量为1
SPPF: 该层的网络层名字是SPPF
[1024, 5]:
SPPF层的两个参数
**输出图片:**20201024
到第9层为止,backbone部分就结束了**,**这个部分会形成三个接口:
- **第4层的输出:**8080256
- **第6层的输出:**4040512
- **第9层的输出:**20201024
结构示意图如下:
# 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包括Neck和Detect两部分。
Neck采用了FPN+PAN结构,Detect结构和YOLOv3中的Head一样。其中BottleNeckCSP带有False,说明没有使用残差结构,而是采用的backbone中的Conv。
四个参数和上面backbone一样就不再解释了,我们来继续解释一下每个层参数含义以及图片变化:
**上一个阶段输出大小:**20201024
首先前两个阶段是向上concat
第10层:Conv层 [-1, 1, Conv, [512, 1, 1]]
-1: 输入是上一层的输出
**1:**网络模块数量为1
Conv: 该层的网络层名字是Conv
[512, 1, 1]:
Conv层的三个参数
**输出图片:**2020512
第11层:Upsample层 [-1, 1, nn.Upsample, [None, 2, ‘nearest’]]
-1: 输入是上一层的输出
**1:**网络模块数量为1
nn.Upsample: 该层的网络层名字是Upsample
[None, 2, ‘nearest’]:
Upsample
层的三个参数
**输出图片:通过该层之后特征图不改变通道数,**特征图的长和宽会增加一倍——4040512
第12层:Concat层 [[-1, 6], 1, Concat, [1]]
第13层:C3层 [-1, 3, C3, [512, False]]
-1: 输入是上一层的输出
**3:**网络模块数量为3
C3: 该层的网络层名字是C3
[512, False]:
C3层的两个参数
**输出图片:**4040512
第14层:Conv层 [-1, 1, Conv, [256, 1, 1]]
-1: 输入是上一层的输出
**1:**网络模块数量为1
Conv: 该层的网络层名字是Conv
[256, 1, 1]:
Conv层的三个参数
**输出图片:**4040256
第15层:Upsample层 [-1, 1, nn.Upsample, [None, 2, ‘nearest’]]
-1: 输入是上一层的输出
**1:**网络模块数量为1
nn.Upsample: 该层的网络层名字是Upsample
[None, 2, ‘nearest’]:
Upsample
层的三个参数
**输出图片:通过该层之后特征图不改变通道数,**特征图的长和宽会增加一倍——8080256
第16层:Concat层 [[-1, 4], 1, Concat, [1]]
第17层:C3层 [-1, 3, C3, [256, False]]
-1: 输入是上一层的输出
**3:**网络模块数量为1
C3: 该层的网络层名字是Conv
[256, False]:
C3层的两个参数
**输出图片:**8080256
后两个阶段是向下concat
第18层:Conv层 [-1, 1, Conv, [256, 3, 2]]
-1: 输入是上一层的输出
**1:**网络模块数量为1
Conv: 该层的网络层名字是Conv
[256, 1, 1]:
Conv层的三个参数
**输出图片:**4040256
第19层:Concat层 [[-1, 14], 1, Concat, [1]]
第20层:C3层 [-1, 3, C3, [512, False]]
-1: 输入是上一层的输出
**3:**网络模块数量为3
C3: 该层的网络层名字是C3
[512, False]:
C3层的两个参数
**输出图片:**4040512
第21层:Conv层 [-1, 1, Conv, [512, 3, 2]]
-1: 输入是图片
**1:**网络模块数量为1
Conv: 该层的网络层名字是Conv
[512, 3, 2]:
Conv层的三个参数
**输出图片:**2020512
第22层:Concat层 [[-1, 10], 1, Concat, [1]]
第23层:C3层 [-1, 3, C3, [1024, False]]
-1: 输入是上一层的输出
**3:**网络模块数量为3
C3: 该层的网络层名字是C3
[1024, False]:
C3层的两个参数
**输出图片:**20201024
第24层:Detect层 [[17, 20, 23], 1, Detect, [nc, anchors]]
[17, 20, 23]: 表示把第17、20和23三层作为Detect模块的输入
**1:**网络模块数量为1
Detect: 该层的网络层名字是Detect
[nc, anchors]:
初始化Detect模块的参数
**输出图片:**20201024
结构示意图如下:
精确度对比
配置对比
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 |
深度对比
宽度对比
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。