【目标检测实验系列】EMA高效注意力机制,融合多尺度特征,助力YOLOv5检测模型涨点(文内附源码)

news2024/11/15 11:45:54

1. 文章主要内容

       本篇博客主要涉及多尺度高效注意力机制,融合到YOLOv5s模型中,增加模型提取多尺度特征的能力,助力模型涨点。(通读本篇博客需要7分钟左右的时间)

2. 简要概括

       论文地址:EMA论文地址

       如下图所示。EMA注意力提取特征主要分三个特征分支,分别是X、Y和一个3 x 3 的卷积块。另外,原论文中提出了一种跨分支学习,将其中的三个分支融合在一起,丰富多尺度感受野的特征,最后调整维度输出。更详细的细节,请阅读原论文。
       亮点在于:比起CA注意力机制多了一个3x3的卷积分支,另外新增了跨分支的特征交互,丰富了提取模型的特征信息,有助于模型涨点。
       分析:建议将EMA放置于YOLOv5 BackBone部分,因为BackBone是提取特征的关键,另外数据集如果有大量多尺度的目标分布,EMA很有可能起到明显的作用。另外,在EMA基础上,可以做一些微弱的创新,比如新增一个5x5的卷积分支并加入到跨分支学习中等等,这里只是提供一个思路。

在这里插入图片描述

3. 详细代码改进流程

3.1新建一个EMA的文件,放置源代码

       特别注意:博主这里将EMA与YOLOv5中的C3模块结构融合在一起并命名为C3EMA。所以源代码中会含有C3EMA的代码,另外此代码提高了main函数的测试案例,启动测试控制台打印输入输出通道对得上就木有问题。源代码如下:

import torch
from torch import nn

