把 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 里加 GatedCNNBlock 到 base_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。

相关推荐
ragnwang3 小时前
Notes: Python pybind11 import C++ module
开发语言·c++·python
王中阳Go3 小时前
后端转 Agent 岗面试怎么答:8 个高频问题与应答口径
人工智能·后端·python·大语言模型
weixin_307779134 小时前
RAG 面试陷阱——混合检索并非无条件优越:一个条件反转实验
人工智能·python·面试·职场和发展
云和数据.ChenGuang5 小时前
深入解析 Python 的 dir():从用法到 CPython 源码实现
开发语言·人工智能·python·langchain
荣码7 小时前
长上下文与大文档处理:200页PDF怎么喂给AI,我踩了4个坑
java·python
databook8 小时前
Pandas 与 Polars:语法、性能和资源占用方面的对比
python·数据分析·pandas
威哥爱编程8 小时前
Python 智能体开发实战 10:本地跑得好好的,一并发就崩?把它做成一个能上线的服务
python·agent
威哥爱编程8 小时前
Python 智能体开发实战 09:改了提示词,到底是变好还是变坏?搭一套能打分的离线评测
python·agent
meiying88389 小时前
多快递公司快递单号批量查询接口怎么对接?Python 聚合查询实现
java·大数据·python
Hello_Pyhx9 小时前
Deep-Live-Cam 源码配置思路:环境、模型与执行后端分开排查
python