前言
本文介绍 MFDS-DETR 中的高层筛选特征金字塔 HS-FPN 在 YOLO26 中的接入方法。HS-FPN 利用高层语义特征生成通道权重,对低层特征进行选择,再通过逐点相加完成跨尺度融合。本文保留 YOLO26 主干及检测头,在 Neck 中构建 P5 → P4 → P3 的选择性特征交互,提供与当前项目一致的模块实现、注册步骤、YAML 和训练脚本。具体精度与速度变化需要通过目标数据集上的完整训练及基线对比评估。
文章目录: YOLO26改进大全:卷积层、轻量化、注意力机制、损失函数、Backbone、SPPF、Neck、检测头全方位优化汇总
专栏链接: 最新YOLO26改进专栏
文章目录
- 前言
- 介绍
- 摘要
- 文章链接
- 基本原理
- 核心代码
- YOLO26引入代码
- tasks注册
- 步骤1:
- 步骤2:
- 配置yolo26-HSFPN.yaml
- 实验
- 脚本
- 结果
介绍
以下摘要和基本原理对应原 MFDS-DETR 论文;本项目的接入范围为 HS-FPN 特征选择与融合模块。
摘要
本文提出了一种突破性的白细胞检测方法——多层次特征融合和可变形自注意力DETR(MFDS-DETR),旨在革新传统医院血液检测流程中存在的诸多痼疾。传统检测模式中,医务人员需借助显微镜从患者血液显微图像中手动分离白细胞,继而通过自动分类器确定不同类型白细胞的分布情况以辅助临床诊断。此种方法不仅耗费大量人力物力,更因图像质量波动和环境干扰等因素容易产生判读偏差,进而导致分类错误与诊断失准。现有白细胞检测技术在处理特征稀疏的图像样本及应对白细胞尺寸差异方面表现乏力,检测效果往往不尽如人意。
针对上述挑战,我们精心设计了MFDS-DETR检测框架,其核心创新在于两大技术突破:一方面,为应对白细胞尺寸变化问题,我们构建了高层次筛选特征融合金字塔(HS-FPN),实现了多层次特征的智能融合。该模块巧妙地利用高层次特征作为权重指导,通过精密的通道注意力机制对低层次特征进行有效筛选,随后将优化后的特征信息与高层次特征进行深度融合,显著增强了模型的特征表达能力。另一方面,我们创新性地在编码器中引入多尺度可变形自注意模块,并在解码器中融合自注意与交叉可变形注意机制,有效解决了白细胞特征稀缺的难题,极大提升了模型捕获白细胞图像全局特征的能力。
通过在私有WBCDD数据集以及公开的LISC和BCCD基准数据集上与前沿白细胞检测模型的全面比较,充分验证了MFDS-DETR方法的卓越性能、技术优势及广泛适用性。我们的完整源代码及私有WBCCD数据集已在GitHub平台(https://github.com/JustlfC03/MFDS-DETR)开放共享,以促进该领域的进一步研究与应用。
文章链接
论文地址:论文地址
代码地址:代码地址
基本原理
HS-FPN(Hierarchical Scale-based Feature Pyramid Network)是一种用于多尺度特征融合的网络结构,旨在解决白细胞图像中的多尺度挑战,从而提高模型对白细胞的准确识别能力。HS-FPN包括两个主要组件:特征选择模块和特征融合模块。
特征选择模块:在特征选择模块中,不同尺度的特征图经过筛选过程。这个过程有助于选择高级和低级特征图中的信息。
特征融合模块:在特征融合模块中,经过筛选的特征与高级语义特征进行逐点相加。这种融合方式能够有效地将高级语义信息与低级特征属性相结合,从而提高对白细胞图像的特征表达能力。
HS-FPN利用通道注意(Channel Attention,CA)模块来利用高级语义特征作为权重,以过滤低级特征。这种筛选后的特征与高级语义特征相加,实现了多尺度特征融合,从而提高了模型的特征表达能力。通过这种方式,HS-FPN能够更好地捕获白细胞图像的全面特征信息,从而提高白细胞检测的准确性和效率。
核心代码
import torch import torch.nn as nn class HSFPNChannelAttention(nn.Module): """Return reweighted features, or channel weights for selecting a lower-level feature.""" def __init__(self, in_planes, ratio=4, flag=True): super().__init__() if in_planes < 1 or ratio < 1: raise ValueError("HSFPNChannelAttention requires positive channels and reduction ratio") hidden = max(1, in_planes // ratio) self.avg_pool = nn.AdaptiveAvgPool2d(1) self.max_pool = nn.AdaptiveMaxPool2d(1) self.conv1 = nn.Conv2d(in_planes, hidden, 1, bias=False) self.relu = nn.ReLU() self.conv2 = nn.Conv2d(hidden, in_planes, 1, bias=False) self.flag = flag self.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)))) weights = self.sigmoid(avg_out + max_out) return weights * x if self.flag else weights class Multiply(nn.Module): """Apply a broadcastable channel gate to a feature map.""" def forward(self, x): if len(x) != 2: raise ValueError("HS-FPN Multiply requires a gate and a feature map") return x[0] * x[1] class Add(nn.Module): """Sum spatially aligned feature maps with matching channels.""" def forward(self, x): if len(x) < 2: raise ValueError("HS-FPN Add requires at least two feature maps") return torch.sum(torch.stack(x, dim=0), dim=0)YOLO26引入代码
在根目录下的ultralytics/nn/目录,新建一个featureFusion目录,然后新建一个以HSFPN为文件名的py文件, 把代码拷贝进去。
当前项目已有此文件时,更新为下面的完整实现。隐藏通道数至少为 1,以兼容较小输入通道;注意力计算与原文一致。
importtorchimporttorch.nnasnnclassHSFPNChannelAttention(nn.Module):"""Return reweighted features, or channel weights for selecting a lower-level feature."""def__init__(self,in_planes,ratio=4,flag=True):super().__init__()ifin_planes<1orratio<1:raiseValueError("HSFPNChannelAttention requires positive channels and reduction ratio")hidden=max(1,in_planes//ratio)self.avg_pool=nn.AdaptiveAvgPool2d(1)self.max_pool=nn.AdaptiveMaxPool2d(1)self.conv1=nn.Conv2d(in_planes,hidden,1,bias=False)self.relu=nn.ReLU()self.conv2=nn.Conv2d(hidden,in_planes,1,bias=False)self.flag=flag self.sigmoid=nn.Sigmoid()nn.init.xavier_uniform_(self.conv1.weight)nn.init.xavier_uniform_(self.conv2.weight)defforward(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))))weights=self.sigmoid(avg_out+max_out)returnweights*xifself.flagelseweightsclassMultiply(nn.Module):"""Apply a broadcastable channel gate to a feature map."""defforward(self,x):iflen(x)!=2:raiseValueError("HS-FPN Multiply requires a gate and a feature map")returnx[0]*x[1]classAdd(nn.Module):"""Sum spatially aligned feature maps with matching channels."""defforward(self,x):iflen(x)<2:raiseValueError("HS-FPN Add requires at least two feature maps")returntorch.sum(torch.stack(x,dim=0),dim=0)tasks注册
在ultralytics/nn/tasks.py中进行如下操作:
步骤1:
fromultralytics.nn.featureFusion.HSFPNimport(AddasHSFPNAdd,HSFPNChannelAttention,MultiplyasHSFPNMultiply,)步骤2:
在parse_model(d, ch, verbose=True)的模块判断链中增加以下专用分支 .
elifmisHSFPNChannelAttention:c2=ch[f]args=[c2,*args]elifmin{HSFPNMultiply,HSFPNAdd}:ifnotisinstance(f,list)orlen(f)<2:raiseValueError(f"{m.__name__}requires multiple input layers")ifmisHSFPNMultiplyandlen(f)!=2:raiseValueError("HSFPNMultiply requires two input layers")c2=ch[f[-1]]ifany(ch[x]!=c2forxinf):raiseValueError(f"{m.__name__}requires matching input channels")args=[]配置yolo26-HSFPN.yaml
# Ultralytics 🚀 AGPL-3.0 License - https://ultralytics.com/license# Ultralytics YOLO26 object detection model with P3/8 - P5/32 outputs# Model docs: https://docs.ultralytics.com/models/yolo26# Task docs: https://docs.ultralytics.com/tasks/detect# Parametersnc:80# number of classesend2end:True# whether to use end-to-end modereg_max:1# DFL binsscales:# model compound scaling constants, i.e. 'model=yolo26n.yaml' will call yolo26.yaml with scale 'n'# [depth, width, max_channels]n:[0.50,0.25,1024]s:[0.50,0.50,1024]m:[0.50,1.00,512]l:[1.00,1.00,512]x:[1.00,1.50,512]# YOLO26n backbonebackbone:# [from, repeats, module, args]-[-1,1,Conv,[64,3,2]]# 0-P1/2-[-1,1,Conv,[128,3,2]]# 1-P2/4-[-1,2,C3k2,[256,False,0.25]]-[-1,1,Conv,[256,3,2]]# 3-P3/8-[-1,2,C3k2,[512,False,0.25]]-[-1,1,Conv,[512,3,2]]# 5-P4/16-[-1,2,C3k2,[512,True]]-[-1,1,Conv,[1024,3,2]]# 7-P5/32-[-1,2,C3k2,[1024,True]]-[-1,1,SPPF,[1024,5,3,True]]# 9-[-1,2,C2PSA,[1024]]# 10# YOLO26n head:head:-[10,1,HSFPNChannelAttention,[4]]# 11 select backbone P5-[-1,1,Conv,[256,1,1]]# 12 project P5/32 channels-[-1,1,nn.ConvTranspose2d,[256,3,2,1,1]]# 13 P5 to P4-[6,1,HSFPNChannelAttention,[4]]# 14 select backbone P4-[-1,1,Conv,[256,1,1]]# 15 project P4 channels-[13,1,HSFPNChannelAttention,[4,False]]# 16 high-level P4 channel gate-[[16,15],1,HSFPNMultiply,[]]# 17 select lower-level P4-[[17,13],1,HSFPNAdd,[]]# 18 fuse gated P4 with high-level P4-[-1,2,C3k2,[256,True]]# 19 P4/16-medium-[19,1,nn.ConvTranspose2d,[256,3,2,1,1]]# 20 refined P4 to P3-[4,1,HSFPNChannelAttention,[4]]# 21 select backbone P3-[-1,1,Conv,[256,1,1]]# 22 project P3 channels-[20,1,HSFPNChannelAttention,[4,False]]# 23 high-level P3 channel gate-[[23,22],1,HSFPNMultiply,[]]# 24 select lower-level P3-[[24,20],1,HSFPNAdd,[]]# 25 fuse gated P3 with high-level P3-[-1,2,C3k2,[256,True]]# 26 P3/8-small-[[26,19,12],1,Detect,[nc]]# Detect(P3, P4, P5)实验
脚本
importwarnings warnings.filterwarnings('ignore')fromultralyticsimportYOLOif__name__=='__main__':# 修改为自己的配置文件地址model=YOLO('./ultralytics/cfg/models/26/yolo26-HSFPN.yaml')# 修改为自己的数据集地址model.train(data='./ultralytics/cfg/datasets/coco8.yaml',cache=False,imgsz=640,epochs=10,single_cls=False,# 是否是单类别检测batch=8,close_mosaic=10,workers=0,optimizer='MuSGD',# optimizer='SGD',amp=False,project='runs/train',name='HSFPN',)