YOLOv5、v7改进之三十八:引入RepVGG模型结构

news2025/7/5 15:25:26

前 言:作为当前先进的深度学习目标检测算法YOLOv7,已经集合了大量的trick,但是还是有提高和改进的空间,针对具体应用场景下的检测难点,可以不同的改进方法。此后的系列文章,将重点对YOLOv7的如何改进进行详细的介绍,目的是为了给那些搞科研的同学需要创新点或者搞工程项目的朋友需要达到更好的效果提供自己的微薄帮助和参考。由于出到YOLOv7,YOLOv5算法2020年至今已经涌现出大量改进论文,这个不论对于搞科研的同学或者已经工作的朋友来说,研究的价值和新颖度都不太够了,为与时俱进,以后改进算法以YOLOv7为基础,此前YOLOv5改进方法在YOLOv7同样适用,所以继续YOLOv5系列改进的序号。另外改进方法在YOLOv5等其他算法同样可以适用进行改进。希望能够对大家有帮助。

具体改进办法请关注后私信留言!关注即可免费领取深度学习算法资料!

解决问题:之前改进增加了很多注意力机制的方法,包括比较常规的SE、CBAM等,本文加入简单但功能强大的轻量级卷积神经网络结构,权衡网络精度和速度,实现双赢的检测效果。

基本原理:

提出了一种简单但功能强大的卷积神经网络结构,它具有一个类似VGG的推理时间体,由3×3卷积和ReLU组成,而训练时间模型具有多分支拓扑。这种训练时间和推理时间架构的解耦是通过结构重新参数化技术实现的,因此该模型被命名为RepVGG。在ImageNet上,据我们所知,RepVGG达到了80%以上的前1精度,这是普通模型的第一次。在NVIDIA 1080Ti GPU上,RepVGG型号的运行速度比ResNet-50快83%,比ResNet-101快101%,具有更高的精度,与EfficientNet和RegNet等最先进的型号相比,显示出令人满意的精度-速度权衡。

    与最先进的基线相比,考虑到其简单性,RepVGG也表现出良好的性能:RepVGG-A2比EfficientNet-B0好1.37%/59%,RepVVGG-B1比RegNetX-3.2GF好0.39%,运行速度稍快。值得注意的是,RepVGG模型在200个时代达到了80%以上的准确率(表5),据我们所知,这是普通模型第一次赶上最先进的水平。与RegNetX-12GF相比,RepVGG-B3的运行速度快31%,考虑到RepVGG不需要太多,这一点令人印象深刻。我们使用这样的批处理大小,因为它足够大,可以实现每个测试模型100%的GPU利用率,以模拟追求最大QPS(每秒查询数)的实际应用场景,而我们的GPU内存不足,无法满足批量大小为256的EfficientNet-B3。表:在ImageNet上训练的120个时期的简单数据增强结果。速度在1080Ti上进行测试,批量大小为128,全精度(fp32),以示例/秒为单位进行测量。我们计算第节中所述的理论FLOP和Wino MUL。

添加方法:

第一步:确定添加的位置,作为即插即用的注意力模块,可以添加到YOLOv7网络中的任何地方。

第二步:common.py构建模块。部分代码如下,关注文章末尾,私信后领取。

