YOLOv9 使用中的一些问题

这里先提一嘴什么是辅助可逆分支(全名auxiliary reversible branch),在YOLOv9论文中提出利用辅助可逆分支可以使信息更加完整的传递到深层,利用辅助可逆分支在训练时反向传播更新梯度,辅助训练,论文中提到了aux branch只用在训练过程中,推理时不用,值得注意的是辅助可逆分支具有很多的参数量,是一种靠牺牲训练时间提升精度的方法。

论文中提出的PGI(可编程梯度信息)概念就是由辅助可逆分支实现的,辅助分支可以放在任何位置,这体现了其可编程的性质。

yolov9-c.pt 和 yolov9-convert.c.pt 有什么区别?

yolov9-c 是论文中提到的 yolov9 完整模型的权重偏置文件,是包括了辅助可逆分支的。而第二者是 yolov9-c.pt 中的模型删除了辅助分支之后的模型权重文件。

所以这就是 yolov9-c.pt 文件显著大于 v8 ,yolov9-convert.pt 文件小些的原因。

为什么官方项目代码中有 train.py,train_dual.py,train_triple.py,detect.py,detect_dual.py,detect_triple.py,这些 dual,triple 的含义是什么?他们之间的区别是什么?

官方对此做出了回答,detect.py 是作用于没有辅助分支(aux branch)的模型,detect_dual.py 作用于有一条辅助分支的模型,detect_triple.py 作用于有两条辅助分支的模型。

train.py,train_dual.py,train_triple.py 的含义区别和上述类似。

怎么将由train_dual.py 和 train_triple.py 训练之后得到的模型权重文件(.pt 文件)删除辅助分支,转换为无辅助分支的模型?

这是值得做的,因为删除辅助分支后,推理不再经过辅助分支,可加快推理,和论文中提到的一致。

通过官方 GitHub 项目中给出的一个 .ipynb 文件,可以对模型进行转换,删除辅助分支,下面附上链接地址https://github.com/WongKinYiu/yolov9/blob/main/tools/reparameterization.ipynb,这个文件其实可以在下载下来的项目代码中可以找到,位置就在yolov9/tools/reparameterization.ipynb。

这里附上yolov9-c模型的转换代码

import torch
from models.yolo import Model

model_file = 'runs/train/exp10/weights/best.pt'    # 训练的yolov9模型权重文件
save_file = './yolov9c_converted.pt'               # 转化后模型文件的地址
input_channels, nc = 3, 1                          # 输入通道数,预测类别数

device = torch.device("cpu")
cfg = "./models/detect/gelan-c.yaml"
model = Model(cfg, ch=input_channels, nc=nc, anchors=3)
#model = model.half()
model = model.to(device)
_ = model.eval()
ckpt = torch.load(model_file, map_location='cpu')
# ckpt['model'] = ckpt['ema']    # 转换临时best.pt可能会丢失精度,见github.com/WongKinYiu/yolov9/issues/198
model.names = ckpt['model'].names
model.nc = ckpt['model'].nc
idx = 0
for k, v in model.state_dict().items():
    if "model.{}.".format(idx) in k:
        if idx < 22:
            kr = k.replace("model.{}.".format(idx), "model.{}.".format(idx+1))
            model.state_dict()[k] -= model.state_dict()[k]
            model.state_dict()[k] += ckpt['model'].state_dict()[kr]
        elif "model.{}.cv2.".format(idx) in k:
            kr = k.replace("model.{}.cv2.".format(idx), "model.{}.cv4.".format(idx+16))
            model.state_dict()[k] -= model.state_dict()[k]
            model.state_dict()[k] += ckpt['model'].state_dict()[kr]
        elif "model.{}.cv3.".format(idx) in k:
            kr = k.replace("model.{}.cv3.".format(idx), "model.{}.cv5.".format(idx+16))
            model.state_dict()[k] -= model.state_dict()[k]
            model.state_dict()[k] += ckpt['model'].state_dict()[kr]
        elif "model.{}.dfl.".format(idx) in k:
            kr = k.replace("model.{}.dfl.".format(idx), "model.{}.dfl2.".format(idx+16))
            model.state_dict()[k] -= model.state_dict()[k]
            model.state_dict()[k] += ckpt['model'].state_dict()[kr]
    else:
        while True:
            idx += 1
            if "model.{}.".format(idx) in k:
                break
        if idx < 22:
            kr = k.replace("model.{}.".format(idx), "model.{}.".format(idx+1))
            model.state_dict()[k] -= model.state_dict()[k]
            model.state_dict()[k] += ckpt['model'].state_dict()[kr]
        elif "model.{}.cv2.".format(idx) in k:
            kr = k.replace("model.{}.cv2.".format(idx), "model.{}.cv4.".format(idx+16))
            model.state_dict()[k] -= model.state_dict()[k]
            model.state_dict()[k] += ckpt['model'].state_dict()[kr]
        elif "model.{}.cv3.".format(idx) in k:
            kr = k.replace("model.{}.cv3.".format(idx), "model.{}.cv5.".format(idx+16))
            model.state_dict()[k] -= model.state_dict()[k]
            model.state_dict()[k] += ckpt['model'].state_dict()[kr]
        elif "model.{}.dfl.".format(idx) in k:
            kr = k.replace("model.{}.dfl.".format(idx), "model.{}.dfl2.".format(idx+16))
            model.state_dict()[k] -= model.state_dict()[k]
            model.state_dict()[k] += ckpt['model'].state_dict()[kr]
