一.yolov5模型结构与构建原理
修改模型结构,全部在models文件夹下面
models/common.py (加入新增网络细节)
models/yolo.py (设定网络结构传参细节)
models/##.yaml (修改模型结构配置文件)
上一篇博客用的自己标注的火影的数据集,修改的是data
data/##.yaml,
然后把数据集datasets放进项目里面
没有修改模型本身
1.用tensorboard可视化来理解模型结构:
进入到group图
综合上面的3个图,我们可以这样总结:
(1)每经过一个卷积conv,特征图/2(2)每一层都有层数标号,从0开始,这个标号非常重要,决定了特征融合是哪一层和哪一层融合(相同大小的特征图才能彼此融合)
(3)最后是融合之后的17,20,23层成为3种size的特征头
2.理解深层逻辑
(1)在train.py里面找到#model
我们只关注最后一行,给model传的参列表
cfg:对应yolov5s.yaml文件
ch:通道数为3
nc:原始类别数,修改yaml会对其更新
(2)进到Model里面看看实现
会发现这个Model其实等于DetectionModel的返回值
yolo.py:
(3)进入DetectionModel看看具体实现
会发现竟然跳到了yolo.py里面来 惊!
还记得文章最前面的这个吗?
可以看到默认是这样的:cfg果然默认是yolov5s.yaml
并且nc值如果和默认的.yaml不一样会修改nc值
还可以看到里面有这一行:
(4)转入parse_model看看
d:.yaml(注意:我们从上一层传入这个的原因是我们要遍历和使用.yaml文件里面的内容
ch:通道数
- 遍历.yaml
from:输入来自哪一层 number:重复几次 model args(参数)
补充:depth_multiple:控制真正的重复次数 number=max(1,depth_multiple*number)
width_multiple:控制输出通道数 Eg:下面这个64
这个64,6,2,2,其实对应的是Conv里面_init_的c2,k,s,p这四个,因为c1可以直接用保存的上一层的通道数,不用单独传参
commom.py里面
2.
所以ch[f],f=-1(输入通道数)
输出通道数c2=args[0]=64(其中一个例子)
二.修改网络结构(以C2f为例)
总:要修改yolov5的模型结构的话,主要改的是commom.py,yolo.py,.yaml这3个文件
目的:yolov5->yolov8的模型结构
yolov8代码下载地址:
GitHub - ultralytics/ultralytics: NEW - YOLOv8 🚀 in PyTorch > ONNX > OpenVINO > CoreML > TFLite
1.加入新增网络结构
打开yolov8文件,找到E:\ultralytics-main\ultralytics\nn\modules\block.py<=>yolov5里面的common.py
找到 C2f:
把C2f复制粘贴放到yolov5 的common.py的c3前面
因为C2f里面有Bottleneck这个函数,所有要把Bottleneck也粘贴过来
避免麻烦,我们在两个地方都加一个C2f
2.设定网络结构传参细节
在yolov5的yolo.py里面找到
def parse_model(d, ch):
加上C2f (因为它和C3的结构类似,直接加)
3.修改模型结构配置文件.yaml
(1)复制粘贴重命名一个yolov5s-C2f.yaml
(2)把里面的C3改成C2f
(3)改train.py里面的cfg
改为:
在服务器上跑结果:
successful!
三.引入注意力机制
借鉴代码:https://github.com/ZhugeKongan/Attention-mechanism-implementation
里面的se_block
1.加入新增网络结构
把借鉴的代码复制粘贴到common.py中
C2fBottleneck(nn.Module):的前面
2.修改模型结构配置文件
复制粘贴重命名yolov5s-se.yaml
修改backbone,加一个SE
因为相当于中间多加了一个第10层:
所以后面大于10层的层号都要变一下:+1
3.设定网络结构的传参细节
yolo.py
四.替换主干网络backbone(特征提取部分)为MobileNet
我们要的是models.mobilenet里面的features部分(第一个sequencial)
1-3:还不满足我们的采样要求
4:8倍下采样
5-9 :16倍下采样
10-最后:32倍下采样
head:(不用改)
backbone:(是我们修改主干真正要改的)
1.common.py里面加上:
2. .yaml
复制粘贴重命名:
注:输出通道数是查找了:
因为backbone里面变成3层了,head里面拼接的层数也要变:
3.yolo.py里面
注意:这个args是.yaml里面穿的参
arge[0]对于的是输出通道数 .yaml里面backbone的[24,1]中的24
4.改train.py里面
总结:其实是起到一个模型轻量化的作用,层数变多了,参数量变少了