YOLOv7 | 添加GSConv,VoVGSCSP等多种卷积,有效提升目标检测效果,代码改进(超详细)

news2024/11/26 8:20:51

⭐欢迎大家订阅我的专栏一起学习⭐

🚀🚀🚀订阅专栏,更新及时查看不迷路🚀🚀🚀
       YOLOv5涨点专栏:http://t.csdnimg.cn/QdCj6

YOLOv7专栏: http://t.csdnimg.cn/dygOj

YOLOv8涨点专栏:http://t.csdnimg.cn/Avu8g

                    💡魔改网络、复现论文、优化创新💡                

目录

主要想法

GSConv

GSConv代码实现 

 slim-neck

  slim-neck代码实现

yaml文件

完整代码分享

总结


目标检测是计算机视觉中重要的下游任务。对于车载边缘计算平台来说,巨大的模型很难达到实时检测的要求。而且,由大量深度可分离卷积层构建的轻量级模型无法达到足够的精度。我们引入了一种新的轻量级卷积技术 GSConv,以减轻模型重量但保持准确性。 GSConv 在模型的准确性和速度之间实现了出色的权衡。并且,我们提供了一种设计范例,细颈,以实现探测器更高的计算成本效益。我们的方法的有效性在二十多组比较实验中得到了强有力的证明。特别是,与原始检测器相比,通过我们的方法改进的检测器获得了最先进的结果(例如,在公开数据集的Tesla T4 GPU 上以100FPS 的速度获得 70.9% mAP0.5)。

 主要想法

生物大脑处理信息的强大能力和低能耗远远超出了计算机。简单地无休止地增加模型参数的数量并不能建立强大的模型。轻量化设计可以有效缓解现阶段高昂的计算成本。这个目的主要是通过深度可分离卷积(DSC)运算来减少参数量和浮点运算(FLOP)来实现的,效果很明显。然而DSC的缺点也很明显:在计算过程中输入图像的通道信息被分离。这一缺陷导致 DSC 的特征提取和融合能力比标准卷积 (SC) 低得多。

 SC(左) 和 DSC(右) 的计算过程。 SC是通道密集卷积计算,DSC是通道稀疏卷积计算。

GSConv

尽管DSC有一定的优点,但DSC 的缺陷在主干中直接被放大,无论是用于图像分类还是检测。我们相信SC和DSC可以合作。我们注意到,仅通过混洗 DSC 输出通道生成的特征图仍然是“深度分离”。为了使DSC的输出尽可能接近SC,我们引入了一种新方法——SC、DSC和shuffle的混合卷积,命名为GSConv。如图所示,我们使用shuffle将SC(通道密集卷积运算)生成的信息渗透到DSC生成的信息的每个部分中。shuffle是一种统一的混合策略。该方法通过在不同通道上统一交换局部特征信息,可以将来自 SC 的信息完全混合到 DSC 的输出中,而无需任何附加功能。

GSConv 模块的结构—— “Conv”框由三层组成:卷积 2D 层、批量归一化 2D 层和激活层。这里蓝色标记的“DWConv”表示DSC操作。
GSConv代码实现 
import torch
import torch.nn as nn
import math


