YOLOv9改进策略 | Neck篇 | 2024.1最新MFDS-DETR的HS-FPN改进特征融合层(轻量化Neck、全网独家首发)

本文主要是介绍YOLOv9改进策略 | Neck篇 | 2024.1最新MFDS-DETR的HS-FPN改进特征融合层(轻量化Neck、全网独家首发),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

  一、本文介绍

本文给大家带来的改进机制是最近这几天最新发布的改进机制MFDS-DETR提出的一种HS-FPN结构,其是一种为白细胞检测设计的网络结构,主要用于解决白细胞数据集中的多尺度挑战。它的基本原理包括两个关键部分:特征选择模块特征融合模块。其可以起到特征选择的作用,非常适合轻量化的读者来使用,其存在二次创新和多次创新的机会,利用该结构参数量下降了约100W,本专栏每周更新3-5篇最新机制,更有包含我所有改进的文件和交流群提供给大家,同时本专栏目前改进基于yolov9.yaml文件,后期如果官方放出轻量化版本,专栏内所有改进也会同步更新,请大家放心。

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

专栏地址:YOLOv9有效涨点专栏-持续复现各种顶会内容-有效涨点-全网改进最全的专栏 

目录

  一、本文介绍

二、HS-FPN原理

2.1  HS-FPN的基本原理

2.2  SSF模块

三、HS-FPN的核心代码

四、手把手教你添加HS-FPN 

4.1 HS-FPN添加步骤

4.1.1 修改一

4.1.2 修改二

4.1.3 修改三 

4.1.4 修改四

4.2 HS-FPN的yaml文件和训练截图

4.2.1 HS-FPN的yaml版本一(推荐)

4.2.2 HS-FPN的yaml版本二

4.2 HS-FPN的训练过程截图 

五、本文总结


二、HS-FPN原理

dc5fc59fbdae4c919232c28df8009d0f.png

论文地址:论文官方链接

代码地址:代码官方链接

610b78849060477ca986c2d71398cf80.png


2.1  HS-FPN的基本原理

HS-FPN(High-level Screening-feature Fusion Pyramid Networks)是一种为白细胞检测设计的网络结构,主要用于解决白细胞数据集中的多尺度挑战。它的基本原理包括两个关键部分:特征选择模块特征融合模块

HS-FPN的结构如下图所示,包括两个主要组成部分:

2eafc944fb234fc5b384934ecd97a0a8.png

1. 特征选择模块:该模块利用通道注意力(CA)和维度匹配(DM)机制对不同尺度的特征图进行筛选。通过池化操作(如全局平均池化和全局最大池化)和权重计算,该模块有效地提取了每个通道中的重要信息。

2. 特征融合模块:该模块通过选择性特征融合(SFF)机制将筛选后的低级特征和高级特征结合起来。高级特征扩展后,通过双线性插值或转置卷积进行尺度调整,然后与低级特征融合,从而增强模型对白细胞特征的表达能力。

总的来说,HS-FPN通过这两个模块协同工作,有效地解决了白细胞检测中的多尺度问题,提高了检测的准确性和鲁棒性。


2.2  SSF模块

选择性特征融合(Selective Feature Fusion, SFF)是HS-FPN网络中的一个关键组件,它的主要作用是融合不同尺度的特征图。SFF通过使用高级特征作为权重来过滤低尺度特征中的重要信息。在这个过程中,高级特征经过转置卷积和双线性插值操作进行尺度调整,以匹配低尺度特征的尺寸。然后,利用高级特征作为注意力权重,筛选出低尺度特征中有用的信息。这种融合方法能够有效地结合高级特征的语义信息和低尺度特征的细节信息,从而提高模型在处理多尺度问题时的性能。

 下图为大家展示了SFF模块的框架结构:

4ab051fb7d174d31add86d1ac4ad0e7d.png

给定一个输入高级特征eq?f_%7Bhigh%7D%5Cepsilon%20R%5E%7BC*H*W%7D和一个输入低尺度特征eq?f_%7Blow%7D%5Cepsilon%20R%5E%7BC*H*W_%7B1%7D%7D,高级特征首先使用一个大小为2,核大小为3x3的转置卷积(T-Conv)进行扩展,得到特征大小eq?f_%7Bhigh%7D%5Cepsilon%20R%5E%7BC*2H*2W%7D

然后,为了统一高级特征和低尺度特征的维度,作者使用双线性插值来向上或向下采样高级特征,得到特征eq?f_%7Batt%7D%5Cepsilon%20R%5E%7BC*H_%7B1%7D*W_%7B1%7D%7D。接下来,使用CA模块将高级特征转换为相应的注意力权重,以过滤低尺度特征,在获得具有相同维度的特征后。

