一、YoLov5结构模型与构建原理
1、使用tensorboard绘制框架图:
打开VSCode,在终端激活对应的环境并输入以下命令:
conda activate yolov5-sider #激活环境
tensorboard --logdir runs #绘图




二、修改网络结构——以C2f为例
下载YOLOv8的代码拿来借鉴,地址如下:https://github.com/ultralytics/ultralytics

1、加入新增网络结构 -> models/commons.py
下载好后解压,打开下图目录,双击打开block1文件:

在block.py中找到C2f模块复制,打开YOLOv5的common.py文件,粘贴进去:

我们发现C2f中有Bottleneck模块,所以把Bottleneck模块也copy过来,为了避免覆盖之前yolov5的块,我们把copy过来的模块加上了前缀:

2、设定网络结构的传参细节 -> models/yolo.py
在yolov5的yolo.py中找到parse_model(同时也要导包),做以下操作:


3、修改现有模型结构配置文件 -> models/yolov5*.yaml
把yolov5s.yaml文件复制一份并重命名为yolov5s-C2f.yaml,把backbone部分所有的C3全部替换为C2f:


4、训练时指定模型结构配置文件 -> train.py
打开train.py文件,做下图修改:

打开终端(激活环境),输入以下代码:
python train.py

三、引入注意力机制——以SE为例
借鉴代码:https://github.com/ZhugeKongan/Attention-mechanism-implementation

双击打开文件:

1、加入新增网络结构 -> models/commons.py
在SE_block.py中找到SE模块复制,打开YOLOv5的common.py文件,粘贴进去:
记得把F的那个包也copy过来!!!!否则会报错


2、修改现有模型结构配置文件 -> models/yolov5*.yaml
把yolov5s.yaml文件复制一份并重命名为yolov5s-se.yaml,把backbone部分所有的C3全部替换为C2f:

当引入新的层时,要修改后续的结构中的from参数!!!
在yolov5s-se.yaml的backbone中加上SE层,head中原来的要用来concat的层数大于等于10的都1需要加上1:

3、设定网络结构的传参细节 -> models/yolo.py
当新的自定义模块中存在输入输出维度时,要使用gw调整输出维度!!!
在yolov5的yolo.py中找到parse_model(记得导包),做以下操作:


4、训练时指定模型结构配置文件 -> train.py
打开train.py文件,做下图修改:

点击运行:
四、替换主干网络——以MobileNet为例
借鉴代码:torchvision/timm
1、预准备:
打开VScode创建demo.ipynb文件,然后打开demo.ipynb文件进行以下操作:
(1)导包:
import torchvision.models as models
(2)加载MobileNet这个网络:
model = models.mobilenet_v3_small(pretrained=True, progress=True)
(3)查看网络模型:
model
用pip装torchinfo库:
pip install torchinfo
装完后导入一下:
from torchinfo import summary

通过summary()传入参数查看模型:
summary(model, input_size=(1, 3, 640, 640)) #batch:1, rgb:3, size(w,h):640

如果只想要,models中features这一部分就运行以下代码:
summary(model.features, input_size=(1, 3, 640, 640))
输入以下代码查看model.features的类型:
type(model.features)
通过查看得知model.features为sequential类型,故可以通过切片的形式查看相应的模型块,例:
model.features[:4]
2、加入新增网络结构 -> models/common.py
首先把包导入:
import torchvision.models as models

在common.py中创建类函数:
class MobileNetV3(nn.Module):
def __init__(self, slice):
super(MobileNetV3, self).__init__()
self.model = None
if slice == 1:
self.model = models.mobilenet_v3_small(pretrained=True).features[:4]
elif slice == 2:
self.model = models.mobilenet_v3_small(pretrained=True).features[4:9]
else:
self.model = models.mobilenet_v3_small(pretrained=True).features[9:]
def forward(self, x):
return self.model(x)
3、修改现有模型结构配置文件 -> models/yolov5*.yaml
当引入新的层时,要修改后续的结构中的from参数!!!
当仅替换主干网络时,要注意特征图的变换,/8,/16,/32!!!
把yolov5s.yaml文件复制一份并重命名为yolov5s-mobilenet.yaml:

把backbone部分全部注释掉,写上新的代码:

根据前面查询的模型架构填写新代码的输入通道数,三块的输入通道数分别是24,48,576:

head中原来的要用来concat的第几层都需要修改(根据特征图大小修改):

4、设定网络结构的传参细节 -> models/yolo.py
当新的自定义模块中存在输入输出维度时,要使用gw调整输出维度!!!
在yolov5的yolo.py中找到parse_model(同时也要导包),做以下操作:


5、训练时指定模型结构配置文件 -> train.py
打开train.py文件,在cfg的default不填路径得运行结果如下:

打开train.py文件,在cfg的default填上路径ROOT / "models/yolov5s-mobilenet.yaml"得运行结果如下:


通过对比可以发现改造后的模型参数量大大减少了。
参考视频:【手把手带你实战YOLOv5-进阶篇】YOLOv5 替换主干网络——以MobileNet为例_哔哩哔哩_bilibili

25万+

被折叠的 条评论
为什么被折叠?



