一、本文介绍
大家好,本文给大家带来的是2024年2月21日全新发布的SOTA模型YOLOv9的补全教程(算是一种补全吧我个人认为),了解V7的读者都知道V7系列是不支持模型深度和宽度的修改的也就是没有办法像YOLOv8那样有多个版本(例如:V9n、V9s、V9m、V9l、V9x这样),所以我也是在YOLOv9最新版本的基础上给大家把这个共功能添加上了(修改模型的深度和宽度从而产生达到不同版本的效果),本文的内容均为我个人整理和撰写,创作不易,大家可以帮忙点赞评论支持一下!
专栏地址:YOLOv9有效涨点专栏-持续复现各种顶会内容-有效涨点-全网改进最全的专栏
目录
一、本文介绍
二、模型获取和训练
2.1 训练教程
2.2 模型下载
三、 添加多版本教程
3.1 修改一
3.2 修改二
3.3 修改三
四、运行对比
4.1 gelan-n
4.1.1 gelan-n.yaml文件
4.1.2 运行截图
4.2 gelan-s
4.2.1 gelan-s.yaml文件
4.2.1 运行截图
4.3 gelan-m
4.3.1 gelan-m.yaml文件
4.3.2 运行截图
4.4 gelan-l
4.4.1 gelan-l.yaml文件
4.4.1 运行截图
4.5 gelan-x
4.5.1 gelan-x.yaml文件
4.5.1 运行截图
五、全文总结
二、模型获取和训练
2.1 训练教程
在开始之前大家肯定要学会训练自己的YOLOv9模型(比较特殊)所以我这里给大家总结了教程,大家有需要的可以点击下面的链接进行跳转到我另一篇的文章里(文章里详细介绍了如何训练、验证、导出、推理等功能)。
使用教程:YOLOv9 | 利用yolov9训练自己的数据集 -> 推理、验证(源码解读 + 手撕结构图)
2.2 模型下载
YOLOv9已经开源在Github上了,地址如下->
官方论文地址: 官方论文地址点击即可跳转
官方代码地址: 官方代码地址点击即可跳转
三、 添加多版本教程
下面给大家添加上教程,修改教程很简单大家看着修改即可。
3.1 修改一
首先我们下载完YOLOv9的官方代码之后,我们找到如下的文件'models/yolo.py'文件,在其中找到'def parse_model(d, ch): # model_dict, input_channels(3)'。
下面的代码就是红框内的代码大家复制即可,省的自己可能打错字!
if m in (RepNCSPELAN4,):
args[1] = make_divisible(args[1] * gw, 8)
args[2] = make_divisible(args[2] * gw, 8)
args[3] = max(round(args[3] * gd), 1) if n > 1 else n
3.2 修改二
同样还是同一个文件我们往下翻一下找到'elif m is CBLinear:'然后按照我给的图片内修改即可,修改后的代码我以及提供了大家复制替换下即可。
c2 = [int(x * gw) for x in args[0]]
3.3 修改三
修改完上面之后我们可以找到我们的模型配置文件进行修改了,我这里以'models/detect/gelan.yaml'为例。进行修改,
修改后的yaml文件提供给大家!
# YOLOv9
# parameters
nc: 80 # number of classes
depth_multiple: 0.33 # model depth multiple
width_multiple: 0.25 # layer channel multiple
#activation: nn.LeakyReLU(0.1)
#activation: nn.ReLU()
# anchors
anchors: 3
# gelan backbone
backbone:
[
# conv down
[-1, 1, Conv, [64, 3, 2]], # 0-P1/2
# conv down
[-1, 1, Conv, [128, 3, 2]], # 1-P2/4
# elan-1 block
[-1, 1, RepNCSPELAN4, [256, 128, 64, 1]], # 2
# avg-conv down
[-1, 1, Conv, [256, 3, 2]], # 3-P3/8
# elan-2 block
[-1, 1, RepNCSPELAN4, [512, 256, 128, 1]], # 4
# avg-conv down
[-1, 1, Conv, [512, 3, 2]], # 5-P4/16
# elan-2 block
[-1, 1, RepNCSPELAN4, [512, 512, 256, 1]], # 6
# avg-conv down
[-1, 1, Conv, [512, 3, 2]], # 7-P5/32
# elan-2 block
[-1, 1, RepNCSPELAN4, [512, 512, 256, 1]], # 8
]
# gelan head
head:
[
# elan-spp block
[-1, 1, SPPELAN, [512, 256]], # 9
# up-concat merge
[-1, 1, nn.Upsample, [None, 2, 'nearest']],
[[-1, 6], 1, Concat, [1]], # cat backbone P4
# elan-2 block
[-1, 1, RepNCSPELAN4, [512, 512, 256, 1]], # 12
# up-concat merge
[-1, 1, nn.Upsample, [None, 2, 'nearest']],
[[-1, 4], 1, Concat, [1]], # cat backbone P3
# elan-2 block
[-1, 1, RepNCSPELAN4, [256, 256, 128, 1]], # 15 (P3/8-small)
# avg-conv-down merge
[-1, 1, Conv, [256, 3, 2]],
[[-1, 12], 1, Concat, [1]], # cat head P4
# elan-2 block
[-1, 1, RepNCSPELAN4, [512, 512, 256, 1]], # 18 (P4/16-medium)
# avg-conv-down merge
[-1, 1, Conv, [512, 3, 2]],
[[-1, 9], 1, Concat, [1]], # cat head P5
# elan-2 block
[-1, 1, RepNCSPELAN4, [512, 512, 256, 1]], # 21 (P5/32-large)
# detect
[[15, 18, 21], 1, DDetect, [nc]], # Detect(P3, P4, P5)
]
到此就修改完了,此时我们的模型就支持修改深度和宽度系数了,修改的教程也很简单不知道为什么YOLOv7的作者不提供,所以这里我也是给其做了一个补全,其中修改一的修改方法主要是因为其yaml文件配置的参数都放到了args的位置所以不能直接插入到下面的判断里,所以大家注意不要修改错了!
四、运行对比
上面我们提供了修改的教程,下面提供几个版本的yaml文件和运行截图供大家参考。
4.1 gelan-n
4.1.1 gelan-n.yaml文件
下面的两个参数是X版本对应的深度和宽度系数。
depth_multiple: 0.33 # model depth multiple
width_multiple: 0.25 # layer channel multiple
# YOLOv9
# parameters
nc: 80 # number of classes
depth_multiple: 0.33 # model depth multiple
width_multiple: 0.25 # layer channel multiple
#activation: nn.LeakyReLU(0.1)
#activation: nn.ReLU()
# anchors
anchors: 3
# gelan backbone
backbone:
[
# conv down
[-1, 1, Conv, [64, 3, 2]], # 0-P1/2
# conv down
[-1, 1, Conv, [128, 3, 2]], # 1-P2/4
# elan-1 block
[-1, 1, RepNCSPELAN4, [256, 128, 64, 1]], # 2
# avg-conv down
[-1, 1, Conv, [256, 3, 2]], # 3-P3/8
# elan-2 block
[-1, 1, RepNCSPELAN4, [512, 256, 128, 1]], # 4
# avg-conv down
[-1, 1, Conv, [512, 3, 2]], # 5-P4/16
# elan-2 block
[-1, 1, RepNCSPELAN4, [512, 512, 256, 1]], # 6
# avg-conv down
[-1, 1, Conv, [512, 3, 2]], # 7-P5/32
# elan-2 block
[-1, 1, RepNCSPELAN4, [512, 512, 256, 1]], # 8
]
# gelan head
head:
[
# elan-spp block
[-1, 1, SPPELAN, [512, 256]], # 9
# up-concat merge
[-1, 1, nn.Upsample, [None, 2, 'nearest']],
[[-1, 6], 1, Concat, [1]], # cat backbone P4
# elan-2 block
[-1, 1, RepNCSPELAN4, [512, 512, 256, 1]], # 12
# up-concat merge
[-1, 1, nn.Upsample, [None, 2, 'nearest']],
[[-1, 4], 1, Concat, [1]], # cat backbone P3
# elan-2 block
[-1, 1, RepNCSPELAN4, [256, 256, 128, 1]], # 15 (P3/8-small)
# avg-conv-down merge
[-1, 1, Conv, [256, 3, 2]],
[[-1, 12], 1, Concat, [1]], # cat head P4
# elan-2 block
[-1, 1, RepNCSPELAN4, [512, 512, 256, 1]], # 18 (P4/16-medium)
# avg-conv-down merge
[-1, 1, Conv, [512, 3, 2]],
[[-1, 9], 1, Concat, [1]], # cat head P5
# elan-2 block
[-1, 1, RepNCSPELAN4, [512, 512, 256, 1]], # 21 (P5/32-large)
# detect
[[15, 18, 21], 1, DDetect, [nc]], # Detect(P3, P4, P5)
]
4.1.2 运行截图
4.2 gelan-s
4.2.1 gelan-s.yaml文件
下面的两个参数是X版本对应的深度和宽度系数。
depth_multiple: 0.33 # model depth multiple
width_multiple: 0.50 # layer channel multiple
# YOLOv9
# parameters
nc: 80 # number of classes
depth_multiple: 0.33 # model depth multiple
width_multiple: 0.50 # layer channel multiple
#activation: nn.LeakyReLU(0.1)
#activation: nn.ReLU()
# anchors
anchors: 3
# gelan backbone
backbone:
[
# conv down
[-1, 1, Conv, [64, 3, 2]], # 0-P1/2
# conv down
[-1, 1, Conv, [128, 3, 2]], # 1-P2/4
# elan-1 block
[-1, 1, RepNCSPELAN4, [256, 128, 64, 1]], # 2
# avg-conv down
[-1, 1, Conv, [256, 3, 2]], # 3-P3/8
# elan-2 block
[-1, 1, RepNCSPELAN4, [512, 256, 128, 1]], # 4
# avg-conv down
[-1, 1, Conv, [512, 3, 2]], # 5-P4/16
# elan-2 block
[-1, 1, RepNCSPELAN4, [512, 512, 256, 1]], # 6
# avg-conv down
[-1, 1, Conv, [512, 3, 2]], # 7-P5/32
# elan-2 block
[-1, 1, RepNCSPELAN4, [512, 512, 256, 1]], # 8
]
# gelan head
head:
[
# elan-spp block
[-1, 1, SPPELAN, [512, 256]], # 9
# up-concat merge
[-1, 1, nn.Upsample, [None, 2, 'nearest']],
[[-1, 6], 1, Concat, [1]], # cat backbone P4
# elan-2 block
[-1, 1, RepNCSPELAN4, [512, 512, 256, 1]], # 12
# up-concat merge
[-1, 1, nn.Upsample, [None, 2, 'nearest']],
[[-1, 4], 1, Concat, [1]], # cat backbone P3
# elan-2 block
[-1, 1, RepNCSPELAN4, [256, 256, 128, 1]], # 15 (P3/8-small)
# avg-conv-down merge
[-1, 1, Conv, [256, 3, 2]],
[[-1, 12], 1, Concat, [1]], # cat head P4
# elan-2 block
[-1, 1, RepNCSPELAN4, [512, 512, 256, 1]], # 18 (P4/16-medium)
# avg-conv-down merge
[-1, 1, Conv, [512, 3, 2]],
[[-1, 9], 1, Concat, [1]], # cat head P5
# elan-2 block
[-1, 1, RepNCSPELAN4, [512, 512, 256, 1]], # 21 (P5/32-large)
# detect
[[15, 18, 21], 1, DDetect, [nc]], # Detect(P3, P4, P5)
]
4.2.1 运行截图
4.3 gelan-m
4.3.1 gelan-m.yaml文件
下面的两个参数是X版本对应的深度和宽度系数。
depth_multiple: 0.67 # model depth multiple
width_multiple: 0.75 # layer channel multiple
# YOLOv5 🚀 by Ultralytics, AGPL-3.0 license
# Parameters
nc: 80 # number of classes
depth_multiple: 0.67 # model depth multiple
width_multiple: 0.75 # 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)
]
4.3.2 运行截图
4.4 gelan-l
4.4.1 gelan-l.yaml文件
下面的两个参数是X版本对应的深度和宽度系数。
depth_multiple: 1.0 # model depth multiple
width_multiple: 1.0 # layer channel multiple
# YOLOv9
# parameters
nc: 80 # number of classes
depth_multiple: 1.0 # model depth multiple
width_multiple: 1.0 # layer channel multiple
#activation: nn.LeakyReLU(0.1)
#activation: nn.ReLU()
# anchors
anchors: 3
# gelan backbone
backbone:
[
# conv down
[-1, 1, Conv, [64, 3, 2]], # 0-P1/2
# conv down
[-1, 1, Conv, [128, 3, 2]], # 1-P2/4
# elan-1 block
[-1, 1, RepNCSPELAN4, [256, 128, 64, 1]], # 2
# avg-conv down
[-1, 1, Conv, [256, 3, 2]], # 3-P3/8
# elan-2 block
[-1, 1, RepNCSPELAN4, [512, 256, 128, 1]], # 4
# avg-conv down
[-1, 1, Conv, [512, 3, 2]], # 5-P4/16
# elan-2 block
[-1, 1, RepNCSPELAN4, [512, 512, 256, 1]], # 6
# avg-conv down
[-1, 1, Conv, [512, 3, 2]], # 7-P5/32
# elan-2 block
[-1, 1, RepNCSPELAN4, [512, 512, 256, 1]], # 8
]
# gelan head
head:
[
# elan-spp block
[-1, 1, SPPELAN, [512, 256]], # 9
# up-concat merge
[-1, 1, nn.Upsample, [None, 2, 'nearest']],
[[-1, 6], 1, Concat, [1]], # cat backbone P4
# elan-2 block
[-1, 1, RepNCSPELAN4, [512, 512, 256, 1]], # 12
# up-concat merge
[-1, 1, nn.Upsample, [None, 2, 'nearest']],
[[-1, 4], 1, Concat, [1]], # cat backbone P3
# elan-2 block
[-1, 1, RepNCSPELAN4, [256, 256, 128, 1]], # 15 (P3/8-small)
# avg-conv-down merge
[-1, 1, Conv, [256, 3, 2]],
[[-1, 12], 1, Concat, [1]], # cat head P4
# elan-2 block
[-1, 1, RepNCSPELAN4, [512, 512, 256, 1]], # 18 (P4/16-medium)
# avg-conv-down merge
[-1, 1, Conv, [512, 3, 2]],
[[-1, 9], 1, Concat, [1]], # cat head P5
# elan-2 block
[-1, 1, RepNCSPELAN4, [512, 512, 256, 1]], # 21 (P5/32-large)
# detect
[[15, 18, 21], 1, DDetect, [nc]], # Detect(P3, P4, P5)
]
4.4.1 运行截图
4.5 gelan-x
4.5.1 gelan-x.yaml文件
下面的两个参数是X版本对应的深度和宽度系数。
depth_multiple: 1.33 # model depth multiple
width_multiple: 1.25 # layer channel multiple
# YOLOv9
# parameters
nc: 80 # number of classes
depth_multiple: 1.33 # model depth multiple
width_multiple: 1.25 # layer channel multiple
#activation: nn.LeakyReLU(0.1)
#activation: nn.ReLU()
# anchors
anchors: 3
# gelan backbone
backbone:
[
# conv down
[-1, 1, Conv, [64, 3, 2]], # 0-P1/2
# conv down
[-1, 1, Conv, [128, 3, 2]], # 1-P2/4
# elan-1 block
[-1, 1, RepNCSPELAN4, [256, 128, 64, 1]], # 2
# avg-conv down
[-1, 1, Conv, [256, 3, 2]], # 3-P3/8
# elan-2 block
[-1, 1, RepNCSPELAN4, [512, 256, 128, 1]], # 4
# avg-conv down
[-1, 1, Conv, [512, 3, 2]], # 5-P4/16
# elan-2 block
[-1, 1, RepNCSPELAN4, [512, 512, 256, 1]], # 6
# avg-conv down
[-1, 1, Conv, [512, 3, 2]], # 7-P5/32
# elan-2 block
[-1, 1, RepNCSPELAN4, [512, 512, 256, 1]], # 8
]
# gelan head
head:
[
# elan-spp block
[-1, 1, SPPELAN, [512, 256]], # 9
# up-concat merge
[-1, 1, nn.Upsample, [None, 2, 'nearest']],
[[-1, 6], 1, Concat, [1]], # cat backbone P4
# elan-2 block
[-1, 1, RepNCSPELAN4, [512, 512, 256, 1]], # 12
# up-concat merge
[-1, 1, nn.Upsample, [None, 2, 'nearest']],
[[-1, 4], 1, Concat, [1]], # cat backbone P3
# elan-2 block
[-1, 1, RepNCSPELAN4, [256, 256, 128, 1]], # 15 (P3/8-small)
# avg-conv-down merge
[-1, 1, Conv, [256, 3, 2]],
[[-1, 12], 1, Concat, [1]], # cat head P4
# elan-2 block
[-1, 1, RepNCSPELAN4, [512, 512, 256, 1]], # 18 (P4/16-medium)
# avg-conv-down merge
[-1, 1, Conv, [512, 3, 2]],
[[-1, 9], 1, Concat, [1]], # cat head P5
# elan-2 block
[-1, 1, RepNCSPELAN4, [512, 512, 256, 1]], # 21 (P5/32-large)
# detect
[[15, 18, 21], 1, DDetect, [nc]], # Detect(P3, P4, P5)
]
4.5.1 运行截图
其他版本的这里就不提供了,主要就是修改其ymal文件中对应的深度和宽度系数即可,我上面对应的每个版本都已经提供了。
五、全文总结
到此本文的正式分享内容就结束了,在这里给大家推荐我的YOLOv9改进有效涨点专栏,本专栏目前为新开的,后期我会根据各种最新的前沿顶会进行论文复现,也会对一些老的改进机制进行补充,如果大家觉得本文帮助到你了,订阅本专栏(目前免费订阅,后期不迷路),关注后续更多的更新~
专栏地址:YOLOv9有效涨点专栏-持续复现各种顶会内容-有效涨点-全网改进最全的专栏