把 MambaOut 塞进 YOLOv11:会有什么样的反应

把 MambaOut 塞进 YOLOv11:会有什么样的反应

yolov11改进系列第15篇

作者:小探

发布时间:2026年6月

关键词:Mamba,yolov11改进

1. 改进介绍

Mamba 最近在 CV 圈很火,也很多人进行了改进尝试,不过把它直接塞进检测器的结果都比较一般,显存和推理速度也不怎么友好。

MambaOut (Yu et al.) 做了一个犀利的消融实验:

论文: https://arxiv.org/abs/2405.07992

代码: https://github.com/yuweihao/MambaOut

把 Mamba 的核心(SSM)去掉,只保留剩余结构(门控 CNN),在 ImageNet 上居然和原版 Mamba 打得有来有回。 既然门控 CNN 块又好又轻,为什么不把它放进 YOLO?

这就是本文尝试做的事情。

2. MambaOut 的核心:GatedCNNBlock

MambaOut 的主体结构拆解出来就一个东西------Gated CNN Block

复制代码
输入 → LayerNorm → FC 扩展 (8/3×) → 三路拆分:
                                          ├── gate (门控信号)
                                          ├── identity (恒等直通)
                                          └── conv  (深度可分离卷积)
                       ↓
              gate × concat(identity, conv)
                       ↓
                  FC 投影回原通道
                       ↓
                  + 残差连接 + DropPath

几个关键设计:

  • 门控机制:从 Mamba 那里借来的,通道扩展后用 GELU 激活 gate 分支,逐元素乘到特征上。这个门控相当于一个输入依赖的特征筛选器。

  • 部分卷积 (partial conv)conv_ratio 控制走深度卷积的通道比例。设为 0.5 时只有一半通道做卷积,剩下直接 bypass,省计算。

  • 纯 CNN 实现:没有 SSM 的状态空间计算,没有 RNN 的时序依赖,全部是标准卷积算子,TensorRT/ONNX 部署零障碍。

3. 怎么塞进 YOLOv11

Ultralytics 的模块注册机制很干净,只需要三步就可以嵌入mambaout模块:

Step 1 --- 写模块

ultralytics/nn/modules/mambaout.py 中实现 GatedCNNBlock(c1, c2, kernel_size=7, conv_ratio=1.0, expansion_ratio=8/3)

python 复制代码
class GatedCNNBlock(nn.Module):
    def __init__(self, c1, c2, kernel_size=7, conv_ratio=1.0,
                 expansion_ratio=8/3, drop_path_rate=0.0):
        super().__init__()
        dim = c2
        hidden = int(expansion_ratio * dim)
        conv_channels = int(conv_ratio * dim)

        self.proj = nn.Conv2d(c1, dim, 1) if c1 != dim else nn.Identity()
        self.norm = LayerNormGeneral((dim, 1, 1), (1, 2, 3))
        self.fc1 = nn.Conv2d(dim, hidden * 2, 1)      # expand
        self.conv = nn.Conv2d(conv_channels, conv_channels,
                              kernel_size, padding=kernel_size//2,
                              groups=conv_channels)     # depthwise
        self.fc2 = nn.Conv2d(hidden, dim, 1)           # project
        self.act = nn.GELU()
        self.drop_path = DropPath(drop_path_rate)
        self.split_indices = (hidden, hidden - conv_channels, conv_channels)

    def forward(self, x):
        x = self.proj(x)
        shortcut = x
        x = self.norm(x)
        g, i, c = torch.split(self.fc1(x), self.split_indices, dim=1)
        c = self.conv(c)
        x = self.fc2(self.act(g) * torch.cat((i, c), dim=1))
        return shortcut + self.drop_path(x)

这里做了一个实用改动:当 c1 ≠ c2 时加一个 1×1 的投影卷积,适配 YOLO 中通道数变化的场景。

Step 2 --- 注册

  • __init__.py 里加 from .mambaout import GatedCNNBlock
  • tasks.py 里加 GatedCNNBlockbase_modules 集合,让它自动享受 width_multiple 缩放

Step 3 --- 写 YAML

yolo11.yaml 里所有的 C3k2 替换成 GatedCNNBlock

yaml 复制代码
backbone:
  - [-1, 1, Conv, [64, 3, 2]]
  - [-1, 1, Conv, [128, 3, 2]]
  - [-1, 1, GatedCNNBlock, [256, 7, 1.0]]    # ← 替代 C3k2
  - [-1, 1, Conv, [256, 3, 2]]
  ...

4. 初测数据

用 YOLOv11n 的 scale 参数跑了一个 epoch 的 smoke test:

指标 YOLOv11n (原版) YOLOv11-MambaOut
参数量 2.6M 3.9M
GFLOPs 6.6 12.7
显存占用 ~1.1G ~1.4G

参数和计算量确实涨了不少------因为 expansion_ratio=8/3 的通道膨胀比较激进,中间层的通道数会跳到 c2 × 2.67

下一步调参方向

  • 降低 expansion_ratio 到 2.0 或 1.5
  • 减小 conv_ratio 到 0.5(只让一半通道走卷积)
  • 只在 backbone 深层(P4/P5)替换,浅层保留 C3k2
  • 搭配 GFLOPs 约束做架构搜索

5. 一键跑通

bash 复制代码
# 用 conda 环境
conda activate yolov11

# 训练(注意设 PYTHONPATH 用本地修改版)
PYTHONPATH=. yolo detect train \
  model=ultralytics/cfg/models/11/yolo11-mambaout.yaml \
  data=coco.yaml \
  epochs=300 imgsz=640

完整代码已开源在 Ultralytics fork 的 ultralytics/nn/modules/mambaout.py 中,可私信获取开源代码。

6. 小结

MambaOut 的思路很好------不要为了追热点而塞 SSM,门控 CNN 本身就是一个很强的基线。把它嵌入 YOLOv11 的技术成本很低(一个文件 + 三处注册),剩下的就是调参找 sweet spot。

相关推荐
如竟没有火炬2 小时前
最大矩阵——单调栈
数据结构·python·线性代数·算法·leetcode·矩阵
阳区欠2 小时前
【LangChain】LLM基础介绍
开发语言·python·langchain
Cosolar2 小时前
保姆级 CrewAI 教程:从零构建多智能体协作系统
人工智能·python·架构
GDAL2 小时前
使用 uv 管理 Python 版本
python·uv·版本
真实的菜2 小时前
Redis 从入门到精通(十二):典型业务场景实战 —— 排行榜、限流器、秒杀系统、Session 共享
数据库·redis·python
cup113 小时前
[开源] Meta Assistant / 告别命令行,我为一堆 Python 脚本做了一个 Windows 任务栏的“家”
windows·python·工具·nuitka·脚本运行
小小编程路3 小时前
Python 还有容器类型互转、进制转换、字符编码转换
开发语言·windows·python
Samooyou4 小时前
RAG项目案例--02在线检索&过滤流水线
人工智能·python·ai·全文检索·检索
动能小子ohhh4 小时前
DocForge平台的设计与开发--文件上传接口的实现
开发语言·人工智能·python·langchain·ocr·fastapi