_ = model.eval()
m_ckpt = {'model': model.half(),
          'optimizer': None,
          'best_fitness': None,
          'ema': None,
          'updates': None,
          'opt': None,
          'git': None,
          'date': None,
          'epoch': -1}
torch.save(m_ckpt, save_file)

通过对此代码的解析,发现这份代码将原本的yolov9-c.yaml中的网络改为了gelan-c.yaml的网络,去掉了辅助分支。那么yolov9-e的转换,自然只需要将代码中的gelan-c改为gelan-e就可以了。

去掉辅助分支后的网络才叫做yolov9,可以看到去掉辅助分支后网络参数量为25227859个,运算速度101.8GFLOPs(GFLOPs与个人设备也有关),和官方提供的数据相同。

转换后的模型,yolov9-c-converted.pt请使用detect.py进行推理检测。

  • 24
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
YOLOv4-tiny和YOLOv5s是两种目标检测算法模型。根据引用\[1\]的信息,YOLOv4-tiny在Jetson Nano上的性能为13.5FPS(使用USB摄像头)和14FPS(使用CSI摄像头),而YOLOv5s在相同环境下的性能为9FPS(使用USB摄像头)和13FPS(使用TensorRT转换后的USB摄像头),14FPS(使用TensorRT转换和DeepStream部署的CSI摄像头)。从这些数据来看,YOLOv4-tiny在Jetson Nano上的性能稍微优于YOLOv5s。 关于YOLOv5s的一些特点,引用\[2\]提到了数据加载器进行的三种数据增强:缩放、色彩空间调整和马赛克增强。马赛克数据增强是YOLOv5的创造者Glen Jocher提出的一种方法,可以有效解决模型训练的小对象问题,即小对象不如大对象那样准确地被检测到。 至于YOLOv4-tiny和YOLOv5s的创新性,引用\[3\]指出它们主要是整合了计算机视觉领域的最新技术,以显著改善YOLO对象检测的性能。虽然有人认为它们没有带来太多耳目一新的创新,但对于工程应用来说,能够整合这两个优秀的技术实例供我们免费使用和学习研究已经是非常宝贵的资源了。 总结来说,YOLOv4-tiny和YOLOv5s是两种目标检测算法模型,它们在性能和创新方面有一些差异,但都是非常有价值的技术。 #### 引用[.reference_title] - *1* [yolov4-tiny和yolov5s部署在jetson nano上的速度对比](https://blog.csdn.net/weixin_54603153/article/details/120299403)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [YOLO5相对于YOLO4的改进](https://blog.csdn.net/LarsGyonX/article/details/123280425)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值