news 2026/4/25 13:08:58

YOLO26改进 - 卷积Conv | SPConv:基于分割的卷积巧解特征冗余,实现高效特征提取

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
YOLO26改进 - 卷积Conv | SPConv:基于分割的卷积巧解特征冗余,实现高效特征提取

前言

本文介绍了一种基于分割的卷积操作SPConv及其在YOLO26中的结合。传统卷积方法忽视了特征图中的模式冗余,SPConv将输入特征图分割为代表性部分和不确定冗余部分,分别采用k × k k \times kk×k卷积和1 × 1 1 \times 11×1卷积处理,并引入组卷积减少代表性部分冗余,还设计了无参数特征融合模块。SPConv可直接替代原始卷积。我们将其集成进YOLO26,实验表明配备SPConv的网络在准确性、推理时间上优于基准模型,同时减少了浮点运算和参数量。

文章目录: YOLO26改进大全:卷积层、轻量化、注意力机制、损失函数、Backbone、SPPF、Neck、检测头全方位优化汇总

专栏链接: YOLO26改进专栏

文章目录

  • 前言
  • 介绍
    • 摘要
  • 文章链接
  • 基本原理
    • 代表性部分的进一步减少
    • 3.2 无参数特征融合模块
  • 核心代码
  • YOLO26引入代码
  • 注册
    • 步骤1:
    • 步骤2
  • 配置yolo26-SPConv.yaml
  • 实验
    • 脚本
    • 结果

介绍

摘要

许多有效的解决方案已被提出以减少推理加速中模型的冗余。然而,常见的方法大多集中在消除不重要的滤波器或构建高效的操作上,而忽视了特征图中的模式冗余。我们揭示了在一个层内,许多特征图分享相似但不完全相同的模式。然而,确定具有类似模式的特征是否冗余或包含重要细节是困难的。因此,我们提出了一种基于分割的卷积操作,即SPConv,来容忍具有相似模式但需要较少计算的特征。具体来说,我们将输入的特征图分割成代表性部分和不确定冗余部分,从代表性部分中通过相对复杂的计算提取内在信息,而在不确定冗余部分中处理微小的隐藏细节则采用轻量级操作。为了重新校准和融合这两组处理过的特征,我们提出了一个无需参数的特征融合模块。此外,我们的SPConv设计成可以直接替代原始卷积,在使用中非常便捷。实验结果表明,基准测试中配备SPConv的网络在GPU上在准确性和推理时间上始终优于最先进的基准模型,同时大幅减少了浮点运算和参数量。

文章链接

论文地址:论文地址

代码地址:代码地址

基本原理

在现有的滤波器中,如常规卷积、GhostConv、OctConv和HetConv,通常在所有输入通道上执行 ( k \times k ) 卷积操作。然而,这些方法未能解决同一层特征中存在的冗余问题,即使不存在完全相同的两个通道特征,也难以直接剔除冗余。

受此现象启发,研究者提出了一种新的方法,将所有输入特征按比例分为两部分:

  1. 代表性部分:执行k × k k \times kk×k卷积以提取重要信息;
  2. 不确定部分:执行1 × 1 1 \times 11×1卷积以补充隐含细节信息。

这种过程可以用以下公式描述:

SPConv = Representative部分 ⊕ Uncertain部分 \text{SPConv} = \text{Representative部分} \oplus \text{Uncertain部分}SPConv=Representative部分Uncertain部分

代表性部分的进一步减少

在将所有输入通道分成两个主要部分后,代表性部分之间可能存在冗余。为了进一步减少这种冗余,我们引入了组卷积的概念。组卷积可以视作具有稀疏块对角卷积核的普通卷积,其中每个块对应一个通道,并且分组之间没有连接。这一步骤旨在消除代表性部分内部的冗余,尽管可能会牺牲一些跨通道连接的有用信息。为了弥补信息损失,我们在所有代表性通道上应用逐点卷积,将组卷积和逐点卷积的结果通过直接求和融合,从而获得更丰富的特征表示。

3.2 无参数特征融合模块

为了克服分组信息损失带来的影响,我们设计了一个无参数特征融合模块,用于控制不同输入通道特征的有效融合。这一模块与传统的直接求和融合不同,不需要额外的参数,却能提升模型的性能表现。这种设计使得我们的SPConv在性能和效率上都有显著的提升。

通过这些优化,SPConv不仅解决了传统方法中存在的特征冗余和信息损失问题,还有效地提升了模型的整体性能和学习能力。

这些创新的特征提取和融合方法,使得SPConv在图像处理和计算机视觉任务中具有广泛的应用前景。

核心代码