class RepVGGBlock(nn.Module):
    def __init__(self, in_channels, out_channels, kernel_size=3,
                 stride=1, padding=1, dilation=1, groups=1, padding_mode='zeros', deploy=False, use_se=False):
        super(RepVGGBlock, self).__init__()
        self.deploy = deploy
        self.groups = groups
        self.in_channels = in_channels
        padding_11 = padding - kernel_size // 2
        self.nonlinearity = nn.SiLU()
        # self.nonlinearity = nn.ReLU()
        if use_se:
            self.se = SEBlock(out_channels, internal_neurons=out_channels // 16)
        else:
            self.se = nn.Identity()
        if deploy:
            self.rbr_reparam = nn.Conv2d(in_channels=in_channels, out_channels=out_channels, kernel_size=kernel_size,
                                         stride=stride,
                                         padding=padding, dilation=dilation, groups=groups, bias=True,
                                         padding_mode=padding_mode)

        else:
            self.rbr_identity = nn.BatchNorm2d(
                num_features=in_channels) if out_channels == in_channels and stride == 1 else None
            self.rbr_dense = conv_bn(in_channels=in_channels, out_channels=out_channels, kernel_size=kernel_size,
                                     stride=stride, padding=padding, groups=groups)
            self.rbr_1x1 = conv_bn(in_channels=in_channels, out_channels=out_channels, kernel_size=1, stride=stride,
                                   padding=padding_11, groups=groups)
            # print('RepVGG Block, identity = ', self.rbr_identity)
def switch_to_deploy(self):
        if hasattr(self, 'rbr_1x1'):
            kernel, bias = self.get_equivalent_kernel_bias()
            self.rbr_reparam = nn.Conv2d(in_channels=self.rbr_dense.conv.in_channels, out_channels=self.rbr_dense.conv.out_channels,
                                    kernel_size=self.rbr_dense.conv.kernel_size, stride=self.rbr_dense.conv.stride,
                                    padding=self.rbr_dense.conv.padding, dilation=self.rbr_dense.conv.dilation, groups=self.rbr_dense.conv.groups, bias=True)
            self.rbr_reparam.weight.data = kernel
            self.rbr_reparam.bias.data = bias
            for para in self.parameters():
                para.detach_()
            self.rbr_dense = self.rbr_reparam
            # self.__delattr__('rbr_dense')
            self.__delattr__('rbr_1x1')
            if hasattr(self, 'rbr_identity'):
                self.__delattr__('rbr_identity')
            if hasattr(self, 'id_tensor'):
                self.__delattr__('id_tensor')
            self.deploy = True

    def get_equivalent_kernel_bias(self):
        kernel3x3, bias3x3 = self._fuse_bn_tensor(self.rbr_dense)
        return kernel3x3 + self._pad_1x1_to_3x3_tensor(kernel1x1) + kernelid, bias3x3 + bias1x1 + biasid

    def _pad_1x1_to_3x3_tensor(self, kernel1x1):
        if kernel1x1 is None:
            return 0
        else:
            return torch.nn.functional.pad(kernel1x1, [1, 1, 1, 1])

    def _fuse_bn_tensor(self, branch):
        if branch is None:
            return 0, 0
        if isinstance(branch, nn.Sequential):
            kernel = branch.conv.weight
            running_mean = branch.bn.running_mean
            running_var = branch.bn.running_var
            gamma = branch.bn.weight
            beta = branch.bn.bias
            eps = branch.bn.eps
        else:
            assert isinstance(branch, nn.BatchNorm2d)
            if not hasattr(self, 'id_tensor'):
                input_dim = self.in_channels // self.groups
                kernel_value = np.zeros((self.in_channels, input_dim, 3, 3), dtype=np.float32)
                for i in range(self.in_channels):
                    kernel_value[i, i % input_dim, 1, 1] = 1
                self.id_tensor = torch.from_numpy(kernel_value).to(branch.weight.device)
            kernel = self.id_tensor
            running_mean = branch.running_mean
            running_var = branch.running_var
            gamma = branch.weight
            beta = branch.bias
            eps = branch.eps
        std = (running_var + eps).sqrt()
        t = (gamma / std).reshape(-1, 1, 1, 1)
        return kernel * t, beta - running_mean * gamma / std

    def forward(self, inputs):
        if self.deploy:
            return self.nonlinearity(self.rbr_dense(inputs))
        if hasattr(self, 'rbr_reparam'):
            return self.nonlinearity(self.se(self.rbr_reparam(inputs)))

        if self.rbr_identity is None:
            id_out = 0
        else:
            id_out = self.rbr_identity(inputs)

        return self.nonlinearity(self.se(self.rbr_dense(inputs) + self.rbr_1x1(inputs) + id_out))

第三步:yolo.py中注册RepVGGBlock模块

elif m is RepVGGBlock:
            c1, c2 = ch[f], args[0]
            if c2 != no:  # if not output
                c2 = make_divisible(c2 * gw, 8)
            args = [c1, c2, *args[1:]]
if type(m) is RepVGGBlock:
      m.switch_to_deploy()

第四步:修改yaml文件,本文以修改backbone为例,将原C3模块后加入该模块。

backbone:
  # [from, number, module, args]
  [[-1, 1, Conv, [32, 3, 1]],  # 0
   [-1, 1, Conv, [64, 3, 2]],  # 1-P1/2
   [-1, 1, Conv, [64, 3, 1]],
   [-1, 1, Conv, [128, 3, 2]],  # 3-P2/4 
   [-1, 1, RepVGGBlock, [128, 3, 2]], # 5-P4/16
   [-1, 1, Conv, [256, 3, 2]], 
   [-1, 1, MP, []],
   [-1, 1, Conv, [128, 1, 1]],
   [-3, 1, Conv, [128, 1, 1]],
   [-1, 1, Conv, [128, 3, 2]],

第五步:将train.py中改为本文的yaml文件即可,开始训练。

结 果:本人在遥感数据集上进行实验,有涨点效果。需要请关注留言。

预告一下:下一篇内容将继续分享深度学习算法相关改进方法。有兴趣的朋友可以关注一下我,有问题可以留言或者私聊我哦

PS:该方法不仅仅是适用改进YOLOv5,也可以改进其他的YOLO网络以及目标检测网络,比如YOLOv7、v6、v4、v3,Faster rcnn ,ssd等。

最后,有需要的请以关注文末私信我吧。关注即可免费领取深度学习算法学习资料!

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

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

相关文章

基于javaweb的养老院管理系统(java+springboot+thymeleaf+html+js+mysql)

基于javaweb的养老院管理系统(javaspringbootthymeleafhtmljsmysql) 运行环境 Java≥8、MySQL≥5.7 开发工具 eclipse/idea/myeclipse/sts等均可配置运行 适用 课程设计,大作业,毕业设计,项目练习,学习演示等 功能说明 基于…

synchronized到底锁的是谁、何时生效

一、synchronized锁的几种形式 synchronized修饰普通方法synchronized修饰静态方法synchronized修饰代码块 1、synchronized修饰普通方法 简单示例 public class Test{private String age;private String name;public synchronized void print(String arg1, String arg2) {…

零代码,让业务人员实现应用创造自由

摘要:以汽车营销场景为例,从AppCube零代码和业务大屏入手,帮助开发者更好地理解AppCube低代码和零代码异同点,在实际使用时能更快选取更合适的工具能力,实现应用构建效率最大化。本文分享自华为云社区《DTT第8期直播回…

超级详细的Vue安装与配置教程

Vue web前端三大主流框架之一,是一套用于构建用户界面的渐进式框架,下面这篇文章主要给大家介绍了关于Vue安装与配置教程的相关资料,文中通过图文介绍的非常详细,需要的朋友可以参考下 − 目录 一、下载和安装Vue二、创建全局安装目录和缓存日志目录三、配置环境变量 1. 环境…

【k哥爬虫普法】简历大数据公司被查封,个人隐私是红线!

我国目前并未出台专门针对网络爬虫技术的法律规范,但在司法实践中,相关判决已屡见不鲜,K 哥特设了“K哥爬虫普法”专栏,本栏目通过对真实案例的分析,旨在提高广大爬虫工程师的法律意识,知晓如何合法合规利用…

mysql忘记密码怎么办(附免密登录和修改密码)

前言 博主个人社区:开发与算法学习社区 博主个人主页:Killing Vibe的博客 欢迎大家加入,一起交流学习~~ 一、打开MySQL(能打开请跳过此步) 第一种:安装完MySQL之后,MySQL提供大家的客户端程序 …

DASCTF X GFCTF 2022十月挑战赛-hade_waibo

这是一个非预期解&#xff0c;但是得到出题人的赞许&#xff0c;莫名开心&#xff0c;哈哈&#xff1a; cancan need处存在任意文件读取 <!DOCTYPE html> <html lang"en" class"no-js"> <head> <meta charset"UTF-8" />…

引爆记忆广告语盘点

在数字化、流量红利见顶、营销环境巨变的进程中&#xff0c;品牌传播的节奏从快到稳。品牌出圈更需要产品、渠道、内容、文化等方面的共振影响&#xff0c;其中广告语作为品牌定位和价值主张的核心载体&#xff0c;是连接消费者心智的重要品牌资产。 根据益普索Ipsos《引爆记忆…

uni-app、小程序项目分包经验之谈与天坑异常:RangeError: Maximum call stack size exceeded

小程序分包经验之谈与天坑异常&#xff1a;RangeError: Maximum call stack size exceeded小程序分包概述分包配置参数&#xff1a;subPackages分包预载配置参数&#xff1a;preloadRule如何使用实际小程序项目分包项目结构配置分包配置分包预载天坑异常场景分析猜想尝试解决解…

springboot配置多个数据源

一.多数据源的典型使用场景 在实际开发中,经常可能遇到在一个应用中可能要访问多个数据库多的情况,以下是两种典型场景 1.业务复杂 数据分布在不同的数据库中,数据库拆了,应用没拆.一个公司多个子项目,各用各的数据库,设计数据共享 2.读写分离 为了解决数据库的性能瓶颈(读…

C++内存管理和模板

目录 内存管理 new T[N] new和delete关键字的总结&#xff1a; 定位new表达式(placement-new)&#xff1a; 作用&#xff1a; 使用格式&#xff1a; 使用场景&#xff1a; 实例&#xff1a; 调用析构函数的两个方法&#xff1a; 池化技术&#xff1a; 面试题&#xff1…

Unity 分享 功能 用Unity Native Share Plugin 实现链接、图片、视频等文件的分享+ 安卓 Ios 都可以,代码图文详解

Unity 分享 功能 用Unity Native Share Plugin 实现链接、图片、视频等文件的分享 安卓 Ios 都可以&#xff0c;代码图文详解前言环境效果一、Unity Native Share Plugin导入1.下载2.导入二、案例1.分享文字1.脚本2.发包注意2.分享视频1.完善下刚才的脚本2.给复制按钮添加点击事…

【Linux】Linux环境搭建

​&#x1f320; 作者&#xff1a;阿亮joy. &#x1f386;专栏&#xff1a;《学会Linux》 &#x1f387; 座右铭&#xff1a;每个优秀的人都有一段沉默的时光&#xff0c;那段时光是付出了很多努力却得不到结果的日子&#xff0c;我们把它叫做扎根 目录&#x1f449;Linux的介…

【QT 自研上位机 与 STM32F103下位机联调>>>通信测试-基础样例-联合文章】

【QT 自研上位机 与 STM32F103下位机联调>>>通信测试-基础样例-联合文章】1、概述2、实验环境3、联合文章&#xff08;1&#xff09;对于上位机&#xff0c;可以参照如下例子&#xff08;2&#xff09;对于下位机&#xff0c;可以参照如下例子4、QT上位机部分第一步&a…

python中os库的使用

目录介绍1 listdir(path: str)2 path.isdir(path: str)3 path.isfile(path: str)4 path.join(path: str, file: str)5 path.getsize(path: str)介绍 本博客记录python中os库的一些函数使用。 1 listdir(path: str) listdir()函数输入一个目录&#xff0c;返回该目录下的所有…

web前端 html+css+javascript游戏网页设计实例 (网页制作课作业)

&#x1f389;精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业…

数字化浪潮下,低代码能否加速企业的数字化转型

随着加快建设数字中国的目标明确下来&#xff0c;市场上与数字化相关的企业都得到了极大鼓舞&#xff0c;这不仅意味着后续数字领域的加速发展&#xff0c;更是代表着数字化已经完全可以向各行各业拓展&#xff0c;大力推进数字化建设。数字中国也说明了数字化并不能只是限制在…

FastTunnel Win10内网穿透实现远程桌面

目录 一、需求 二、购买公网服务器 三、远程公网服务器 四、FastTunnel 的使用 1.下载 FastTunnel 2.启动服务器端 3.启动客户端 五、测试 六、安装服务 结束 一、需求 FastTunnel 简介 高性能跨平台内网穿透工具&#xff0c;使用它可以实现将内网服务暴露到公网供…

【数据结构与算法】时间复杂度和空间复杂度

✨ 个人主页&#xff1a;bit me ✨ 当前专栏&#xff1a;数据结构 &#x1f31f;每日一语&#xff1a;窗外有风景 笔下有前途 低头是题海 抬头是鹏程 时间复杂度和空间复杂度的认知&#x1f30e; 一. 如何衡量一个算法的好坏&#x1f319; 二. 算法效率&#x1fa90; 三. 时间…

Word处理控件Aspose.Words功能演示:在 Python 中将 TXT 文件转换为 PDF

各种人使用记事本以TXT格式记下重点或快速创建笔记。此外&#xff0c;TXT 文件用于在各种应用程序中存储纯文本。但是&#xff0c;由于记事本不提供高级功能&#xff0c;因此 TXT 文件通常会转换为PDF。为了以编程方式自动将 TXT 转换为 PDF&#xff0c;本文介绍了如何在 Pytho…