最后,将过滤后的低尺度特征与高级特征融合,以增强模型的特征表示,并得到eq?f_%7Bout%7D%5Cepsilon%20R%5E%7BC*H_%7B1%7D*W_%7B1%7D%7D。方程(1)和(2)说明了特征选择的融合过程:

65f82ddf139441b29ef26fd1349271af.png


三、HS-FPN的核心代码

这里的CA对应着官方代码中的ChannelAttention,但是在早期的库里面它在官方里面已经集成了,导入过来可能名字重复从而导致使用的时候报错,我这里给改写成CA了,大家看官方代码的时候需要注意下。

import torch
import torch.nn as nn
import torch.nn.functional as F__all__ = ['CA', 'multiply', 'Add']class Add(nn.Module):# Concatenate a list of tensors along dimensiondef __init__(self, ch=256):super().__init__()def forward(self, x):input1, input2 = x[0], x[1]x = input1 + input2return xclass multiply(nn.Module):def __init__(self):super().__init__()def forward(self, x):x = x[0] * x[1]return xclass CA(nn.Module):def __init__(self, in_planes, ratio = 4, flag=True):super(CA, self).__init__()self.avg_pool = nn.AdaptiveAvgPool2d(1)self.max_pool = nn.AdaptiveMaxPool2d(1)self.conv1 = nn.Conv2d(in_planes, in_planes // ratio, 1, bias=False)self.relu = nn.ReLU()self.conv2 = nn.Conv2d(in_planes // ratio, in_planes, 1, bias=False)self.flag = flagself.sigmoid = nn.Sigmoid()nn.init.xavier_uniform_(self.conv1.weight)nn.init.xavier_uniform_(self.conv2.weight)def forward(self, x):avg_out = self.conv2(self.relu(self.conv1(self.avg_pool(x))))max_out = self.conv2(self.relu(self.conv1(self.max_pool(x))))out = avg_out + max_outout = self.sigmoid(out) * x if self.flag else self.sigmoid(out)return outclass FeatureSelectionModule(nn.Module):def __init__(self, in_chan, out_chan):super(FeatureSelectionModule, self).__init__()self.conv_atten = nn.Conv2d(in_chan, in_chan, kernel_size=1)self.group_norm1 = nn.GroupNorm(32, in_chan)self.sigmoid = nn.Sigmoid()self.conv = nn.Conv2d(in_chan, out_chan, kernel_size=1)self.group_norm2 = nn.GroupNorm(32, out_chan)nn.init.xavier_uniform_(self.conv_atten.weight)nn.init.xavier_uniform_(self.conv.weight)def forward(self, x):atten = self.sigmoid(self.group_norm1(self.conv_atten(F.avg_pool2d(x, x.size()[2:]))))feat = torch.mul(x, atten)x = x + featfeat = self.group_norm2(self.conv(x))return featif __name__ == "__main__":# Generating Sample imageimage_size = (1, 64, 240, 240)image = torch.rand(*image_size)# Modelmobilenet_v3 = FeatureSelectionModule(64, 64)out = mobilenet_v3(image)print(out.size())


四、手把手教你添加HS-FPN 

4.1 HS-FPN添加步骤

4.1.1 修改一

首先我们找到如下的目录'yolov9-main/models',然后在这个目录下在创建一个新的目录然后这个就是存储改进的仓库,大家可以在这里新建所有的改进的py文件,对应改进的文件名字可以根据你自己的习惯起(不影响任何但是下面导入的时候记住改成你对应的即可),然后将HS-FPN 的核心代码复制进去。


4.1.2 修改二

然后在新建的目录里面我们在新建一个__init__.py文件(此文件大家只需要建立一个即可),然后我们在里面添加导入我们模块的代码。注意标记一个'.'其作用是标记当前目录。


4.1.3 修改三 

然后我们找到如下文件''models/yolo.py''在开头的地方导入我们的模块按照如下修改->

(如果你看了我多个改进机制此处只需要添加一个即可,无需重复添加)

注意的添加位置要放在common的导入上面!!!!!

5af82969538846b0ad386aa4acd733dd.png​​​​


4.1.4 修改四

然后我们找到''models/yolo.py''文件中的parse_model方法,按照如下修改->

3b5e1471ac054f6c8e50ffd57a080b7a.png

        elif m in {'此处添加大家修改的对应机制即可'}:c2 = ch[f]args = [c2, *args]
        elif m is multiply:c2 = ch[f[0]]elif m is Add:c2 = ch[f[-1]]

