YOLOv5:修改backbone为MobileOne

YOLOv5:修改backbone为MobileOne

  • 前言
  • 前提条件
  • 相关介绍
  • MobileOne
    • YOLOv5修改backbone为MobileOne
      • 修改common.py
      • 修改yolo.py
      • 修改yolov5.yaml配置
  • 参考

在这里插入图片描述

前言

  • 记录在YOLOv5修改backbone操作,方便自己查阅。
  • 由于本人水平有限,难免出现错漏,敬请批评改正。
  • 更多精彩内容,可点击进入YOLO系列专栏、自然语言处理
    专栏或我的个人主页查看
  • 基于DETR的人脸伪装检测
  • YOLOv7训练自己的数据集(口罩检测)
  • YOLOv8训练自己的数据集(足球检测)
  • YOLOv5:TensorRT加速YOLOv5模型推理
  • YOLOv5:IoU、GIoU、DIoU、CIoU、EIoU
  • 玩转Jetson Nano(五):TensorRT加速YOLOv5目标检测
  • YOLOv5:添加SE、CBAM、CoordAtt、ECA注意力机制
  • YOLOv5:yolov5s.yaml配置文件解读、增加小目标检测层
  • Python将COCO格式实例分割数据集转换为YOLO格式实例分割数据集
  • YOLOv5:使用7.0版本训练自己的实例分割模型(车辆、行人、路标、车道线等实例分割)
  • 使用Kaggle GPU资源免费体验Stable Diffusion开源项目

前提条件

  • 熟悉Python

相关介绍

  • Python是一种跨平台的计算机程序设计语言。是一个高层次的结合了解释性、编译性、互动性和面向对象的脚本语言。最初被设计用于编写自动化脚本(shell),随着版本的不断更新和语言新功能的添加,越多被用于独立的、大型项目的开发。
  • PyTorch 是一个深度学习框架,封装好了很多网络和深度学习相关的工具方便我们调用,而不用我们一个个去单独写了。它分为 CPU 和 GPU 版本,其他框架还有 TensorFlow、Caffe 等。PyTorch 是由 Facebook 人工智能研究院(FAIR)基于 Torch 推出的,它是一个基于 Python 的可续计算包,提供两个高级功能:1、具有强大的 GPU 加速的张量计算(如 NumPy);2、构建深度神经网络时的自动微分机制。
  • YOLOv5是一种单阶段目标检测算法,该算法在YOLOv4的基础上添加了一些新的改进思路,使其速度与精度都得到了极大的性能提升。它是一个在COCO数据集上预训练的物体检测架构和模型系列,代表了Ultralytics对未来视觉AI方法的开源研究,其中包含了经过数千小时的研究和开发而形成的经验教训和最佳实践。

MobileOne

  • MobileOne是一种神经网络骨干,专为移动设备设计,可在iPhone12上实现1毫秒以下的推理时间,并在ImageNet上实现75.9%的top-1准确率。它针对延迟进行了优化,这是移动设备的关键指标,并在高效架构中提供了最先进的性能,同时在移动设备上快得多。论文作者确定并分析了最近高效神经网络中的架构和优化瓶颈,并提供了缓解这些瓶颈的方法。论文还表明,当在移动设备上部署时,他们的模型可以推广到多个任务 - 图像分类、目标检测和语义分割,并且在延迟和准确性方面与现有高效架构相比有显着的改进。
  • MobileOne最大的不同点在于:
    • 使用了过参数化
    • 使用了与MobileNet类似的深度可分离卷积结构
  • 过参数化是指模型的可调权重数过多,导致模型过于复杂,完美地拟合训练数据,但对测试数据的预测效果不佳。
  • 重参数化是一种将神经网络的结构转换为更简单的结构,以减少计算复杂度和存储复杂度的方法。具体而言,重参数化方法使用数学变换将一个复杂的神经网络结构转化为一个更简单的结构,在保持一定精度的情况下增加模型推理时的速度。这些方法在神经网络压缩中得到了广泛应用。
  • 重参数化常用方法如下:
    • 卷积层与BN层的合并
    • 多分支相加
    • 1×1卷积与K×K卷积的重参数化
    • 通道拼接
    • AveragePooling
    • 多尺度卷积
  • 论文地址:https://arxiv.org/abs/2206.04040
  • 官方源代码地址:https://github.com/apple/ml-mobileone
  • 有兴趣可查阅论文和官方源代码地址。

在这里插入图片描述

YOLOv5修改backbone为MobileOne

修改common.py

将以下代码,添加进common.py。

