特征融合篇 | YOLOv8 (ultralytics) 实现 YOLOv9 辅助可逆分支架构 | 附训练推理结构图 RepNCSPELAN4/ADown/SPPELAN/train/val

本文主要是介绍特征融合篇 | YOLOv8 (ultralytics) 实现 YOLOv9 辅助可逆分支架构 | 附训练推理结构图 RepNCSPELAN4/ADown/SPPELAN/train/val,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在这里插入图片描述
在这里插入图片描述

今天的深度学习方法专注于如何设计最合适的目标函数,以使模型的预测结果最接近真实情况。同时,必须设计一个合适的架构,以便为预测提供足够的信息。现有方法忽视了一个事实,即当输入数据经过逐层特征提取和空间转换时,会丢失大量信息。本文将深入探讨数据通过深度网络传输时出现的数据丢失的重要问题,即信息瓶颈和可逆函数。我们提出了可编程梯度信息(PGI)的概念,以应对深度网络实现多个目标所需的各种变化。PGI可以为目标任务提供完整的输入信息,以计算目标函数,从而获得可靠的梯度信息来更新网络权重。此外,基于梯度路径规划设计了一种新的轻量级网络架构——通用高效层聚合网络(GELAN)。GELAN的架构证实了PGI在轻量级模型上取得了优异的结果。我们在基于 MS COCO 数据集的目标检测上验证了提出的 GELAN 和 PGI。结果显示,GELAN 仅使用传统的卷积运算符,比基于深度卷积的最新方法实现了更好的参数利用率。PGI 可以用于各种模型,从轻量级到大型模型都适用。它可以用来获取完整的信息,使得从头开始训练的模型比使用大型数据集预训练的最新模型获得更好的结果,比较结果如图1所示。

文章地址:https://arxiv.org/pdf/2402.13616.pdf


文章贡献

  1. 创新的方法论:提出了可编程梯度信息(Programmable Gradient Information, PGI)的概念和通用高效层聚合网络(Generalized Efficient Layer Aggregation Network, GELAN)的设计。这两项技术共同解决了深度学习模型中的信息丢失问题,特别是在对象检测这类复杂任务中。

  2. 高性能的对象检测模型:通过结合PGI和GELAN,开发了YOLOv9对象检测模型。该模型在保持轻量级和高效性的同时,显著提升了对象检测任务的准确性,超越了当前最先进的方法,如YOLOv5、YOLOv6、YOLOv7和YOLOv8等。

  3. 全面的实验验证:在标准的MS COCO数据集上进行了广泛的实验,验证了提出方法的有效性。实验结果不仅展示了YOLOv9在对象检测性能上的显著提升,还包括了对模型参数效率和计算效率的深入分析。

  4. 开源贡献:作者公开了YOLOv9的源代码,为研究社区提供了一个可以直接使用和进一步研究的高性能对象检测模型。这一开源贡献促进了技术的共享和交流,有助于推动对象检测技术的进一步发展。

  5. 理论与实践的结合:论文不仅从理论上探讨了PGI和GELAN的设计原理和优势,还通过实际的实验数据展示了这些理论在实践中的应用效果。这种理论与实践相结合的研究方式为解决深度学习中的实际问题提供了有力的证据和灵感。

总之,这篇论文通过提出新的技术方案和实现高性能的模型,为对象检测领域做出了重要的理论和实践贡献,特别是在提高深度学习模型处理复杂视觉任务时的性能和效率方面。


实验结果

在这里插入图片描述


结构图

在这里插入图片描述


源代码