class EMA(nn.Module):
    def __init__(self, channels, c2=None, factor=32):
        super(EMA, self).__init__()
        self.groups = factor
        assert channels // self.groups > 0
        self.softmax = nn.Softmax(-1)
        self.agp = nn.AdaptiveAvgPool2d((1, 1))
        self.pool_h = nn.AdaptiveAvgPool2d((None, 1))
        self.pool_w = nn.AdaptiveAvgPool2d((1, None))
        self.gn = nn.GroupNorm(channels // self.groups, channels // self.groups)
        self.conv1x1 = nn.Conv2d(channels // self.groups, channels // self.groups, kernel_size=1, stride=1, padding=0)
        self.conv3x3 = nn.Conv2d(channels // self.groups, channels // self.groups, kernel_size=3, stride=1, padding=1)

    def forward(self, x):
        b, c, h, w = x.size()
        group_x = x.reshape(b * self.groups, -1, h, w)  # b*g,c//g,h,w
        x_h = self.pool_h(group_x)
        x_w = self.pool_w(group_x).permute(0, 1, 3, 2)
        hw = self.conv1x1(torch.cat([x_h, x_w], dim=2))
        x_h, x_w = torch.split(hw, [h, w], dim=2)
        x1 = self.gn(group_x * x_h.sigmoid() * x_w.permute(0, 1, 3, 2).sigmoid())
        x2 = self.conv3x3(group_x)
        x11 = self.softmax(self.agp(x1).reshape(b * self.groups, -1, 1).permute(0, 2, 1))
        x12 = x2.reshape(b * self.groups, c // self.groups, -1)  # b*g, c//g, hw
        x21 = self.softmax(self.agp(x2).reshape(b * self.groups, -1, 1).permute(0, 2, 1))
        x22 = x1.reshape(b * self.groups, c // self.groups, -1)  # b*g, c//g, hw
        weights = (torch.matmul(x11, x12) + torch.matmul(x21, x22)).reshape(b * self.groups, 1, h, w)
        return (group_x * weights.sigmoid()).reshape(b, c, h, w)
        
class C3EMA(nn.Module):
    def __init__(self, c1, c2, n=1, shortcut=True, g=1,
                 e=0.5):  # ch_in, ch_out, number, shortcut, groups, expansion #iscyy

        super(C3EMA, self).__init__()
        c_ = int(c2 * e)  # hidden channels
        self.ema = EMA(c1)
        self.cv1 = Conv(c1, c_, 1, 1)
        self.cv2 = Conv(c1, c_, 1, 1)
        self.cv3 = Conv(2 * c_, c2, 1)  # act=FReLU(c2)
        # self.m = nn.Sequential(*[CB2d(c_) for _ in range(n)])
        self.m = nn.Sequential(*[Bottleneck(c_, c_, shortcut, g, e=1.0) for _ in range(n)])

    def forward(self, x):
        out = torch.cat((self.m(self.cv1(self.ema(x))), self.cv2(x)), dim=1)
        out = self.cv3(out)
        return out
if __name__ == '__main__':
    model = C3EMA(64,64)
    inputs = torch.randn((1, 64, 64, 64))
    print(model(inputs).size())

3.2新建一个yolov5-EMA.yaml文件

       注意到,这里博主直接使用C3EMA代替Backbone部分后面两个C3模块(事实上可以替换结构中的任意C3模块), 另外注意nc改为自己数据集的类别数

# YOLOv5 🚀 by Ultralytics, GPL-3.0 license

# Parameters
nc: 4  # 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  output_channel, kernel_size, stride, padding
   [-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, C3EMA, [512]],
   [-1, 1, Conv, [1024, 3, 2]],  # 7-P5/32
   [-1, 3, C3EMA, [1024]],
   [-1, 1, SPPF, [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)
  ]

3.3 将C3EMA引入到yolo.py文件中

       在下图的红色圈内位置处,引入C3EMA(一共是两处地方),并手动导入相应的包即可。
在这里插入图片描述

3.4 修改train.py启动文件

       修改配置文件为yolov5-EMA.yaml即可,如下图所示:
在这里插入图片描述

4. 总结

       本篇博客主要介绍了高效多尺度注意力机制EMA,融合多尺度特征信息,助力YOLOv5模型涨点。另外,在修改过程中,要是有任何问题,评论区交流;如果博客对您有帮助,请帮忙点个赞,收藏一下;后续会持续更新本人实验当中觉得有用的点子,如果很感兴趣的话,可以关注一下,谢谢大家啦!

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

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

相关文章

使用 VMware vCenter Server(vSphere Client)迁移 ESXi 虚拟机

我需要将虚拟机 k8s-dev-node4从 ESXi 主机 192.168.1.161 迁移到 ESXi 主机 192.168.1.162 上,使用 VMware vCenter Server(vSphere Client)在浏览器上可视化操作,将这个需求变的非常简单。 1、选中需要迁移的虚拟机&#xff0c…

k8s部署rabbitmq集群

1 部署集群 1.1 安装 # 创建一个中间件的命名空间 kubectl create namespace middleware # 创建ConfigMap,包含RabbitMQ的配置文件内容 kubectl apply -f rabbitmq-configmap.yaml # 配置用于存储RabbitMQ数据的PersistentVolume(PV)和PersistentVolum…

系统架构设计师教程 第4章 信息安全技术基础知识-4.3 信息安全系统的组成框架4.4 信息加解密技术-解读

系统架构设计师教程 第4章 信息安全技术基础知识-4.3 信息安全系统的组成框架 4.3 信息安全系统的组成框架4.3.1 技术体系4.3.1.1 基础安全设备4.3.1.2 计算机网络安全4.3.1.3 操作系统安全4.3.1.4 数据库安全4.3.1.5 终端安全设备4.3.2 组织机构体系4.3.3 管理体系4.4 信息加…

机器学习(五) -- 无监督学习(1) --聚类2

系列文章目录及链接 上篇:机器学习(五) -- 无监督学习(1) --聚类1 下篇: 前言 tips:标题前有“***”的内容为补充内容,是给好奇心重的宝宝看的,可自行跳过。文章内容被…

微服务(网关路由)

目录 一:网关路由 1:认识网关 2:快速入门 2.1:创建项目 2.2:引入依赖 2.3:启动类 2.4:路由配置 2.5:测试 3:路由过滤 二:网关登录校验 1&…

OpenWrt 为软件包和docker空间扩容

参考资料 【openwrt折腾日记】解决openwrt固件刷入后磁盘空间默认小的问题,关联openwrt磁盘扩容空间扩容【openwrt分区扩容】轻松解决空间可用不足的尴尬丨老李一瓶奶油的YouTube 划分空间 参考一瓶奶油的YouTube 系统 -> 磁盘管理 -> 磁盘 -> 修改 格…

探索Linux-1

Linux是什么? Linux是一个开源的操作系统内核,由林纳斯托瓦兹(Linus Torvalds)于1991年首次发布。它基于Unix操作系统,但提供了更多的自由和灵活性。Linux内核是操作系统的核心部分,负责管理系统资源、处理…

编程中的智慧四:设计模式总览

前面三篇我们通过从一些零散的例子,和简单应用来模糊的感受了下设计模式在编程中的智慧,从现在开始正式进入设计模式介绍,本篇将从设计模式的7大原则、设计模式的三大类型、与23种设计模式的进行总结,和描述具体意义。 设计模式体…

LeetCode 860柠檬水找零(贪心算法)/406根据身高重建队列(贪心算法)

1. 柠檬水找零 思路分析 只需要维护三种金额的数量,5,10和20。 有如下三种情况: 情况一:账单是5,直接收下。情况二:账单是10,消耗一个5,增加一个10情况三:账单是20&am…

(35)远程识别(又称无人机识别)(二)

文章目录 前言 4 ArduRemoteID 5 终端用户数据的设置和使用 6 测试 7 为OEMs添加远程ID到ArduPilot系统的视频教程 前言 在一些国家,远程 ID 正在成为一项法律要求。以下是与 ArduPilot 兼容的设备列表。这里(here)有一个关于远程 ID 的很好解释和常见问题列表…

【linux】Shell脚本三剑客之awk命令的详细用法攻略

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全…

[用AI日进斗金系列③]用CodeFlying在企微接单自动生成一个固定资产管理系统

今天是【日进斗金】系列的第三期文章。 给新朋友简单介绍一下,我们这个系列主要是教大家如何在企业微信的工作台上接单赚米。 详细介绍可以看看前两期的文章 [用AI日进斗金系列]用码上飞在企微接单开发一个项目管理系统!-CSDN博客 [用AI日进斗金系列…

【Android】性能实践—编码优化与布局优化学习笔记

【Android】性能实践—编码优化与布局优化学习笔记 编码优化 使用场景 如果需要拼接字符串,优先使用StringBuffer和StringBuilder进行凭借,他们的性能优于直接用加号进行拼接,因为使用加号连接符会创建多余的对象一般情况下使用基本数据类…

有监督学习基础

基本概念 给定输入有为(x,y),其中x表示学习特征,y表示输出,m表示输入总数,有监督学习旨在根据输入建立能够预测可能输出的模型,大致可以分为回归和分类两种,代表可能输出是无限的或…

vue 实战 tab标签页+el-card+流式布局+异步接口调用

<template><div><!-- 布局按钮 --><el-button click"dialogVisible true">布局配置查看</el-button><!-- 布局配置对话框 --><el-dialog :visible.sync"dialogVisible" title"布局配置查看" width"…

nature reviews genetics | 单细胞基因组eQTL发展历程

– https://doi.org/10.1038/s41576-023-00599-5 留意更多内容&#xff0c;欢迎关注微信公众号&#xff1a;组学之心 Single-cell genomics meets human genetics 单细胞基因组技术已经扩展到可以检测数千个个体的样本的程度。将大规模的单细胞信息与基因型数据相结合&#x…

STM32F103C8T6基于YMODEM协议的串口IAP升级实践

一.为什么要做IAP升级 1.不易拆卸的设备&#xff0c;可以使用IAP升级&#xff0c;方便用户升级固件 2.YMODEM协议是串口传输协议&#xff0c;传输速率较高&#xff0c;传输文件较大时&#xff0c;传输时间较短 3.不想给别人源代码&#xff0c;但是项目有bug&#xff0c;需要修…

【PLC】三菱FX3U下载程序通讯中断问题解决方法之一

博主最近买了一个三菱PLC FX3U&#xff0c;然后随意在GX Works中编写了一段带有子程序的程序&#xff0c;后来发现刷写程序过程中&#xff0c;会突然出现通讯中断的情况&#xff0c;然后切断PLC电源&#xff0c;变更COM口&#xff0c;重启PLC后&#xff0c;通讯才可以连接上&am…

鸿蒙OpenHarmony Native API【drawing_pen.h】 头文件

drawing_pen.h Overview Related Modules: [Drawing] Description: 文件中定义了与画笔相关的功能函数 Since: 8 Version: 1.0 Summary Enumerations Enumeration NameDescription[OH_Drawing_PenLineCapStyle] { [LINE_FLAT_CAP], [LINE_SQUARE_CAP], [LINE_ROUND_…

PMP考试难度大吗?

由于目前的PMP考试主要以新大纲为主&#xff0c;许多内容都已经发生了变化&#xff0c;因此学习新内容以适应这些变化仍然是非常必要的。 一、新版考试题量和答题时间有何变化&#xff1f; 题量由200道减少到180道&#xff0c;因此答题时间相对更充裕。 二、新版考试的整体难…