############## MobileOne ##############
def conv_bn(in_channels, out_channels, kernel_size, stride, padding, groups=1):
    result = nn.Sequential()
    result.add_module('conv', nn.Conv2d(in_channels=in_channels, out_channels=out_channels,
                                        kernel_size=kernel_size, stride=stride, padding=padding, groups=groups,
                                        bias=False))
    result.add_module('bn', nn.BatchNorm2d(num_features=out_channels))
    return result


class DepthWiseConv(nn.Module):
    def __init__(self, inc, kernel_size, stride=1):
        super().__init__()
        padding = 1
        if kernel_size == 1:
            padding = 0
        # self.conv = nn.Sequential(
        #     nn.Conv2d(inc, inc, kernel_size, stride, padding, groups=inc, bias=False,),
        #     nn.BatchNorm2d(inc),
        # )
        self.conv = conv_bn(inc, inc, kernel_size, stride, padding, inc)

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


class PointWiseConv(nn.Module):
    def __init__(self, inc, outc):
        super().__init__()
        # self.conv = nn.Sequential(
        #     nn.Conv2d(inc, outc, 1, 1, 0, bias=False),
        #     nn.BatchNorm2d(outc),
        # )
        self.conv = conv_bn(inc, outc, 1, 1, 0)

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


class MobileOneBlock(nn.Module):

    def __init__(self, in_channels, out_channels, k,
                 stride=1, dilation=1, padding_mode='zeros', deploy=False, use_se=False):
        super(MobileOneBlock, self).__init__()
        self.deploy = deploy
        self.in_channels = in_channels
        self.out_channels = out_channels
        self.deploy = deploy
        kernel_size = 3
        padding = 1
        assert kernel_size == 3
        assert padding == 1
        self.k = k
        padding_11 = padding - kernel_size // 2

        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.dw_reparam = nn.Conv2d(in_channels=in_channels, out_channels=in_channels, kernel_size=kernel_size,
                                        stride=stride,
                                        padding=padding, dilation=dilation, groups=in_channels, bias=True,
                                        padding_mode=padding_mode)
            self.pw_reparam = nn.Conv2d(in_channels=in_channels, out_channels=out_channels, kernel_size=1, stride=1,
                                        bias=True)

        else:
            self.dw_bn_layer = nn.BatchNorm2d(in_channels) if out_channels == in_channels and stride == 1 else None
            for k_idx in range(k):
                setattr(self, f'dw_3x3_{k_idx}',
                        DepthWiseConv(in_channels, 3, stride=stride)
                        )
            self.dw_1x1 = DepthWiseConv(in_channels, 1, stride=stride)

            self.pw_bn_layer = nn.BatchNorm2d(in_channels) if out_channels == in_channels and stride == 1 else None
            for k_idx in range(k):
                setattr(self, f'pw_1x1_{k_idx}',
                        PointWiseConv(in_channels, out_channels)
                        )

    def forward(self, inputs):
        if self.deploy:
            x = self.dw_reparam(inputs)
            x = self.nonlinearity(x)
            x = self.pw_reparam(x)
            x = self.nonlinearity(x)
            return x

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

        x_conv_3x3 = []
        for k_idx in range(self.k):
            x = getattr(self, f'dw_3x3_{k_idx}')(inputs)
            x_conv_3x3.append(x)
        x_conv_1x1 = self.dw_1x1(inputs)
        x = id_out + x_conv_1x1 + sum(x_conv_3x3)
        x = self.nonlinearity(self.se(x))

        # 1x1 conv
        if self.pw_bn_layer is None:
            id_out = 0
        else:
            id_out = self.pw_bn_layer(x)
        x_conv_1x1 = []
        for k_idx in range(self.k):
            x_conv_1x1.append(getattr(self, f'pw_1x1_{k_idx}')(x))
        x = id_out + sum(x_conv_1x1)
        x = self.nonlinearity(x)
        return x


class MobileOne(nn.Module):
    # MobileOne
    def __init__(self, in_channels, out_channels, n, k,
                 stride=1, dilation=1, padding_mode='zeros', deploy=False, use_se=False):
        super().__init__()
        self.m = nn.Sequential(*[MobileOneBlock(in_channels, out_channels, k, stride, deploy) for _ in range(n)])

    def forward(self, x):
        x = self.m(x)
        return x
############## mobileone ##############

修改yolo.py

        elif m is MobileOne:
            c1, c2 = ch[f], args[0]
            c2 = make_divisible(c2 * gw, 8)
            args = [c1, c2, n, *args[1:]]

在这里插入图片描述

修改yolov5.yaml配置

# YOLOv5 🚀 by Ultralytics, GPL-3.0 license

# Parameters
nc: 80  # number of classes
depth_multiple: 0.33  # model depth multiple
width_multiple: 0.50  # 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, MobileOne, [1024, 5]],  # 9
  ]

