2026/2/14 22:02:17
网站建设
项目流程
湖南企业网站,中国网库做网站,雅虎网站提交,四川省建行网站前言
本文介绍了焦点调制网络#xff08;FocalNets#xff09;及其在YOLO26中的结合应用。FocalNets完全用焦点调制模块替代自注意力#xff0c;该模块由焦点上下文化、门控聚合和逐元素仿射变换组成#xff0c;能有效建模视觉中的标记交互。它通过局部特征聚焦、全局信息…前言本文介绍了焦点调制网络FocalNets及其在YOLO26中的结合应用。FocalNets完全用焦点调制模块替代自注意力该模块由焦点上下文化、门控聚合和逐元素仿射变换组成能有效建模视觉中的标记交互。它通过局部特征聚焦、全局信息调制和多尺度处理增强模型表达能力。我们将FocalModulation模块集成进YOLO26。文章目录 YOLO26改进大全卷积层、轻量化、注意力机制、损失函数、Backbone、SPPF、Neck、检测头全方位优化汇总专栏链接: YOLO26改进专栏文章目录前言介绍摘要文章链接基本原理具体实现核心代码YOLO26引入代码注册步骤1:步骤2配置yolo26-FocalModulation.yaml实验脚本结果介绍摘要本研究提出焦点调制网络FocalNets该网络采用焦点调制模块完全替代自注意力SA机制用于视觉任务中的标记交互建模。焦点调制模块由三个核心组件构成i焦点上下文化组件通过深度卷积层序列实现从短距离到长距离的视觉上下文编码ii门控聚合组件选择性将上下文信息聚合至每个查询标记的调制器中iii逐元素仿射变换组件将调制器注入查询标记。大量实验验证表明FocalNets展现出卓越的可解释性特征并在图像分类、目标检测及分割任务中以相近计算成本超越了当前最先进的SA模型如Swin和Focal Transformers。具体而言FocalNets小型与基础版本在ImageNet-1K数据集上分别实现了82.3%和83.9%的top-1准确率在ImageNet-22K数据集以224×224分辨率预训练后微调至224×224和384×384分辨率时分别达到86.5%和87.3%的top-1准确率。在目标检测任务中基于Mask R-CNN框架的FocalNet基础版本以1×训练计划超越Swin对照组2.1个百分点且已超过采用3×训练计划的Swin模型49.0对48.5在语义分割任务中基于UPerNet框架的FocalNet基础版本在单尺度测试下超越Swin模型2.4个百分点多尺度测试下同样表现优异50.5对49.7。进一步地采用大型FocalNet与Mask2former组合在ADE20K语义分割任务中达到58.5 mIoU在COCO全景分割任务中获得57.9 PQ采用巨型FocalNet与DINO组合在COCO minival和test-dev数据集上分别实现64.3和64.4 mAP显著超越Swinv2-G和BEIT-3等基于注意力机制的大型模型。这些系统性实验结果充分证明焦点调制机制在视觉计算领域具有重要应用价值与发展潜力。文章链接论文地址论文地址代码地址代码地址基本原理Focal Modulation机制旨在结合CNNs和自注意力机制的优点通过在不同的空间尺度上聚焦Focal和调制Modulation特征来增强模型的表达能力。具体来说Focal Modulation包含以下几个关键组件局部特征聚焦Local Focalization通过聚焦机制在局部区域内提取特征类似于卷积操作。这有助于捕捉局部模式和细节。全局信息调制Global Modulation在全局范围内对特征进行调制类似于自注意力机制。这有助于整合全局上下文信息使模型能够理解更广泛的特征关系。多尺度处理Multi-Scale Processing通过在不同尺度上进行特征提取和调制Focal Modulation能够同时处理图像中的细节和整体结构。这种多尺度特性使得模型在处理复杂场景时更具鲁棒性。具体实现Focal Modulation的具体实现可以通过以下步骤进行特征提取使用卷积层或其他局部运算层提取初始特征。局部聚焦对提取的特征进行局部聚焦操作可以采用池化Pooling或注意力机制来实现。全局调制利用全局上下文信息对局部聚焦后的特征进行调制。这可以通过全局注意力层或其他全局运算层实现。多尺度融合将不同尺度上的特征进行融合通过跳跃连接Skip Connections或金字塔结构Pyramid Structure来整合多尺度信息。核心代码classFocalModulation(nn.Module): 焦点调制模块 Args: dim (int): 输入通道数。 proj_drop (float, optional): 输出的dropout比率。默认值0.0 focal_level (int): 焦点层级的数量 focal_window (int): 焦点层级1的焦点窗口大小 focal_factor (int, default2): 增加焦点窗口的步长 use_postln (bool, defaultFalse): 是否使用后调制层归一化 def__init__(self,dim,proj_drop0.,focal_level2,focal_window7,focal_factor2,use_postlnFalse):super().__init__()self.dimdim# 焦点调制模块的特定参数self.focal_levelfocal_level self.focal_windowfocal_window self.focal_factorfocal_factor self.use_postlnuse_postln# 线性层输出维度为2*dim(焦点层级数1)self.fnn.Linear(dim,2*dim(self.focal_level1),biasTrue)# 1x1卷积层输入和输出通道数均为dimself.hnn.Conv2d(dim,dim,kernel_size1,stride1,padding0,groups1,biasTrue)# GELU激活函数self.actnn.GELU()# 线性层输入和输出维度均为dimself.projnn.Linear(dim,dim)# Dropout层使用给定的丢弃比率self.proj_dropnn.Dropout(proj_drop)# 存储焦点层的列表self.focal_layersnn.ModuleList()ifself.use_postln:# 如果使用后调制层归一化定义层归一化层self.lnnn.LayerNorm(dim)# 构建每个焦点层forkinrange(self.focal_level):# 根据层级计算卷积核大小kernel_sizeself.focal_factor*kself.focal_window self.focal_layers.append(nn.Sequential(nn.Conv2d(dim,dim,kernel_sizekernel_size,stride1,groupsdim,paddingkernel_size//2,biasFalse),nn.GELU(),))defforward(self,x): 前向传播函数 Args: x: 形状为(B, H, W, C)的输入特征 B,nH,nW,Cx.shape# 通过线性层f得到形状为(B, H, W, 2*C 焦点层级数1)的张量xself.f(x)# 将通道维度移动到第二维并转换为连续内存布局xx.permute(0,3,1,2).contiguous()# 将张量x拆分为查询q、上下文ctx和门控信号gatesq,ctx,gatestorch.split(x,(C,C,self.focal_level1),1)ctx_all0# 处理每个焦点层级forlinrange(self.focal_level):ctxself.focal_layers[l](ctx)ctx_allctx_allctx*gates[:,l:l1]# 计算全局上下文并应用激活函数ctx_globalself.act(ctx.mean(2,keepdimTrue).mean(3,keepdimTrue))ctx_allctx_allctx_global*gates[:,self.focal_level:]# 查询q与处理后的上下文相乘x_outq*self.h(ctx_all)# 将通道维度移动到最后并转换为连续内存布局x_outx_out.permute(0,2,3,1).contiguous()# 如果使用后调制层归一化应用层归一化ifself.use_postln:x_outself.ln(x_out)# 通过线性层和Dropout层x_outself.proj(x_out)x_outself.proj_drop(x_out)returnx_outYOLO26引入代码在根目录下的ultralytics/nn/目录新建一个otherModules目录然后新建一个以FocalModulation为文件名的py文件 把代码拷贝进去。importtorchimporttorch.nnasnnclassFocalModulation(nn.Module):def__init__(self,dim,focal_window3,focal_level2,focal_factor2,biasTrue,proj_drop0.,use_postln_in_modulationFalse,normalize_modulatorFalse):super().__init__()self.dimdim self.focal_windowfocal_window self.focal_levelfocal_level self.focal_factorfocal_factor self.use_postln_in_modulationuse_postln_in_modulation self.normalize_modulatornormalize_modulator self.f_linearnn.Conv2d(dim,2*dim(self.focal_level1),kernel_size1,biasbias)self.hnn.Conv2d(dim,dim,kernel_size1,stride1,biasbias)self.actnn.GELU()self.projnn.Conv2d(dim,dim,kernel_size1)self.proj_dropnn.Dropout(proj_drop)self.focal_layersnn.ModuleList()self.kernel_sizes[]forkinrange(self.focal_level):kernel_sizeself.focal_factor*kself.focal_window self.focal_layers.append(nn.Sequential(nn.Conv2d(dim,dim,kernel_sizekernel_size,stride1,groupsdim,paddingkernel_size//2,biasFalse),nn.GELU(),))self.kernel_sizes.append(kernel_size)ifself.use_postln_in_modulation:self.lnnn.LayerNorm(dim)defforward(self,x): Args: x: input features with shape of (B, H, W, C) Cx.shape[1]# pre linear projectionxself.f_linear(x).contiguous()q,ctx,gatestorch.split(x,(C,C,self.focal_level1),1)# context aggreationctx_all0.0forlinrange(self.focal_level):ctxself.focal_layers[l](ctx)ctx_allctx_allctx*gates[:,l:l1]ctx_globalself.act(ctx.mean(2,keepdimTrue).mean(3,keepdimTrue))ctx_allctx_allctx_global*gates[:,self.focal_level:]# normalize contextifself.normalize_modulator:ctx_allctx_all/(self.focal_level1)# focal modulationx_outq*self.h(ctx_all)x_outx_out.contiguous()ifself.use_postln_in_modulation:x_outself.ln(x_out)# post linear porjectionx_outself.proj(x_out)x_outself.proj_drop(x_out)returnx_out注册在ultralytics/nn/tasks.py中进行如下操作步骤1:fromultralytics.nn.otherModules.FocalModulationimportFocalModulation步骤2修改def parse_model(d, ch, verboseTrue):elifmin{FocalModulation}:args[ch[f],*args]配置yolo26-FocalModulation.yamlultralytics/cfg/models/26/yolo26-FocalModulation.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]# summary: 260 layers, 2,572,280 parameters, 2,572,280 gradients, 6.1 GFLOPss:[0.50,0.50,1024]# summary: 260 layers, 10,009,784 parameters, 10,009,784 gradients, 22.8 GFLOPsm:[0.50,1.00,512]# summary: 280 layers, 21,896,248 parameters, 21,896,248 gradients, 75.4 GFLOPsl:[1.00,1.00,512]# summary: 392 layers, 26,299,704 parameters, 26,299,704 gradients, 93.8 GFLOPsx:[1.00,1.50,512]# summary: 392 layers, 58,993,368 parameters, 58,993,368 gradients, 209.5 GFLOPs# 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,FocalModulation,[]]# 9-[-1,2,C2PSA,[1024]]# 10# YOLO26n headhead:-[-1,1,nn.Upsample,[None,2,nearest]]-[[-1,6],1,Concat,[1]]# cat backbone P4-[-1,2,C3k2,[512,True]]# 13-[-1,1,nn.Upsample,[None,2,nearest]]-[[-1,4],1,Concat,[1]]# cat backbone P3-[-1,2,C3k2,[256,True]]# 16 (P3/8-small)-[-1,1,Conv,[256,3,2]]-[[-1,13],1,Concat,[1]]# cat head P4-[-1,2,C3k2,[512,True]]# 19 (P4/16-medium)-[-1,1,Conv,[512,3,2]]-[[-1,10],1,Concat,[1]]# cat head P5-[-1,1,C3k2,[1024,True,0.5,True]]# 22 (P5/32-large)-[[16,19,22],1,Detect,[nc]]# Detect(P3, P4, P5)实验脚本importwarnings warnings.filterwarnings(ignore)fromultralyticsimportYOLOif__name____main__:# 修改为自己的配置文件地址modelYOLO(./ultralytics/cfg/models/26/yolo26-FocalModulation.yaml)# 修改为自己的数据集地址model.train(data./ultralytics/cfg/datasets/coco8.yaml,cacheFalse,imgsz640,epochs10,single_clsFalse,# 是否是单类别检测batch8,close_mosaic10,workers0,optimizerMuSGD,# optimizerSGD,ampFalse,projectruns/train,nameyolo26-FocalModulation,)结果