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