# YOLOv5 v6.0 head
head:
  [[-1, 1, Conv, [512, 1, 1]],
   [-1, 1, nn.Upsample, [None, 2, 'nearest']],
   [[-1, 6], 1, Concat, [1]],  # cat backbone P4
   [-1, 3, C3, [512, False]],  # 13

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

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

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

   [[17, 20, 23], 1, Detect, [nc, anchors]],  # Detect(P3, P4, P5)
  ]

在这里插入图片描述

参考

[1] Pavan Kumar Anasosalu Vasu, James Gabriel, Jeff Zhu, Oncel Tuzel, Anurag Ranjan. MobileOne: An Improved One millisecond Mobile Backbone. 2023
[2] https://github.com/apple/ml-mobileone
[3] https://github.com/ultralytics/yolov5.git
[4] https://arxiv.org/abs/2206.04040
[5] https://zhuanlan.zhihu.com/p/560894077
[6] https://zhuanlan.zhihu.com/p/550626959

  • 由于本人水平有限,难免出现错漏,敬请批评改正。
  • 更多精彩内容,可点击进入YOLO系列专栏、自然语言处理
    专栏或我的个人主页查看
  • 基于DETR的人脸伪装检测
  • YOLOv7训练自己的数据集(口罩检测)
  • YOLOv8训练自己的数据集(足球检测)
  • YOLOv5:TensorRT加速YOLOv5模型推理
  • YOLOv5:IoU、GIoU、DIoU、CIoU、EIoU
  • 玩转Jetson Nano(五):TensorRT加速YOLOv5目标检测
  • YOLOv5:添加SE、CBAM、CoordAtt、ECA注意力机制
  • YOLOv5:yolov5s.yaml配置文件解读、增加小目标检测层
  • Python将COCO格式实例分割数据集转换为YOLO格式实例分割数据集
  • YOLOv5:使用7.0版本训练自己的实例分割模型(车辆、行人、路标、车道线等实例分割)
  • 使用Kaggle GPU资源免费体验Stable Diffusion开源项目

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Redis之持久化(RDB和AOF)

文章目录 前言一、RDB1.介绍2.redis.config有关配置3.触发4.恢复5.优缺点 二、AOF1.介绍2.redis.config配置3.启动4.恢复5.重写6.优缺点 总结 前言 Redis 是内存数据库,即数据存储在内存。 如果不将内存中的数据保存到磁盘,一旦服务器进程退出&#xff…

Spring Cloud之Docker的学习【详细】

目录 Docker 项目部署问题 总结 镜像与容器 Docker的安装 Docker基本操作 镜像相关命令 拉取镜像 镜像保存 删除镜像 镜像加载 容器相关命令 删除容器 数据卷 数据卷命令 数据挂载 自定义镜像 Dockerfile 案例 Docker-Compose Compose文件 Docker-Compos…

数据结构与算法C语言版学习笔记(1)-绪论

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 一、数据结构的研究内容二、基本概念与术语1.数据与数据元素2.数据结构逻辑结构的种类存储结构的种类 三、算法1.什么是算法?算法的描述2.一个算法要具备…

【VR开发】【Unity】【VRTK】1-无代码VRVR开发介绍

本篇开始精简讲解VRTK相关的知识。 VRTK是基于Unity的一套提供无代码VR开发的插件,这套插件开源,可商用,集合了目前可能的VR体验组件,可以让不会C#编程但想要开发VR体验的人在不写一行代码的前提下开发出心仪的VR作品。 这套组件问世后也很受欢迎,目前已经进化到了第四代…

Java 算法篇-深入了解二分查找法

🔥博客主页: 小扳_-CSDN博客 ❤感谢大家点赞👍收藏⭐评论✍ 目录 1.0 二分查找法的说明 2.0 二分查找实现的多种版本 2.1 二分查找的基础版本 2.2 二分查找的改动版本 2.3 二分查找的平衡版本 2.4 二分查找的官方版本 3.0 二分查找的应用 1…

【Linux系统学习】系统编程开发工具编译器gcc/g++使用

个人主页点击直达:小白不是程序媛 Linux专栏:Linux系统学习 目录 前言 Linux系统下安装gcc和g gcc和g的不同 gcc/g的使用 gcc/g选项 预处理 头文件的展开 宏替换 注释的删除 条件的编译 编译 汇编 链接 系统库 库的分类 库的安装 库的…

[计算机提升] Windows系统软件:娱乐类

3.3 系统软件:娱乐类 3.3.1 Windows Media Player:dvdplay Windows Media Player是Windows操作系统自带的多媒体播放软件,用于播放和管理电脑中的音频和视频文件。它提供了以下功能: 播放音频和视频文件:Windows Med…