# GSConvE test
class GSConvE(nn.Module):
    '''
    GSConv enhancement for representation learning: generate various receptive-fields and
    texture-features only in one Conv module
    https://github.com/AlanLi1997/slim-neck-by-gsconv
    '''
    def __init__(self, c1, c2, k=1, s=1, g=1, act=True):
        super().__init__()
        c_ = c2 // 4
        self.cv1 = Conv(c1, c_, k, s, None, g, act)
        self.cv2 = Conv(c_, c_, 9, 1, None, c_, act)
        self.cv3 = Conv(c_, c_, 13, 1, None, c_, act)
        self.cv4 = Conv(c_, c_, 17, 1, None, c_, act)

    def forward(self, x):
        x1 = self.cv1(x)
        x2 = self.cv2(x1)
        x3 = self.cv3(x1)
        x4 = self.cv4(x1)

        y = torch.cat((x1, x2, x3, x4), dim=1)
        # shuffle
        y = y.reshape(y.shape[0], 2, y.shape[1] // 2, y.shape[2], y.shape[3])
        y = y.permute(0, 2, 1, 3, 4)
        return y.reshape(y.shape[0], -1, y.shape[3], y.shape[4])


def autopad(k, p=None):  # kernel, padding
    # Pad to 'same'
    if p is None:
        p = k // 2 if isinstance(k, int) else [x // 2 for x in k]  # auto-pad
    return p


class Conv(nn.Module):
    # C_B_M
    def __init__(self, c1, c2, k=1, s=1, p=None, g=1, act=True):
        super().__init__()
        self.conv = nn.Conv2d(c1, c2, k, s, autopad(k, p), groups=g, bias=False)
        self.bn = nn.BatchNorm2d(c2)
        self.act = nn.Mish() if act else (act if isinstance(act, nn.Module) else nn.Identity())

    def forward(self, x):
        return self.act(self.bn(self.conv(x)))

    def forward_fuse(self, x):
        return self.act(self.conv(x))


class GSConv(nn.Module):
    # GSConv https://github.com/AlanLi1997/slim-neck-by-gsconv
    def __init__(self, c1, c2, k=1, s=1, g=1, act=True):
        super().__init__()
        c_ = c2 // 2
        self.cv1 = Conv(c1, c_, k, s, None, g, act)
        self.cv2 = Conv(c_, c_, 5, 1, None, c_, act)

    def forward(self, x):
        x1 = self.cv1(x)
        x2 = torch.cat((x1, self.cv2(x1)), 1)
        # shuffle
        y = x2.reshape(x2.shape[0], 2, x2.shape[1] // 2, x2.shape[2], x2.shape[3])
        y = y.permute(0, 2, 1, 3, 4)
        return y.reshape(y.shape[0], -1, y.shape[3], y.shape[4])


class GSConvns(GSConv):
    # GSConv with a normative-shuffle https://github.com/AlanLi1997/slim-neck-by-gsconv
    def __init__(self, c1, c2, k=1, s=1, g=1, act=True):
        super().__init__(c1, c2, k=1, s=1, g=1, act=True)
        c_ = c2 // 2
        self.shuf = nn.Conv2d(c_ * 2, c2, 1, 1, 0, bias=False)

    def forward(self, x):
        x1 = self.cv1(x)
        x2 = torch.cat((x1, self.cv2(x1)), 1)
        # normative-shuffle, TRT supported
        return nn.ReLU(self.shuf(x2))


class GSBottleneck(nn.Module):
    # GS Bottleneck https://github.com/AlanLi1997/slim-neck-by-gsconv
    def __init__(self, c1, c2, k=3, s=1):
        super().__init__()
        c_ = c2 // 2
        # for lighting
        self.conv_lighting = nn.Sequential(
            GSConv(c1, c_, 1, 1),
            GSConv(c_, c2, 3, 1, act=False))
        self.shortcut = Conv(c1, c2, 1, 1, act=False)

    def forward(self, x):
        return self.conv_lighting(x) + self.shortcut(x)


class DWConv(Conv):
    # Depth-wise convolution class
    def __init__(self, c1, c2, k=1, s=1, act=True):  # ch_in, ch_out, kernel, stride, padding, groups
        super().__init__(c1, c2, k, s, g=math.gcd(c1, c2), act=act)


class GSBottleneckC(GSBottleneck):
    # cheap GS Bottleneck https://github.com/AlanLi1997/slim-neck-by-gsconv
    def __init__(self, c1, c2, k=3, s=1):
        super().__init__(c1, c2, k, s)
        self.shortcut = DWConv(c1, c2, 3, 1, act=False)


class VoVGSCSP(nn.Module):
    # VoVGSCSP module with GSBottleneck
    def __init__(self, c1, c2, n=1, shortcut=True, g=1, e=0.5):
        super().__init__()
        c_ = int(c2 * e)  # hidden channels
        self.cv1 = Conv(c1, c_, 1, 1)
        self.cv2 = Conv(c1, c_, 1, 1)
        # self.gc1 = GSConv(c_, c_, 1, 1)
        # self.gc2 = GSConv(c_, c_, 1, 1)
        self.gsb = GSBottleneck(c_, c_, 1, 1)
        self.res = Conv(c_, c_, 3, 1, act=False)
        self.cv3 = Conv(2*c_, c2, 1)  #

    def forward(self, x):

        x1 = self.gsb(self.cv1(x))
        y = self.cv2(x)
        return self.cv3(torch.cat((y, x1), dim=1))
 slim-neck

此外,还研究了增强 CNN 学习能力的通用方法,例如 DensNet 、VoVNet 和 CSPNet ,然后根据这些方法的理论设计 slim-neck 的结构。我们设计了细长的颈部,以降低检测器的计算复杂性和推理时间,但保持精度。 GSConv完成了降低计算复杂度的任务,而减少推理时间并保持精度的任务需要新的模型。 

GSConv的计算成本约为SC的50%(0.5+0.5C1,C1值越大,比例越接近50%),但其对模型学习能力的贡献与后者相当。基于GSConv,我们在GSConv的基础上继续引入GS瓶颈,下图(a)展示了GS瓶颈模块的结构。然后,我们使用一次性聚合方法设计跨阶段部分网络(GSCSP)模块VoV-GSCSP。图(b)(c)和(d)分别显示了我们为VoV-GSCSP提供的三种设计方案,其中(b)简单直接且推理速度更快,(c)和(d)具有功能的重用率更高。事实上,结构越简单的模块由于硬件友好而更容易被使用。下表也详细报告了VoV-GSCSP1、2、3三种结构的消融研究结果,事实上,VoVGSCSP1表现出更高的性价比。最后,我们需要灵活地使用 GSConv、GS 瓶颈和 VoV-GSCSP 这四个模块。

(a) GS瓶颈模块和(b)、(c)、(d) VoV-GSCSP1、2、3模块的结构

细颈 yolov5n 的三种不同 VoV-GSCSP 模块的比较
  slim-neck代码实现
class VoVGSCSPC(VoVGSCSP):
    # cheap VoVGSCSP module with GSBottleneck
    def __init__(self, c1, c2, n=1, shortcut=True, g=1, e=0.5):
        super().__init__(c1, c2, e)
        c_ = int(c2 * e)  # hidden channels
        self.gsb = GSBottleneckC(c_, c_, 3, 1)

代码都添加在common.py中 

yaml文件
# YOLOv5 🚀 by Ultralytics, GPL-3.0 license
# Slim-neck by GSConv: A better design paradigm of detector architectures for autonomous vehicle
# Parameters
nc: 80  # number of classes
depth_multiple: 0.33  # model depth multiple
width_multiple: 0.25  # 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, GSConv, [512, 1, 1]],
   [-1, 1, nn.Upsample, [None, 2, 'nearest']],
   [[-1, 6], 1, Concat, [1]],  # cat backbone P4
   [-1, 3, VoVGSCSP, [512, False]],  # 13

   [-1, 1, GSConv, [256, 1, 1]],
   [-1, 1, nn.Upsample, [None, 2, 'nearest']],
   [[-1, 4], 1, Concat, [1]],  # cat backbone P3
   [-1, 3, VoVGSCSP, [256, False]],  # 17 (P3/8-small)

   [-1, 1, GSConv, [256, 3, 2]],
   [[-1, 14], 1, Concat, [1]],  # cat head P4
   [-1, 3, VoVGSCSP, [512, False]],  # 20 (P4/16-medium)

   [-1, 1, GSConv, [512, 3, 2]],
   [[-1, 10], 1, Concat, [1]],  # cat head P5
   [-1, 3, VoVGSCSP, [1024, False]],  # 23 (P5/32-large)

   [[17, 20, 23], 1, Detect, [nc, anchors]],  # Detect(P3, P4, P5)
  ]
完整代码分享

本代码结合了YOLOv7的官方仓库进行改进,实现了YOLOv7 + GSconv

完整代码链接如下:

链接: https://pan.baidu.com/s/1zQgPu1lxZ4Sm3HYiCW3awg?pwd=v4m4 提取码: v4m4 

如果执行代码出现如下面的样例则代表替换卷积模块成功。

改进后的样例,部分截图

总结

本实验引入了一种新的轻量级卷积方法 GSConv,使深度可分离卷积达到接近普通卷积的效果并且更加高效。设计了一次性聚合模块 VoV-GSCSP 来代替普通的瓶颈模块以加速推理。此外,我们还提供轻量化的细颈设计范例。在我们的实验中,与其他轻量级卷积方法相比,GSConv 显示出更好的性能。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1530980.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

51-31 CVPR’24 | VastGaussian,3D高斯大型场景重建

2024 年 2 月,清华大学、华为和中科院联合发布的 VastGaussian 模型,实现了基于 3D Gaussian Splatting 进行大型场景高保真重建和实时渲染。 Abstract 现有基于NeRF大型场景重建方法,往往在视觉质量和渲染速度方面存在局限性。虽然最近 3D…

Git小乌龟安装及使用教程

一、Win7安装git 软件下载地址:git for windows 安装过程直接默认下一步,直到安装结束。 安装结束后重启一下。 安装完成后,在文件夹空白处右键出现以下几个标识,说明安装成功。 二、安装tortoise git(乌龟git&…

flutter 局部view更新,dialog更新进度,dialog更新

局部更新有好几种方法,本次使用的是 StatefulBuilder 定义 customState去更新对话框内容 import package:flutter/cupertino.dart; import package:flutter/material.dart;class ProgressDialog {final BuildContext context;BuildContext? dialogContext;double _…

帮助读者掌握C语言编程基础知识的书籍

帮助读者掌握C语言编程的基础知识,了解如何将人工智能技术应用于自己的编程项目。 人工智能编程(赋能C语言) 作者: 黄箐、廖云燕、曾锦山、邢振昌 ISBN号: 9787302648796 出版日期: 2023-11-01 本书以C…

【linux】环境变量(进程二)

这里写目录标题 命令行参数:环境变量: 命令行参数: 不谈命令行参数就谈环境变量就是耍流氓。 相信我们在C语言阶段都在main函数里见过参数。 例如int main(int argc, char* argv[]) 这是什么东西呢? 话不多说我们直接打印一下看…

Vue2(八):脚手架结构、render函数、ref属性、props配置项、mixin(混入)、插件、scoped样式

一、脚手架结构分析 crlc终止刚刚搭建的vue。 ├── node_modules ├── public │ ├── favicon.ico: 页签图标 │ └── index.html: 主页面 ├── src │ ├── assets: 存放静态资源 │ │ └── logo.png │ │── component: 存放组件 │ │ …

利用WebGL绘制简单几何

利用WebGL绘制最简单的几何图形 一、WebGL简介 WebGL是一种用于在网页上渲染交互式3D和2D图形的JavaScript API。它基于OpenGL ES 2.0,提供了一种在浏览器中使用硬件加速图形的方式。 二、图形系统绘图流程 图形系统的通用绘图流程会包括六个部分: …

python_django网红基地孵化园场地管理系统flask

作为一个管理孵化园的网络系统,数据流量是非常大的,所以系统的设计必须满足使用方便,操作灵活的要求。所以在设计孵化园管理系统管理系统应达到以下目标: (1)界面要美观友好,检索要快捷简易&…

python问题:vscode切换环境,pip安装库网络错误,不使用anaconda安装库

python问题:vscode切换环境,pip安装库网络错误 vscode切换环境pip安装库网络错误 不使用anaconda安装库 记录一下遇见的python问题。 vscode切换环境 在vscode上面的搜索框输入 > select interpreter然后选择需要的环境。 pip安装库网络错误 用…

数据丢失怎么办?不可不知道的3个恢复方法分享!

“作为一名电脑小白,刚买了电脑后我就把所有学习资料都保存在电脑上了,刚刚发现有部分比较重要的数据找不到了,我应该怎么操作才能恢复这些文件呢?” 数据丢失,对于任何个人或企业来说,都是一件令人头疼的事…

Python学习从0到1 day17 Python异常、模块、包

不走心的努力,都是在敷衍自己 ——24.3.19 万字长文,讲解异常、模块、包,看这一篇就足够啦 什么是异常? 当检测到一个错误时,python解释器就无法继续执行了,反而出现了一些错误的提示,这就是所谓的异常&am…

「滚雪球学Java」:安全(章节汇总)

🏆本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,助你一臂之力,带你早日登顶🚀,欢迎大家关注&&收藏!持续更新中,up!up!up!&#xf…

代码随想录day26(1)二叉树:二叉搜索树的最小绝对差(leetcode530)

题目要求:给你一棵所有节点为非负值的二叉搜索树,请你计算树中任意两节点的差的绝对值的最小值。 思路:最简单的想法就是新建数组,通过中序遍历将节点值全都存入数组中(有序),然后计算相邻两节…

【堡垒机】企业购买堡垒机的七大需求你知道吗?

目前想了解堡垒机的企业越来越多了,采购堡垒机的企业也越来越多了。那企业购买堡垒机的七大需求你知道吗?今天我们小编就跟大家一起来探讨一下,仅供参考哦! 企业购买堡垒机的七大需求 需求1、简化运维流程,提高运维工…

【Docker】-- 如何安装docker

一、安装docker 首先要安装一个yum工具 yum install -y yum-utils 安装成功后,执行命令,配置Docker的yum源: yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo 最后,执行命令&#x…

MySQL中replace into详解、批量更新、不存在插入存在则更新、replace into的坑

文章目录 一、replace into原理二、replace into的三种形式三、replace into 使用案例3.1、replace into values3.1.1、只有主键且主键冲突3.1.2、有主键有唯一索引且主键冲突3.1.3、有主键有唯一索引且唯一索引冲突(有坑)3.1.4、有主键有唯一索引且与一条主键冲突与另一条唯一…

centos7磁盘管理,lvm挂载、扩容

一、centos7 磁盘挂载 默认盘符格式 centos7 默认文件格式xfscentos6 默认文件格式ext4centos5 默认文件格式ext3 1、/dev/vdb和/dev/mapper/lvm-data对比 1)/dev/vdb /dev/vdb通常表示一个裸的块存储设备,比如一个硬盘或者虚拟机中的一个虚拟硬盘。…

c语言综合练习题

1.编写程序实现键盘输入一个学生的学分绩点 score&#xff08;合法的范围为:1.0—5.0&#xff09;&#xff0c;根据学生的学分绩点判定该学 生的奖学金的等级&#xff0c;判定规则如下表所示。 #include <stdio.h>int main() {float score;printf("请输入学生的学分…

在Arm 虚拟硬件(AVH)部署深度学习OCR算法

AI算法的嵌入式部署 AI算法在独立的设备上运行其实就是行业内的嵌入式AI的概念, 大致过程如下: 开发AI模型, 2.对数据集进行处理, 3.训练AI模型并验证效果, 4.转成ONNX格式(ONNX:万金油中间格式,给模型优化和部署带来了更多可能性)或者借助libtorch或者TensorFlow来部署C++版…

FreeRTOS时间片调度

1. 时间片调度简介 同等优先级任务轮流地享有相同的 CPU 时间(可设置)&#xff0c; 叫时间片。在FreeRTOS中&#xff0c;一个时间片就等于SysTick 中断周期。 像我们的源码&#xff0c;滴答定时器是 1ms 中断一次&#xff0c;那么一个时间片的时间就是 1ms。可设置&#xff1a…