前言
本文介绍了动态混合层(DML),并将相关改进模块集成进YOLO26。DML是SRConvNet核心组件,用于解决轻量级图像超分辨率任务中特征捕捉和通道适应性问题。它通过通道扩展拆分、多尺度动态深度卷积、通道洗牌与融合等步骤,实现多尺度局部信息聚合和通道自适应增强。DML的动态卷积具有内容感知适配和分组共享效率优势,多尺度设计能覆盖全尺度图像细节。我们将DML相关模块集成到YOLO26,注册并配置yaml文件。实验表明,改进后的YOLO26有较好的效果。
文章目录: YOLO26改进大全:卷积层、轻量化、注意力机制、损失函数、Backbone、SPPF、Neck、检测头全方位优化汇总
专栏链接: YOLO26改进专栏
@[TOC]
介绍
最近,视觉变换器(Vision Transformers)在多种任务中展现了相较于卷积神经网络(ConvNet)的优势,包括单图像超分辨率(SISR)。变换器的成功可归因于其不可或缺的多头自注意力(MHSA)机制,该机制能够用较少的参数有效地建模全局连接性。然而,MHSA 的二次复杂度通常会导致巨大的计算成本和内存占用,限制了它们在移动设备上的高效部署,相较于广泛使用的轻量级 ConvNet。在本研究中,我们深入探索了基于 ConvNet 和基于变换器的超分辨率(SR)模型之间的关键区别,从而提出了 SRConvNet,它吸收了这两者的优点,以实现轻量级的 SISR。我们的 SRConvNet 通过两个主要设计来实现:(1)傅里叶调制注意力(FMA),一种类似于 MHSA 的但更加计算和参数效率高的运算符,它执行区域频率-空间调制与聚合,以确保长短期依赖关系的建模;(2)动态混合层(DML),利用混合尺度的深度可分离动态卷积,通过通道分割和重排来探索多尺度上下文信息,从而提升模型的局部性和适应性。结合 FMA 和 DFN,我们可以构建一个纯变换器风格的 ConvNet,在效率与准确性之间权衡,来与最优秀的轻量级 SISR 模型竞争。大量实验表明,SRConvNet 在计算和参数方面能够比最近的最先进的轻量级 SISR 方法实现更高效的超分辨率重建,同时保持相当的性能。代码可在 github.com/lifengcs/SR… 获取。
摘要
文章链接
论文地址:论文地址
代码地址:代码地址
基本原理
动态混合层(Dynamic Mixing Layer, DML)是SRConvNet的核心组件之一,专为解决轻量级图像超分辨率(SISR)任务中局部多尺度特征捕捉与通道适应性增强两大痛点设计,旨在替代传统Vision Transformer(ViT)中局限于线性变换的前馈网络(FFN),同时融合卷积神经网络(ConvNet)的局部建模优势与动态权重的灵活性。
一、设计背景与核心目标
1. 现有方法的局限
传统ViT的FFN仅通过“线性层+激活函数”实现特征变换,无法有效捕捉图像的局部空间依赖;后续改进方法(如卷积FFN、混合尺度卷积FFN)虽引入卷积增强局部性,但存在明显缺陷:
- 单尺度卷积:仅用固定尺寸卷积核(如3×3),难以覆盖不同尺度的图像细节(如边缘、纹理);
- 静态权重:卷积核权重训练后固定,无法根据输入特征的通道差异自适应调整,导致通道间适应性不足。
2. DML的核心目标
针对上述问题,DML的设计聚焦两大核心目标:
- 多尺度局部信息聚合:通过多尺寸动态卷积,同时捕捉小尺度精细纹理与大尺度结构特征;
- 通道自适应增强:生成动态卷积权重,根据不同通道的特征分布调整核参数,提升模型对复杂场景的适配能力。
二、整体架构与核心流程
DML的架构遵循“通道扩展-拆分-多尺度动态卷积-通道混合-融合”的逻辑,具体流程如图2c(文档附图)所示,输入为FMA输出的特征(为空间尺寸,为通道数),输出为融合多尺度局部特征的,关键步骤如下:
1. 通道扩展与拆分
- 通道扩展:输入特征先经过层归一化(Layer Norm) 消除通道间分布差异,再通过1×1卷积将通道数从扩展至,为后续多分支学习提供基础;
- 通道拆分:将扩展后的通道特征拆分为两个独立分支和,每个分支负责单一尺度的局部特征提取,避免不同尺度特征相互干扰。
2. 多尺度动态深度卷积(核心步骤)
两个分支分别采用5×5和7×7动态深度卷积(Dynamic Depthwise Convolution),通过“全局特征感知-动态权重生成-局部特征聚合”实现自适应多尺度学习,以(5×5卷积分支)为例:
(1)动态权重生成机制
- 全局特征压缩:对执行全局平均池化(GAP),将的空间维度压缩为1×1,得到通道级特征向量(维度),捕捉全局通道统计信息;
- 线性投影生成权重:通过两层线性投影转换特征向量,生成动态卷积核:
- 第一层线性层(带GELU激活):将通道数从降至(为分组数),减少计算量;
- 第二层线性层(带Sigmoid激活):将维度恢复并重塑为动态滤波器(为卷积核大小,如5或7;为核参数数量)。 文档中明确和,分别对应小尺度细节与大尺度结构的捕捉。
(2)动态卷积计算
动态卷积核与分支特征按“分组-局部窗口”方式进行元素乘累加,公式如下: 其中:
- (如时),表示卷积窗口的半宽;
- 为位置处卷积窗口内坐标的动态权重;
- 为元素乘,权重与对应位置的特征相乘后累加,得到聚合后的局部特征(5×5分支)和(7×7分支)。
3. 通道洗牌与特征融合
- 通道洗牌(Channel Shuffling):参考ShuffleNet V2的设计,将和的通道随机重组,打破分支间的通道独立性,实现跨尺度特征的高效交互,避免通道冗余;
- 特征融合:通过1×1卷积将洗牌后的特征通道数从压缩回,整合多尺度信息,输出最终特征。
三、关键机制的优势
1. 动态深度卷积:超越静态卷积的适应性
与传统静态卷积(如MixCFN的固定核)相比,DML的动态卷积具有两大优势:
- 内容感知适配:动态权重由输入特征的全局统计信息生成,可根据图像内容(如平滑区域、纹理区域)调整核参数——例如,纹理密集区域的权重更关注细节保留,平滑区域的权重更侧重噪声抑制;
- 分组共享效率:动态权重按通道分组(组)共享,每个组内的个通道使用同一组核参数,在保证适应性的同时将计算量降低至静态深度卷积的,符合轻量级设计目标。
2. 多尺度设计:覆盖全尺度图像细节
通过5×5和7×7两个分支的互补:
- 5×5卷积:捕捉小尺度细节(如文本边缘、纹理颗粒);
- 7×7卷积:捕捉大尺度结构(如物体轮廓、场景布局);
- 通道洗牌后,两种尺度特征深度融合,避免单尺度卷积“顾此失彼”的问题,尤其适合SISR中“低分辨率图像细节恢复”的核心需求。
3. 通道拆分与洗牌:高效特征交互
- 拆分优势:将特征拆分为两个分支,使每个分支专注于单一尺度学习,减少不同尺度特征的干扰,提升学习效率;
- 洗牌优势:打破分支间的通道隔离,让5×5分支的细节特征与7×7分支的结构特征在通道维度充分混合,避免“多分支但特征割裂”的问题。
核心代码
class MixFFN(nn.Module):
def __init__(self, dim, num_kernels=16):
super().__init__()
self.proj_in = nn.Conv2d(dim, dim * 2, 1)
self.conv1 = DyConv(dim, kernel_size=5, groups=dim, num_kernels=num_kernels)
self.conv2 = DyConv(dim, kernel_size=7, groups=dim, num_kernels=num_kernels)
self.proj_out = nn.Conv2d(dim * 2, dim, 1)
self.norm = LayerNorm(dim, eps=1e-6, data_format="channels_first")
self.act = nn.GELU()
def forward(self, x):
shortcut = x
x = self.norm(x)
x = self.act(self.proj_in(x))
x1, x2 = torch.chunk(x, 2, dim=1)
x1 = self.act(self.conv1(x1)).unsqueeze(dim=2)
x2 = self.act(self.conv2(x2)).unsqueeze(dim=2)
x = torch.cat([x1, x2], dim=2)
x = rearrange(x, 'b c g h w -> b (c g) h w')
x = self.proj_out(x)
x = x + shortcut
return x
实验
脚本
import warnings
warnings.filterwarnings('ignore')
from ultralytics import YOLO
if __name__ == '__main__':
# 修改为自己的配置文件地址
model = YOLO('./ultralytics/cfg/models/26/yolo26-C2PSA_DML.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-C2PSA_DML',
)
结果
