前言本文介绍了基于注意力尺度序列融合的ASF - YOLO模型在YOLO26中的结合应用。ASF - YOLO旨在实现准确快速的细胞实例分割结合空间和尺度特征引入SSFF模块增强多尺度信息提取能力TFE模块融合不同尺度特征图CPAM整合前两者以关注信息丰富通道和小物体。我们将ASF - YOLO相关模块集成进YOLO26替代原有的部分特征融合模块实现更高效的特征提取与融合。实验证明YOLO26 - ASFYOLO在细胞实例分割任务中表现出色展现了该模型在深度学习中的广泛应用前景。文章目录 YOLO26改进大全卷积层、轻量化、注意力机制、损失函数、Backbone、SPPF、Neck、检测头全方位优化汇总专栏链接: 最新YOLO26改进专栏文章目录前言介绍摘要文章链接基本原理核心代码YOLO26引入代码注册步骤1步骤2配置yolo26-ASFYOLO.yaml实验脚本结果介绍摘要我们提出了一种新颖的基于注意力尺度序列融合的YOLO框架ASF-YOLO该框架结合了空间和尺度特征用于准确且快速的细胞实例分割。在YOLO分割框架的基础上我们采用了尺度序列特征融合SSFF模块来增强网络的多尺度信息提取能力并使用三重特征编码器TFE模块来融合不同尺度的特征图以增加细节信息。我们进一步引入了通道和位置注意力机制CPAM来整合SSFF和TFE模块专注于信息丰富的通道和与空间位置相关的小物体从而提高检测和分割性能。在两个细胞数据集上的实验验证表明所提出的ASF-YOLO模型具有显著的分割精度和速度。在2018年数据科学竞赛数据集上它达到了0.91的box mAP0.887的mask mAP以及47.3 FPS的推理速度性能优于最先进的方法。源代码可在此处获取。文章链接论文地址论文地址代码地址代码地址基本原理ASF-YOLO是一种基于You Only Look Once (YOLO)框架的创新模型旨在实现准确和快速的细胞实例分割。该模型结合了空间和尺度特征通过引入Scale Sequence Feature Fusion (SSFF)模块和Triple Feature Encoder (TFE)模块来增强网络的多尺度信息提取能力和融合不同尺度特征图以增加详细信息。此外还引入了Channel and Position Attention Mechanism (CPAM)来整合SSFF和TFE模块重点关注信息丰富的通道和与空间位置相关的小物体以提高检测和分割性能。ASF-YOLO的整体架构包括以下主要组件SSFF模块用于有效融合来自多个尺度图像的全局或高级语义信息捕获不同细胞类型的各种大小和形状的不同空间尺度。在SSFF中从骨干网络提取的P3、P4和P5特征图被归一化到相同大小上采样然后堆叠在一起作为三维卷积的输入以结合多尺度特征。TFE模块用于增强密集细胞的小物体检测通过在空间维度上拼接三种不同尺寸大、中、小的特征捕获有关小物体的详细信息。TFE模块的详细特征信息然后通过PANet结构集成到每个特征分支中。CPAM基于CSPDarkNet骨干网络和YOLO头部结合了Channel and Position Attention Mechanism (CPAM)。CPAM专注于信息丰富的通道和与空间位置相关的小物体以改善检测和分割性能。核心代码完整实现见下方“YOLO26引入代码”包括 SSFFScalSeq、TPEZoom_cat和 CPAMattention_model。YOLO26引入代码在根目录下的ultralytics/nn/目录新建一个featureFusion目录然后新建一个以ASFYOLO为文件名的py文件 把代码拷贝进去。importtorchimporttorch.nnasnnimporttorch.nn.functionalasFimportmathfromultralytics.nn.modules.convimportConvclassZoom_cat(nn.Module):def__init__(self):super().__init__()# self.conv_l_post_down Conv(in_dim, 2*in_dim, 3, 1, 1)defforward(self,x):l,m,s表示大中小三个尺度最终会被整合到m这个尺度上l,m,sx[0],x[1],x[2]tgt_sizem.shape[2:]lF.adaptive_max_pool2d(l,tgt_size)F.adaptive_avg_pool2d(l,tgt_size)# l self.conv_l_post_down(l)# m self.conv_m(m)# s self.conv_s_pre_up(s)sF.interpolate(s,m.shape[2:],modenearest)# s self.conv_s_post_up(s)lmstorch.cat([l,m,s],dim1)returnlmsclassScalSeq(nn.Module):def__init__(self,inc,channel):super(ScalSeq,self).__init__()self.conv0Conv(inc[0],channel,1)self.conv1Conv(inc[1],channel,1)self.conv2Conv(inc[2],channel,1)self.conv3dnn.Conv2d(channel,channel,kernel_size1)self.bnnn.BatchNorm3d(channel)self.actnn.LeakyReLU(0.1)self.pool_3dnn.MaxPool3d(kernel_size(3,1,1))defforward(self,x):p3,p4,p5x[0],x[1],x[2]p3self.conv0(p3)p4_2self.conv1(p4)p4_2F.interpolate(p4_2,p3.size()[2:],modenearest)p5_2self.conv2(p5)p5_2F.interpolate(p5_2,p3.size()[2:],modenearest)p3_3dtorch.unsqueeze(p3,-3)p4_3dtorch.unsqueeze(p4_2,-3)p5_3dtorch.unsqueeze(p5_2,-3)combinetorch.cat([p3_3d,p4_3d,p5_3d],dim2)b,c,d,h,wcombine.shape# A 1x1x1 Conv3d applies the same channel projection independently at each scale.conv_3dself.conv3d(combine.permute(0,2,1,3,4).reshape(b*d,c,h,w))conv_3dconv_3d.reshape(b,d,c,h,w).permute(0,2,1,3,4)bnself.bn(conv_3d)actself.act(bn)xself.pool_3d(act)xtorch.squeeze(x,2)returnxclassAdd(nn.Module):# Concatenate a list of tensors along dimensiondef__init__(self,ch256):super().__init__()defforward(self,x):input1,input2x[0],x[1]xinput1input2returnxclasschannel_att(nn.Module):def__init__(self,channel,b1,gamma2):super(channel_att,self).__init__()kernel_sizeint(abs((math.log(channel,2)b)/gamma))kernel_sizekernel_sizeifkernel_size%2elsekernel_size1self.avg_poolnn.AdaptiveAvgPool2d(1)self.convnn.Conv2d(1,1,kernel_size(1,kernel_size),padding(0,(kernel_size-1)//2),biasFalse)self.sigmoidnn.Sigmoid()defforward(self,x):yself.avg_pool(x)yy.squeeze(-1)yy.transpose(-1,-2)yself.conv(y.unsqueeze(2)).squeeze(2).transpose(-1,-2).unsqueeze(-1)yself.sigmoid(y)returnx*y.expand_as(x)classlocal_att(nn.Module):def__init__(self,channel,reduction16):super(local_att,self).__init__()self.conv_1x1nn.Conv2d(in_channelschannel,out_channelsmax(1,channel//reduction),kernel_size1,stride1,biasFalse)self.relunn.ReLU()self.bnnn.BatchNorm2d(max(1,channel//reduction))self.F_hnn.Conv2d(in_channelsmax(1,channel//reduction),out_channelschannel,kernel_size1,stride1,biasFalse)self.F_wnn.Conv2d(in_channelsmax(1,channel//reduction),out_channelschannel,kernel_size1,stride1,biasFalse)self.sigmoid_hnn.Sigmoid()self.sigmoid_wnn.Sigmoid()defforward(self,x):_,_,h,wx.size()x_htorch.mean(x,dim3,keepdimTrue).permute(0,1,3,2)x_wtorch.mean(x,dim2,keepdimTrue)x_cat_conv_reluself.relu(self.bn(self.conv_1x1(torch.cat((x_h,x_w),3))))x_cat_conv_split_h,x_cat_conv_split_wx_cat_conv_relu.split([h,w],3)s_hself.sigmoid_h(self.F_h(x_cat_conv_split_h.permute(0,1,3,2)))s_wself.sigmoid_w(self.F_w(x_cat_conv_split_w))outx*s_h.expand_as(x)*s_w.expand_as(x)returnoutclassattention_model(nn.Module):# Concatenate a list of tensors along dimensiondef__init__(self,ch256):super().__init__()self.channel_attchannel_att(ch)self.local_attlocal_att(ch)defforward(self,x):input1,input2x[0],x[1]input1self.channel_att(input1)xinput1input2 xself.local_att(x)returnx注册在ultralytics/nn/tasks.py中进行如下操作步骤1fromultralytics.nn.featureFusion.ASFYOLOimportAdd,ScalSeq,Zoom_cat,attention_model步骤2在parse_model(d, ch, verboseTrue)的模块判断链中增加以下分支。elifmisZoom_cat:c2sum(ch[x]forxinf)args[]elifmin{Add,attention_model}:c2ch[f[-1]]ifany(ch[x]!c2forxinf):raiseValueError(f{m.__name__}requires equal input channels)args[c2]elifmisScalSeq:c2make_divisible(min(args[0],max_channels)*width,8)args[[ch[x]forxinf],c2]配置yolo26-ASFYOLO.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. modelyolo26n.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: SSFF TPE CPAMhead:-[-1,1,Conv,[512,1,1]]# 11 P5 projection-[4,1,Conv,[512,1,1]]# 12 P3 projection-[[12,6,11],1,Zoom_cat,[]]# 13 TPE at P4-[-1,2,C3k2,[512,True]]# 14-[-1,1,Conv,[256,1,1]]# 15 P4 projection-[2,1,Conv,[256,1,1]]# 16 P2 projection-[[16,4,15],1,Zoom_cat,[]]# 17 TPE at P3-[-1,2,C3k2,[256,True]]# 18-[-1,1,Conv,[256,3,2]]# 19-[[-1,15],1,Concat,[1]]# 20-[-1,2,C3k2,[512,True]]# 21 P4/16-[-1,1,Conv,[512,3,2]]# 22-[[-1,11],1,Concat,[1]]# 23-[-1,1,C3k2,[1024,True,0.5,True]]# 24 P5/32-[[4,6,10],1,ScalSeq,[256]]# 25 SSFF-[[18,25],1,attention_model,[]]# 26 CPAM at P3/8-[[26,21,24],1,Detect,[nc]]# Detect(P3, P4, P5)实验脚本importwarnings warnings.filterwarnings(ignore)fromultralyticsimportYOLOif__name____main__:# 修改为自己的配置文件地址modelYOLO(./ultralytics/cfg/models/26/yolo26-ASFYOLO.yaml)# 修改为自己的数据集地址model.train(data./ultralytics/cfg/datasets/coco8.yaml,cacheFalse,imgsz640,epochs10,single_clsFalse,# 是否是单类别检测batch8,close_mosaic10,workers0,optimizerMuSGD,# optimizerSGD,ampFalse,projectruns/train,nameASFYOLO,)结果