到此就修改完成了,复制下面的ymal文件即可运行。


4.2 HS-FPN的yaml文件和训练截图

4.2.1 HS-FPN的yaml版本一(推荐)

下面的添加HS-FPN是我实验结果的版本,这个版本为官方一比一复现的版本。

# YOLOv9# parameters
nc: 80  # number of classes
depth_multiple: 1  # model depth multiple
width_multiple: 1  # layer channel multiple
#activation: nn.LeakyReLU(0.1)
#activation: nn.ReLU()# anchors
anchors: 3# YOLOv9 backbone
backbone:[[-1, 1, Silence, []],# conv down[-1, 1, Conv, [64, 3, 2]],  # 1-P1/2# conv down[-1, 1, Conv, [128, 3, 2]],  # 2-P2/4# elan-1 block[-1, 1, RepNCSPELAN4, [256, 128, 64, 1]],  # 3# conv down[-1, 1, Conv, [256, 3, 2]],  # 4-P3/8# elan-2 block[-1, 1, RepNCSPELAN4, [512, 256, 128, 1]],  # 5# conv down[-1, 1, Conv, [512, 3, 2]],  # 6-P4/16# elan-2 block[-1, 1, RepNCSPELAN4, [512, 512, 256, 1]],  # 7# conv down[-1, 1, Conv, [512, 3, 2]],  # 8-P5/32# elan-2 block[-1, 1, RepNCSPELAN4, [512, 512, 256, 1]],  # 9]# YOLOv9 head
head:[# elan-spp block[-1, 1, SPPELAN, [512, 256]],  # 10[ -1, 1, CA, [ ] ], # 11[ -1, 1, nn.Conv2d, [ 256, 1 ] ], # 12[ -1, 1, RepNCSPELAN4, [256, 256, 128, 1] ], # 13 P5[ 7, 1, CA, [ ] ],[ -1, 1, nn.Conv2d, [ 256, 1 ] ],  # 15[ 12, 1, nn.ConvTranspose2d, [ 256, 3, 2, 1, 1 ] ], # 16[ -1, 1, CA, [ 4, False ] ],[ [ -1, 15 ], 1, multiply, [ ] ], # 18[ [ -1, 16 ], 1, Add, [ ] ], # 19[ -1, 1, RepNCSPELAN4, [256, 256, 128, 1]], # 20 P4[ 5, 1, CA, [ ] ], # 21[ -1, 1, nn.Conv2d, [ 256, 1 ] ], # 22[ 16, 1, nn.ConvTranspose2d, [ 256, 3, 2, 1, 1 ] ], # 23[ -1, 1, CA, [ 4, False ] ], # 24[ [ -1, 22 ], 1, multiply, [ ] ], # 25[ [ -1, 23 ], 1, Add, [ ] ], # 26[ -1, 1, RepNCSPELAN4, [256, 256, 128, 1]], # 27 P3# routing + 5[5, 1, CBLinear, [[256]]], # 28[7, 1, CBLinear, [[256, 512]]], # 29[9, 1, CBLinear, [[256, 512, 512]]], # 30# conv down[0, 1, Conv, [64, 3, 2]],  # 31-P1/2# conv down[-1, 1, Conv, [128, 3, 2]],  # 32-P2/4# elan-1 block[-1, 1, RepNCSPELAN4, [256, 128, 64, 1]],  # 33# conv down fuse[-1, 1, Conv, [256, 3, 2]],  # 34-P3/8[[28, 29, 30, -1], 1, CBFuse, [[0, 0, 0]]], # 35# elan-2 block[-1, 1, RepNCSPELAN4, [512, 256, 128, 1]],  # 36# conv down fuse[-1, 1, Conv, [512, 3, 2]],  # 37-P4/16[[29, 30, -1], 1, CBFuse, [[1, 1]]], # 38# elan-2 block[-1, 1, RepNCSPELAN4, [512, 512, 256, 1]],  # 39# conv down fuse[-1, 1, Conv, [512, 3, 2]],  # 40-P5/32[[30, -1], 1, CBFuse, [[2]]], # 41# elan-2 block[-1, 1, RepNCSPELAN4, [512, 512, 256, 1]],  # 42# detect[[36, 39, 42, 13, 20, 27], 1, DualDDetect, [nc]],  # DualDDetect(A3, A4, A5, P3, P4, P5)]


4.2.2 HS-FPN的yaml版本二

添加的版本二具体那种适合你需要大家自己多做实验来尝试,此版本把通道数改回了YOLOv5的版本。

# YOLOv9# parameters
nc: 80  # number of classes
depth_multiple: 1  # model depth multiple
width_multiple: 1  # layer channel multiple
#activation: nn.LeakyReLU(0.1)
#activation: nn.ReLU()# anchors
anchors: 3# YOLOv9 backbone
backbone:[[-1, 1, Silence, []],# conv down[-1, 1, Conv, [64, 3, 2]],  # 1-P1/2# conv down[-1, 1, Conv, [128, 3, 2]],  # 2-P2/4# elan-1 block[-1, 1, RepNCSPELAN4, [256, 128, 64, 1]],  # 3# conv down[-1, 1, Conv, [256, 3, 2]],  # 4-P3/8# elan-2 block[-1, 1, RepNCSPELAN4, [512, 256, 128, 1]],  # 5# conv down[-1, 1, Conv, [512, 3, 2]],  # 6-P4/16# elan-2 block[-1, 1, RepNCSPELAN4, [512, 512, 256, 1]],  # 7# conv down[-1, 1, Conv, [512, 3, 2]],  # 8-P5/32# elan-2 block[-1, 1, RepNCSPELAN4, [512, 512, 256, 1]],  # 9]# YOLOv9 head
head:[# elan-spp block[-1, 1, SPPELAN, [512, 256]],  # 10[ -1, 1, CA, [ ] ], # 11[ -1, 1, nn.Conv2d, [ 256, 1 ] ], # 12[ -1, 1, RepNCSPELAN4, [256, 256, 128, 1] ], # 13 P5[ 7, 1, CA, [ ] ],[ -1, 1, nn.Conv2d, [ 256, 1 ] ],  # 15[ 12, 1, nn.ConvTranspose2d, [ 256, 3, 2, 1, 1 ] ], # 16[ -1, 1, CA, [ 4, False ] ],[ [ -1, 15 ], 1, multiply, [ ] ], # 18[ [ -1, 16 ], 1, Add, [ ] ], # 19[ -1, 1, RepNCSPELAN4, [512, 256, 128, 1]], # 20 P4[ 5, 1, CA, [ ] ], # 21[ -1, 1, nn.Conv2d, [ 256, 1 ] ], # 22[ 16, 1, nn.ConvTranspose2d, [ 256, 3, 2, 1, 1 ] ], # 23[ -1, 1, CA, [ 4, False ] ], # 24[ [ -1, 22 ], 1, multiply, [ ] ], # 25[ [ -1, 23 ], 1, Add, [ ] ], # 26[ -1, 1, RepNCSPELAN4, [512, 256, 128, 1]], # 27 P3# routing + 5[5, 1, CBLinear, [[256]]], # 28[7, 1, CBLinear, [[256, 512]]], # 29[9, 1, CBLinear, [[256, 512, 512]]], # 30# conv down[0, 1, Conv, [64, 3, 2]],  # 31-P1/2# conv down[-1, 1, Conv, [128, 3, 2]],  # 32-P2/4# elan-1 block[-1, 1, RepNCSPELAN4, [256, 128, 64, 1]],  # 33# conv down fuse[-1, 1, Conv, [256, 3, 2]],  # 34-P3/8[[28, 29, 30, -1], 1, CBFuse, [[0, 0, 0]]], # 35# elan-2 block[-1, 1, RepNCSPELAN4, [512, 256, 128, 1]],  # 36# conv down fuse[-1, 1, Conv, [512, 3, 2]],  # 37-P4/16[[29, 30, -1], 1, CBFuse, [[1, 1]]], # 38# elan-2 block[-1, 1, RepNCSPELAN4, [512, 512, 256, 1]],  # 39# conv down fuse[-1, 1, Conv, [512, 3, 2]],  # 40-P5/32[[30, -1], 1, CBFuse, [[2]]], # 41# elan-2 block[-1, 1, RepNCSPELAN4, [512, 512, 256, 1]],  # 42# detect[[36, 39, 42, 13, 20, 27], 1, DualDDetect, [nc]],  # DualDDetect(A3, A4, A5, P3, P4, P5)]


4.2 HS-FPN的训练过程截图 

大家可以看下面的运行结果和添加的位置所以不存在我发的代码不全或者运行不了的问题大家有问题也可以在评论区评论我看到都会为大家解答(我知道的)。

​​​​​​


五、本文总结

到此本文的正式分享内容就结束了,在这里给大家推荐我的YOLOv9改进有效涨点专栏,本专栏目前为新开的平均质量分98分,后期我会根据各种最新的前沿顶会进行论文复现,也会对一些老的改进机制进行补充,如果大家觉得本文帮助到你了,订阅本专栏,关注后续更多的更新~

希望大家阅读完以后可以给文章点点赞和评论支持一下这样购买专栏的人越多群内人越多大家交流的机会就更多了。  

专栏地址:YOLOv9有效涨点专栏-持续复现各种顶会内容-有效涨点-全网改进最全的专栏 

这篇关于YOLOv9改进策略 | Neck篇 | 2024.1最新MFDS-DETR的HS-FPN改进特征融合层(轻量化Neck、全网独家首发)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

MyBatis Plus 中 update_time 字段自动填充失效的原因分析及解决方案(最新整理)

《MyBatisPlus中update_time字段自动填充失效的原因分析及解决方案(最新整理)》在使用MyBatisPlus时,通常我们会在数据库表中设置create_time和update... 目录前言一、问题现象二、原因分析三、总结:常见原因与解决方法对照表四、推荐写法前言在使用 MyBATis

Java SWT库详解与安装指南(最新推荐)

《JavaSWT库详解与安装指南(最新推荐)》:本文主要介绍JavaSWT库详解与安装指南,在本章中,我们介绍了如何下载、安装SWTJAR包,并详述了在Eclipse以及命令行环境中配置Java... 目录1. Java SWT类库概述2. SWT与AWT和Swing的区别2.1 历史背景与设计理念2.1.

Redis过期删除机制与内存淘汰策略的解析指南

《Redis过期删除机制与内存淘汰策略的解析指南》在使用Redis构建缓存系统时,很多开发者只设置了EXPIRE但却忽略了背后Redis的过期删除机制与内存淘汰策略,下面小编就来和大家详细介绍一下... 目录1、简述2、Redis http://www.chinasem.cn的过期删除策略(Key Expir

Java日期类详解(最新推荐)

《Java日期类详解(最新推荐)》早期版本主要使用java.util.Date、java.util.Calendar等类,Java8及以后引入了新的日期和时间API(JSR310),包含在ja... 目录旧的日期时间API新的日期时间 API(Java 8+)获取时间戳时间计算与其他日期时间类型的转换Dur

MySQL复杂SQL之多表联查/子查询详细介绍(最新整理)

《MySQL复杂SQL之多表联查/子查询详细介绍(最新整理)》掌握多表联查(INNERJOIN,LEFTJOIN,RIGHTJOIN,FULLJOIN)和子查询(标量、列、行、表子查询、相关/非相关、... 目录第一部分:多表联查 (JOIN Operations)1. 连接的类型 (JOIN Types)

MySQL 存储引擎 MyISAM详解(最新推荐)

《MySQL存储引擎MyISAM详解(最新推荐)》使用MyISAM存储引擎的表占用空间很小,但是由于使用表级锁定,所以限制了读/写操作的性能,通常用于中小型的Web应用和数据仓库配置中的只读或主要... 目录mysql 5.5 之前默认的存储引擎️‍一、MyISAM 存储引擎的特性️‍二、MyISAM 的主

利用Python实现时间序列动量策略

《利用Python实现时间序列动量策略》时间序列动量策略作为量化交易领域中最为持久且被深入研究的策略类型之一,其核心理念相对简明:对于显示上升趋势的资产建立多头头寸,对于呈现下降趋势的资产建立空头头寸... 目录引言传统策略面临的风险管理挑战波动率调整机制:实现风险标准化策略实施的技术细节波动率调整的战略价

Python多进程、多线程、协程典型示例解析(最新推荐)

《Python多进程、多线程、协程典型示例解析(最新推荐)》:本文主要介绍Python多进程、多线程、协程典型示例解析(最新推荐),本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定... 目录一、multiprocessing(多进程)1. 模块简介2. 案例详解:并行计算平方和3. 实现逻

macOS Sequoia 15.5 发布: 改进邮件和屏幕使用时间功能

《macOSSequoia15.5发布:改进邮件和屏幕使用时间功能》经过常规Beta测试后,新的macOSSequoia15.5现已公开发布,但重要的新功能将被保留到WWDC和... MACOS Sequoia 15.5 正式发布!本次更新为 Mac 用户带来了一系列功能强化、错误修复和安全性提升,进一步增

Spring Boot集成SLF4j从基础到高级实践(最新推荐)

《SpringBoot集成SLF4j从基础到高级实践(最新推荐)》SLF4j(SimpleLoggingFacadeforJava)是一个日志门面(Facade),不是具体的日志实现,这篇文章主要介... 目录一、日志框架概述与SLF4j简介1.1 为什么需要日志框架1.2 主流日志框架对比1.3 SLF4