classSPConv_3x3(nn.Module):def__init__(self,inplanes,outplanes,stride=1,ratio=0.5):super(SPConv_3x3,self).__init__()# 计算3x3卷积和1x1卷积的输入输出通道数self.inplanes_3x3=int(inplanes*ratio)self.inplanes_1x1=inplanes-self.inplanes_3x3 self.outplanes_3x3=int(outplanes*ratio)self.outplanes_1x1=outplanes-self.outplanes_3x3 self.outplanes=outplanes self.stride=stride# 定义3x3组卷积和1x1卷积层self.gwc=nn.Conv2d(self.inplanes_3x3,self.outplanes,kernel_size=3,stride=self.stride,padding=1,groups=2,bias=False)self.pwc=nn.Conv2d(self.inplanes_3x3,self.outplanes,kernel_size=1,bias=False)# 定义1x1卷积层self.conv1x1=nn.Conv2d(self.inplanes_1x1,self.outplanes,kernel_size=1)# 定义平均池化层self.avgpool_s2_1=nn.AvgPool2d(kernel_size=2,stride=2)self.avgpool_s2_3=nn.AvgPool2d(kernel_size=2,stride=2)self.avgpool_add_1=nn.AdaptiveAvgPool2d(1)self.avgpool_add_3=nn.AdaptiveAvgPool2d(1)# 定义批归一化层self.bn1=nn.BatchNorm2d(self.outplanes)self.bn2=nn.BatchNorm2d(self.outplanes)self.ratio=ratio self.groups=int(1/self.ratio)defforward(self,x):b,c,_,_=x.size()# 分割输入特征为3x3卷积部分和1x1卷积部分x_3x3=x[:,:int(c*self.ratio),:,:]x_1x1=x[:,int(c*self.ratio):,:,:]# 3x3卷积部分的前向传播out_3x3_gwc=self.gwc(x_3x3)ifself.stride==2:x_3x3=self.avgpool_s2_3(x_3x3)out_3x3_pwc=self.pwc(x_3x3)out_3x3=out_3x3_gwc+out_3x3_pwc out_3x3=self.bn1(out_3x3)out_3x3_ratio=self.avgpool_add_3(out_3x3).squeeze(dim=3).squeeze(dim=2)# 1x1卷积部分的前向传播ifself.stride==2:x_1x1=self.avgpool_s2_1(x_1x1)out_1x1=self.conv1x1(x_1x1)out_1x1=self.bn2(out_1x1)out_1x1_ratio=self.avgpool_add_1(out_1x1).squeeze(dim=3).squeeze(dim=2)# 将3x3和1x1卷积部分的输出按通道进行堆叠,并应用Softmax进行权重融合out_31_ratio=torch.stack((out_3x3_ratio,out_1x1_ratio),2)out_31_ratio=nn.Softmax(dim=2)(out_31_ratio)# 按融合的权重计算最终的输出out=out_1x1*(out_31_ratio[:,:,1].view(b,self.outplanes,1,1).expand_as(out_1x1))\+out_3x3*(out_31_ratio[:,:,0].view(b,self.outplanes,1,1).expand_as(out_3x3))returnout

YOLO26引入代码

在根目录下的ultralytics/nn/目录,新建一个conv目录,然后新建一个以SPConv为文件名的py文件, 把代码拷贝进去。

importtorchimporttorch.nnasnnclassSPConv(nn.Module):def__init__(self,inplanes,outplanes,stride=1,ratio=0.5):super(SPConv,self).__init__()self.inplanes_3x3=int(inplanes*ratio)self.inplanes_1x1=inplanes-self.inplanes_3x3 self.outplanes_3x3=int(outplanes*ratio)self.outplanes_1x1=outplanes-self.outplanes_3x3 self.outplanes=outplanes self.stride=stride self.gwc=nn.Conv2d(self.inplanes_3x3,self.outplanes,kernel_size=3,stride=self.stride,padding=1,groups=2,bias=False)self.pwc=nn.Conv2d(self.inplanes_3x3,self.outplanes,kernel_size=1,bias=False)self.conv1x1=nn.Conv2d(self.inplanes_1x1,self.outplanes,kernel_size=1)self.avgpool_s2_1=nn.AvgPool2d(kernel_size=2,stride=2)self.avgpool_s2_3=nn.AvgPool2d(kernel_size=2,stride=2)self.avgpool_add_1=nn.AdaptiveAvgPool2d(1)self.avgpool_add_3=nn.AdaptiveAvgPool2d(1)self.bn1=nn.BatchNorm2d(self.outplanes)self.bn2=nn.BatchNorm2d(self.outplanes)self.ratio=ratio self.groups=int(1/self.ratio)defforward(self,x):b,c,_,_=x.size()x_3x3=x[:,:int(c*self.ratio),:,:]x_1x1=x[:,int(c*self.ratio):,:,:]out_3x3_gwc=self.gwc(x_3x3)ifself.stride==2:x_3x3=self.avgpool_s2_3(x_3x3)out_3x3_pwc=self.pwc(x_3x3)out_3x3=out_3x3_gwc+out_3x3_pwc out_3x3=self.bn1(out_3x3)out_3x3_ratio=self.avgpool_add_3(out_3x3).squeeze(dim=3).squeeze(dim=2)# use avgpool first to reduce information lostifself.stride==2:x_1x1=self.avgpool_s2_1(x_1x1)out_1x1=self.conv1x1(x_1x1)out_1x1=self.bn2(out_1x1)out_1x1_ratio=self.avgpool_add_1(out_1x1).squeeze(dim=3).squeeze(dim=2)out_31_ratio=torch.stack((out_3x3_ratio,out_1x1_ratio),2)out_31_ratio=nn.Softmax(dim=2)(out_31_ratio)out=out_1x1*(out_31_ratio[:,:,1].view(b,self.outplanes,1,1).expand_as(out_1x1))\+out_3x3*(out_31_ratio[:,:,0].view(b,self.outplanes,1,1).expand_as(out_3x3))returnout