#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''
@File      :   Yolov9.py
@Time      :   2024/03/04 14:33:12
@Author    :   CSDN迪菲赫尔曼 
@Version   :   1.0
@Reference :   https://blog.csdn.net/weixin_43694096
@Desc      :   None
'''__all__ = ("RepNCSPELAN4", "ADown", "SPPELAN", "CBFuse", "CBLinear", "Silence")import torch
from torch import nn as nn
import torch.nn.functional as F
from ultralytics.nn.modules.conv import autopad, Conv, RepConvclass RepBottleneck(nn.Module):"""Rep bottleneck."""def __init__(self, c1, c2, shortcut=True, g=1, k=(3, 3), e=0.5):"""Initializes a RepBottleneck module with customizable in/out channels, shortcut option, groups and expansionratio."""super().__init__()c_ = int(c2 * e)  # hidden channelsself.cv1 = RepConv(c1, c_, k[0], 1)self.cv2 = Conv(c_, c2, k[1], 1, g=g)self.add = shortcut and c1 == c2def forward(self, x):"""Forward pass through RepBottleneck layer."""return x + self.cv2(self.cv1(x)) if self.add else self.cv2(self.cv1(x))class RepCSP(nn.Module):"""Rep CSP Bottleneck with 3 convolutions."""def __init__(self, c1, c2, n=1, shortcut=True, g=1, e=0.5):"""Initializes RepCSP layer with given channels, repetitions, shortcut, groups and expansion ratio."""super().__init__()c_ = int(c2 * e)  # hidden channelsself.cv1 = Conv(c1, c_, 1, 1)self.cv2 = Conv(c1, c_, 1, 1)self.cv3 = Conv(2 * c_, c2, 1)  # optional act=FReLU(c2)self.m = nn.Sequential(*(RepBottleneck(c_, c_, shortcut, g, e=1.0) for _ in range(n)))def forward(self, x):"""Forward pass through RepCSP layer."""return self.cv3(torch.cat((self.m(self.cv1(x)), self.cv2(x)), 1))class RepNCSPELAN4(nn.Module):"""CSP-ELAN."""def __init__(self, c1, c2, c3, c4, n=1):"""Initializes CSP-ELAN layer with specified channel sizes, repetitions, and convolutions."""super().__init__()self.c = c3 // 2self.cv1 = Conv(c1, c3, 1, 1)self.cv2 = nn.Sequential(RepCSP(c3 // 2, c4, n), Conv(c4, c4, 3, 1))self.cv3 = nn.Sequential(RepCSP(c4, c4, n), Conv(c4, c4, 3, 1))self.cv4 = Conv(c3 + (2 * c4), c2, 1, 1)def forward(self, x):"""Forward pass through RepNCSPELAN4 layer."""y = list(self.cv1(x).chunk(2, 1))y.extend((m(y[-1])) for m in [self.cv2, self.cv3])return self.cv4(torch.cat(y, 1))def forward_split(self, x):"""Forward pass using split() instead of chunk()."""y = list(self.cv1(x).split((self.c, self.c), 1))y.extend(m(y[-1]) for m in [self.cv2, self.cv3])return self.cv4(torch.cat(y, 1))class ADown(nn.Module):"""ADown."""def __init__(self, c1, c2):"""Initializes ADown module with convolution layers to downsample input from channels c1 to c2."""super().__init__()self.c = c2 // 2self.cv1 = Conv(c1 // 2, self.c, 3, 2, 1)self.cv2 = Conv(c1 // 2, self.c, 1, 1, 0)def forward(self, x):"""Forward pass through ADown layer."""x = torch.nn.functional.avg_pool2d(x, 2, 1, 0, False, True)x1, x2 = x.chunk(2, 1)x1 = self.cv1(x1)x2 = torch.nn.functional.max_pool2d(x2, 3, 2, 1)x2 = self.cv2(x2)return torch.cat((x1, x2), 1)class SPPELAN(nn.Module):"""SPP-ELAN."""def __init__(self, c1, c2, c3, k=5):"""Initializes SPP-ELAN block with convolution and max pooling layers for spatial pyramid pooling."""super().__init__()self.c = c3self.cv1 = Conv(c1, c3, 1, 1)self.cv2 = nn.MaxPool2d(kernel_size=k, stride=1, padding=k // 2)self.cv3 = nn.MaxPool2d(kernel_size=k, stride=1, padding=k // 2)self.cv4 = nn.MaxPool2d(kernel_size=k, stride=1, padding=k // 2)self.cv5 = Conv(4 * c3, c2, 1, 1)def forward(self, x):"""Forward pass through SPPELAN layer."""y = [self.cv1(x)]y.extend(m(y[-1]) for m in [self.cv2, self.cv3, self.cv4])return self.cv5(torch.cat(y, 1))class Silence(nn.Module):"""Silence."""def __init__(self):"""Initializes the Silence module."""super(Silence, self).__init__()def forward(self, x):"""Forward pass through Silence layer."""return xclass CBLinear(nn.Module):"""CBLinear."""def __init__(self, c1, c2s, k=1, s=1, p=None, g=1):"""Initializes the CBLinear module, passing inputs unchanged."""super(CBLinear, self).__init__()self.c2s = c2sself.conv = nn.Conv2d(c1, sum(c2s), k, s, autopad(k, p), groups=g, bias=True)def forward(self, x):"""Forward pass through CBLinear layer."""outs = self.conv(x).split(self.c2s, dim=1)return outsclass CBFuse(nn.Module):"""CBFuse."""def __init__(self, idx):"""Initializes CBFuse module with layer index for selective feature fusion."""super(CBFuse, self).__init__()self.idx = idxdef forward(self, xs):"""Forward pass through CBFuse layer."""target_size = xs[-1].shape[2:]res = [F.interpolate(x[self.idx[i]], size=target_size, mode="nearest")for i, x in enumerate(xs[:-1])]out = torch.sum(torch.stack(res + xs[-1:]), dim=0)return out

改进方式

  1. ultralytics-main/ultralytics/nn/modules 文件夹下新建 Yolov9.py ,将源代码复制进去;
  2. ultralytics-main/ultralytics/nn/tasks.py中输入导包语句;
from ultralytics.nn.modules.Yolov9 import RepNCSPELAN4, ADown, SPPELAN, CBFuse, CBLinear, Silence
  1. ultralytics-main/ultralytics/nn/tasks.py 中添加模块名;
    在这里插入图片描述
    在这里插入图片描述
            RepNCSPELAN4,ADown,SPPELAN,
        elif m is CBLinear:c2 = args[0]c1 = ch[f]args = [c1, c2, *args[1:]]elif m is CBFuse:c2 = ch[f[-1]]
  1. 修改 yaml 文件,开始训练。

模型yaml文件

YOLOv9c.yaml
# YOLOv9c# parameters
nc: 80 # number of classes# gelan backbone
backbone:- [-1, 1, Conv, [64, 3, 2]] # 0-P1/2- [-1, 1, Conv, [128, 3, 2]] # 1-P2/4- [-1, 1, RepNCSPELAN4, [256, 128, 64, 1]] # 2- [-1, 1, ADown, [256]] # 3-P3/8- [-1, 1, RepNCSPELAN4, [512, 256, 128, 1]] # 4- [-1, 1, ADown, [512]] # 5-P4/16- [-1, 1, RepNCSPELAN4, [512, 512, 256, 1]] # 6- [-1, 1, ADown, [512]] # 7-P5/32- [-1, 1, RepNCSPELAN4, [512, 512, 256, 1]] # 8- [-1, 1, SPPELAN, [512, 256]] # 9head:- [-1, 1, nn.Upsample, [None, 2, "nearest"]]- [[-1, 6], 1, Concat, [1]] # cat backbone P4- [-1, 1, RepNCSPELAN4, [512, 512, 256, 1]] # 12- [-1, 1, nn.Upsample, [None, 2, "nearest"]]- [[-1, 4], 1, Concat, [1]] # cat backbone P3- [-1, 1, RepNCSPELAN4, [256, 256, 128, 1]] # 15 (P3/8-small)- [-1, 1, ADown, [256]]- [[-1, 12], 1, Concat, [1]] # cat head P4- [-1, 1, RepNCSPELAN4, [512, 512, 256, 1]] # 18 (P4/16-medium)- [-1, 1, ADown, [512]]- [[-1, 9], 1, Concat, [1]] # cat head P5- [-1, 1, RepNCSPELAN4, [512, 512, 256, 1]] # 21 (P5/32-large)- [[15, 18, 21], 1, Detect, [nc]] # Detect(P3, P4, P5)
YOLOv9e.yaml
# YOLOv9e# parameters
nc: 80 # number of classes# gelan backbone
backbone:- [-1, 1, Silence, []]- [-1, 1, Conv, [64, 3, 2]] # 1-P1/2- [-1, 1, Conv, [128, 3, 2]] # 2-P2/4- [-1, 1, RepNCSPELAN4, [256, 128, 64, 2]] # 3- [-1, 1, ADown, [256]] # 4-P3/8- [-1, 1, RepNCSPELAN4, [512, 256, 128, 2]] # 5- [-1, 1, ADown, [512]] # 6-P4/16- [-1, 1, RepNCSPELAN4, [1024, 512, 256, 2]] # 7- [-1, 1, ADown, [1024]] # 8-P5/32- [-1, 1, RepNCSPELAN4, [1024, 512, 256, 2]] # 9- [1, 1, CBLinear, [[64]]] # 10- [3, 1, CBLinear, [[64, 128]]] # 11- [5, 1, CBLinear, [[64, 128, 256]]] # 12- [7, 1, CBLinear, [[64, 128, 256, 512]]] # 13- [9, 1, CBLinear, [[64, 128, 256, 512, 1024]]] # 14- [0, 1, Conv, [64, 3, 2]] # 15-P1/2- [[10, 11, 12, 13, 14, -1], 1, CBFuse, [[0, 0, 0, 0, 0]]] # 16- [-1, 1, Conv, [128, 3, 2]] # 17-P2/4- [[11, 12, 13, 14, -1], 1, CBFuse, [[1, 1, 1, 1]]] # 18- [-1, 1, RepNCSPELAN4, [256, 128, 64, 2]] # 19- [-1, 1, ADown, [256]] # 20-P3/8- [[12, 13, 14, -1], 1, CBFuse, [[2, 2, 2]]] # 21- [-1, 1, RepNCSPELAN4, [512, 256, 128, 2]] # 22- [-1, 1, ADown, [512]] # 23-P4/16- [[13, 14, -1], 1, CBFuse, [[3, 3]]] # 24- [-1, 1, RepNCSPELAN4, [1024, 512, 256, 2]] # 25- [-1, 1, ADown, [1024]] # 26-P5/32- [[14, -1], 1, CBFuse, [[4]]] # 27- [-1, 1, RepNCSPELAN4, [1024, 512, 256, 2]] # 28- [-1, 1, SPPELAN, [512, 256]] # 29# gelan head
head:- [-1, 1, nn.Upsample, [None, 2, "nearest"]]- [[-1, 25], 1, Concat, [1]] # cat backbone P4- [-1, 1, RepNCSPELAN4, [512, 512, 256, 2]] # 32- [-1, 1, nn.Upsample, [None, 2, "nearest"]]- [[-1, 22], 1, Concat, [1]] # cat backbone P3- [-1, 1, RepNCSPELAN4, [256, 256, 128, 2]] # 35 (P3/8-small)- [-1, 1, ADown, [256]]- [[-1, 32], 1, Concat, [1]] # cat head P4- [-1, 1, RepNCSPELAN4, [512, 512, 256, 2]] # 38 (P4/16-medium)- [-1, 1, ADown, [512]]- [[-1, 29], 1, Concat, [1]] # cat head P5- [-1, 1, RepNCSPELAN4, [512, 1024, 512, 2]] # 41 (P5/32-large)- [[35, 38, 41], 1, Detect, [nc]] # Detect(P3, P4, P5)
训练结构图

在这里插入图片描述

推理结构图

在这里插入图片描述

SPPELAN

在这里插入图片描述

RepNCSPELAN4

在这里插入图片描述

ADown

在这里插入图片描述


以上结构图来自于这位大佬:https://github.com/divided7

这篇关于特征融合篇 | YOLOv8 (ultralytics) 实现 YOLOv9 辅助可逆分支架构 | 附训练推理结构图 RepNCSPELAN4/ADown/SPPELAN/train/val的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/773685

相关文章

mybatis的整体架构

mybatis的整体架构分为三层: 1.基础支持层 该层包括:数据源模块、事务管理模块、缓存模块、Binding模块、反射模块、类型转换模块、日志模块、资源加载模块、解析器模块 2.核心处理层 该层包括:配置解析、参数映射、SQL解析、SQL执行、结果集映射、插件 3.接口层 该层包括:SqlSession 基础支持层 该层保护mybatis的基础模块,它们为核心处理层提供了良好的支撑。

百度/小米/滴滴/京东,中台架构比较

小米中台建设实践 01 小米的三大中台建设:业务+数据+技术 业务中台--从业务说起 在中台建设中,需要规范化的服务接口、一致整合化的数据、容器化的技术组件以及弹性的基础设施。并结合业务情况,判定是否真的需要中台。 小米参考了业界优秀的案例包括移动中台、数据中台、业务中台、技术中台等,再结合其业务发展历程及业务现状,整理了中台架构的核心方法论,一是企业如何共享服务,二是如何为业务提供便利。

hdu1043(八数码问题,广搜 + hash(实现状态压缩) )

利用康拓展开将一个排列映射成一个自然数,然后就变成了普通的广搜题。 #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#include<stdlib.h>#include<ctype.h>#inclu

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

【Prometheus】PromQL向量匹配实现不同标签的向量数据进行运算

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi

让树莓派智能语音助手实现定时提醒功能

最初的时候是想直接在rasa 的chatbot上实现,因为rasa本身是带有remindschedule模块的。不过经过一番折腾后,忽然发现,chatbot上实现的定时,语音助手不一定会有响应。因为,我目前语音助手的代码设置了长时间无应答会结束对话,这样一来,chatbot定时提醒的触发就不会被语音助手获悉。那怎么让语音助手也具有定时提醒功能呢? 我最后选择的方法是用threading.Time

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo

C#实战|大乐透选号器[6]:实现实时显示已选择的红蓝球数量

哈喽,你好啊,我是雷工。 关于大乐透选号器在前面已经记录了5篇笔记,这是第6篇; 接下来实现实时显示当前选中红球数量,蓝球数量; 以下为练习笔记。 01 效果演示 当选择和取消选择红球或蓝球时,在对应的位置显示实时已选择的红球、蓝球的数量; 02 标签名称 分别设置Label标签名称为:lblRedCount、lblBlueCount

Kubernetes PodSecurityPolicy:PSP能实现的5种主要安全策略

Kubernetes PodSecurityPolicy:PSP能实现的5种主要安全策略 1. 特权模式限制2. 宿主机资源隔离3. 用户和组管理4. 权限提升控制5. SELinux配置 💖The Begin💖点点关注,收藏不迷路💖 Kubernetes的PodSecurityPolicy(PSP)是一个关键的安全特性,它在Pod创建之前实施安全策略,确保P

工厂ERP管理系统实现源码(JAVA)

工厂进销存管理系统是一个集采购管理、仓库管理、生产管理和销售管理于一体的综合解决方案。该系统旨在帮助企业优化流程、提高效率、降低成本,并实时掌握各环节的运营状况。 在采购管理方面,系统能够处理采购订单、供应商管理和采购入库等流程,确保采购过程的透明和高效。仓库管理方面,实现库存的精准管理,包括入库、出库、盘点等操作,确保库存数据的准确性和实时性。 生产管理模块则涵盖了生产计划制定、物料需求计划、