基于ThinkPHP+MySQL实现的通用的PHP网站后台管理系统

caozha-admin 后台管理框架 1.8.3 caozha-admin是一个通用的PHP网站后台管理框架,基于开源的ThinkPHP开发,特点:易上手,零门槛,界面清爽极简,极便于二次开发。 基础功能 1、系统设置 2、管理员管理 3、…

搭建ELK+Filebead+zookeeper+kafka实验

一、ELKFilebeatkafkazookeeper架构 架构图分别演示 第一层:数据采集层 数据采集层位于最左边的业务服务集群上,在每个业务服务器上面安装了filebead做日志收集,然后把采集到的原始日志发送到kafkazookeeper集群上。 第二层:消…

vue3中,使用html2canvas截图包含视频、图片、文字的区域

需求:将页面中指定区域进行截图,区域中包含了图片、文字、视频。 第一步,先安装 npm install html2canvas第二步,在页面引入: import html2canvas from html2canvas;第三步,页面使用: 1&…

SpringCloudGateway--过滤器(自定义filter)

目录 一、概览 二、通过GatewayFilter实现 三、继承AbstractGatewayFilterFactory 一、概览 当使用Spring Cloud Gateway构建API网关时,可以利用Spring Cloud Gateway提供的内置过滤器(filter)来实现对请求的处理和响应的处理。过滤器可以…

TiDB 企业版全新升级,平凯数据库核心特性全解读

作为 TiDB 企业版的全新升级,平凯数据库一经推出便广受媒体及用户关注。 近日,平凯星辰首席科学家丁岩在“平凯数据库全解读”活动中,首次详细介绍了平凯数据库的核心能力。 本文为丁岩演讲实录全文,为方便阅读,已做部…

物联网AI MicroPython传感器学习 之 QMC5883指南针罗盘传感器

学物联网,来万物简单IoT物联网!! 一、产品简介 QMC5883是一款表面贴装的集成了信号处理电路的三轴磁性传感器,应用场景主要包括罗盘、导航、无人机、机器人和手持设备等一些高精度的场合。 引脚定义 VCC:3V3&#…

自定义的卷积神经网络模型CNN,对图片进行分类并使用图片进行测试模型-适合入门,从模型到训练再到测试,开源项目

自定义的卷积神经网络模型CNN,对图片进行分类并使用图片进行测试模型-适合入门,从模型到训练再到测试:开源项目 开源项目完整代码及基础教程: https://mbd.pub/o/bread/ZZWclp5x CNN模型: 1.导入必要的库和模块&…

数据结构与算法:使用数组模拟环形队列Java版

文章目录 如何使用数组模拟队列环形队列逻辑分析自己写的听课笔记实现代码部分方法说明 如何使用数组模拟队列 不知道如何使用数组模拟队列的可以看上一篇文章 使用数组模拟队列点击跳转 环形队列逻辑分析 自己写的听课笔记 实现代码 package com.haimeng.queue;import java…

uniapp-自定义表格,右边操作栏固定

uniapp-自定义表格,右边操作栏固定 在网上找了一些,没找到特别合适的,收集了一下其他人的思路,基本都是让左边可以滚动,右边定位,自己也尝试写了一下,有点样式上的小bug,还在尝试修…

多线程锁的升级原理是什么

在 Java 中,锁共有 4 种状态,级别从低到高依次为:无状态锁,偏向锁,轻量级锁和重量级锁状态,这几个状态会随着竞争情况逐渐升级。锁可以升级但不能降级。 多线程锁锁升级过程 如下图所示 多线程锁的升级过程…

在NISQ小型计算机上执行大型并行量子计算的可能性

简介 Steve White提出了密度矩阵重整化群(DMRG)的基本思想,即纠缠是一种有价值的资源,可以用来精确或近似地描述大量子系统。后来,这一思想被理解为优化矩阵积状态(MPS)的算法,支持…

Android开发笔记(三)—Activity篇

活动组件Activity 启动和结束生命周期启动模式信息传递Intent显式Intent隐式Intent 向下一个Activity发送数据向上一个Activity返回数据 附加信息利用资源文件配置字符串利用元数据传递配置信息给应用页面注册快捷方式 启动和结束 (1)从当前页面跳到新页…

[idea]关于idea开发乱码的配置

在JAVA开发中,一般统一设置为UTF-8的编码,包括但不限于开发工具、日志架构、虚拟机、文件编码等。常见配置如下: 1、IDEA工具 在idea64.exe.vmoptions、idea.exe.vmoptions中添加: -Dfile.encodingUTF-8 2、JAVA 运行在window…