注册

ultralytics/nn/tasks.py中进行如下操作:

步骤1:

fromultralytics.nn.conv.SPConvimportSPConv

步骤2

修改def parse_model(d, ch, verbose=True):

SPConv

配置yolo26-SPConv.yaml

ultralytics/cfg/models/26/yolo26-SPConv.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]# 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,SPConv,[128,2]]# 1-P2/4-[-1,2,C3k2,[256,False,0.25]]-[-1,1,SPConv,[256,2]]# 3-P3/8-[-1,2,C3k2,[512,False,0.25]]-[-1,1,SPConv,[512,2]]# 5-P4/16-[-1,2,C3k2,[512,True]]-[-1,1,SPConv,[1024,2]]# 7-P5/32-[-1,2,C3k2,[1024,True]]-[-1,1,SPPF,[1024,5,3,True]]# 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__':# 修改为自己的配置文件地址model=YOLO('./ultralytics/cfg/models/26/yolo26-SPConv.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='yolo26-SPConv',)

结果

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/21 3:58:54

基于深度学习的车辆追踪系统

目录 深度学习车辆追踪系统概述关键技术组成典型应用场景挑战与优化方向 源码文档获取/同行可拿货,招校园代理 :文章底部获取博主联系方式! 深度学习车辆追踪系统概述 深度学习车辆追踪系统利用卷积神经网络(CNN)、循环神经网络&…

作者头像 李华
网站建设 2026/4/21 8:57:39

基于深度学习的工地安全帽检测系统

目录深度学习的工地安全帽检测系统概述核心技术方法系统实现流程性能优化方向应用效果评估源码文档获取/同行可拿货,招校园代理 :文章底部获取博主联系方式!深度学习的工地安全帽检测系统概述 工地安全帽检测系统利用计算机视觉和深度学习技术&#xff…

作者头像 李华
网站建设 2026/4/20 13:41:37

基于深度学习的坐姿检测系统

目录 深度学习的坐姿检测系统概述核心技术与方法系统实现流程应用场景与优化 源码文档获取/同行可拿货,招校园代理 :文章底部获取博主联系方式! 深度学习的坐姿检测系统概述 坐姿检测系统利用计算机视觉和深度学习技术,实时监测人体坐姿状态…

作者头像 李华
网站建设 2026/4/23 18:44:09

《把脉行业与技术趋势》-102-直流电与交流电的比较:它们不是“优劣之分”,而是物理规律在不同约束下的最优解。如同河流的“直流”奔涌与“交流”潮汐,各循其道,各尽其用。

直流电(DC)与交流电(AC)是电能传输与利用的两种根本范式。它们不是“优劣之分”,而是物理规律在不同约束下的最优解——如同河流的“直流”奔涌与“交流”潮汐,各循其道,各尽其用。以下以科学本…

作者头像 李华
网站建设 2026/4/20 17:06:49

基于用户行为与电影票房混合权重的协同过滤电影推荐平台开题报告

基于用户行为与电影票房混合权重的协同过滤电影推荐平台开题报告 一、选题背景 随着数字媒体技术的飞速发展与流媒体平台的普及,电影内容呈现爆发式增长态势,全球每年产出数万部各类影片,流媒体平台的影片库规模也持续扩容。据行业数据显示&…

作者头像 李华
网站建设 2026/4/23 11:34:31

最值得推荐的5家跨境营销服务商

一、趋势与价值随着跨境电商竞争加剧,企业不再满足于依赖第三方平台获取流量,而是希望通过自建独立站、搭建营销中台来掌握自主流量和数据资产。独立站市场正在迅速增长,预计到2025年中国独立站规模将达5.5万亿元并占跨境电商B2C市场的41%–5…

作者头像 李华