ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

YOLO26改进:LSB模块与局部特征连续传输详解

YOLO26改进:LSB模块与局部特征连续传输详解 如果你想在 YOLO26 上做一次改进大概率会先去搜“即插即用模块”。然后就会看到一堆取名很唬人的模块比如 LSB。听起来只要把它塞进网络精度就能涨几个点。但我建议你先别急着改代码。因为真正的难点从来不是“插进去”而是搞明白这个模块到底改变了网络里的哪种特征流动方式。LSB 模块出自 CVPR 2025 的 nnWNet核心表达是“局部特征连续传输”。今天我想结合 YOLO26 的常见改进路径拆一下这个模块解决的问题、接入方法以及从训练到部署最容易踩的坑。先说判断即插即用是表象局部特征连续传输才是它真正改变的东西落地时最难的不是加上一个模块而是选对位置、训练策略并且能验证它确实有效。1. 先搞清楚 YOLO26 改进里的“即插即用”到底解决什么问题1.1 为什么大家都在找即插即用模块YOLO 系列发展到现在主框架已经非常稳定。YOLO26 延续了“骨干提取特征 颈部融合多尺度特征 检测头输出”的经典结构。想在这么成熟的框架上做改进最省力的方式就是引入外部模块。这也是为什么网上会有大量“YOLO 注意力机制”“YOLO 轻量卷积”“YOLO Transformer 块”之类的改进方案。但这里有一个容易被忽略的事实模块本身好不等于改动后的网络就好。多一个模块会改变特征图的尺度、通道数、梯度流动路径还会增加计算量。如果只是把模块“缝”进去而不理解它为什么有效最终大概率会因为训练不收敛、精度不涨、部署变慢而放弃。LSB 模块之所以值得关注是因为它不是简单地增加一层卷积或一个注意力算子而是从特征传输方式上做文章。“局部特征连续传输”这个名字的重点不是“模块”而是“传输”。1.2 拆解 LSB 模块局部、特征、连续传输从命名来看LSB 可以拆成三个词局部Local处理对象是特征图上的局部区域而不是整张图的全局关系。局部感受野意味着它更关注边缘、纹理、小目标这些细节信息。特征Feature它作用在深度特征图上不是输入图像也不是检测结果。连续传输Continuous Transfer这是最核心的部分。它意味着特征在层与层之间不是一次跳变而是在一个相对连续的路径上逐步传递。放到 YOLO26 里理解就是当特征从浅层传到深层时我们希望局部细节不要那么快被“稀释”。普通卷积堆叠后特征图分辨率会降低语义信息变强但小目标的边缘和纹理往往会消失。LSB 这类模块要做的就是通过连续传输让局部特征在深层仍然保留足够的存在感。1.3 表层功能与底层逻辑并不是多了一个算子很多人看到“即插即用”会以为这是一个黑盒输入一个特征图输出一个特征图中间做了某种增强。但真正起作用的是它改变了网络内部的“信息流”。从工程角度看任何模块都必须在有限的计算开销下提升特征表达。如果只是把输入特征乘以一个可学习的权重并加回去那是残差连接不是连续传输。连续传输更像是一种递进式的特征融合前一步输出的一部分会成为后一步的输入局部信息在传递路径上被反复引用而不是经过一次大跨度连接就结束。这种设计对 YOLO26 的启发在于网络加深后梯度回传路径会变长浅层参数更新会变困难。通过连续传输梯度可以沿着多条路径流回浅层训练更容易收敛细节信息也更容易保留下来。注意这里的“连续传输”是对模块设计意图的一种工程解读。实际论文里的具体实现可能更复杂但理解成“让局部特征不要在中途断掉”方向不会偏。2. LSB 模块的机制拆解局部特征连续传输意味着什么2.1 检测网络里的“细节断层”问题目标检测网络通常都有特征金字塔。YOLO26 也一样它会把不同尺度特征图融合起来用来检测大小不同的目标。问题在于特征的生成过程天然存在一个矛盾浅层特征图分辨率高细节多但语义信息弱。深层特征图语义强但分辨率低细节少。常规 CNN 在逐层下采样时每经过一次池化或 stride 为 2 的卷积分辨率就降一半。小目标在浅层已经很小到了深层可能一个目标只剩几个像素。如果网络没有专门对这类信息做保护检测头能用的实际上已经是被污染过的特征。LSB 模块要解决的就是这个“细节断层”。它不是让网络变深而是让浅层细节有更多机会传到高层。2.2 “连续传输”和普通跨层连接有什么不同ResNet 里的残差连接以及 FPN 里的 top-down 融合本质上都是跨层连接。它们的作用是把某一层的信息跳跃式地送到后面的层。而 LSB 强调“连续传输”我更倾向于把它理解成一种更细粒度的连接方式。普通跨层连接像坐直达车从 A 点直接到 D 点中间只做一次相加或拼接。连续传输则更像是分段接力A → B → C → D每一段都保留前面的特征并在当前阶段做一次特征更新。这么做的好处有三个梯度回传路径更短。因为每一段都有残差或类似机制梯度不容易消失。局部特征被反复增强。小目标的边缘信息在每一段都被重新激活而不是被后续卷积“抹平”。网络容量增加但参数不一定爆炸。因为连续传输可以共享部分计算不一定要在每个阶段引入大量新参数。2.3 从 nnWNet 到 YOLO26局部连续传输为什么值得关注nnWNet 是 CVPR 2025 的工作它的整体设计我们不去强行复述因为只看标题很难还原完整论文。但有一点是明确的能在顶会中出现的模块通常不是简单堆参数而是在某种具体问题上有针对性设计。LSB 模块从 nnWNet 中出来被拿来改进 YOLO26本质上是把一个适合连续特征传递的模块迁移到目标检测任务中。它能不能涨点取决于 YOLO26 原本的瓶颈是不是在“局部特征传输”上。如果当前模型已经能检测大目标但小目标、遮挡目标、低光环境下的目标经常漏检那说明局部细节特征确实不够。这时候引入 LSB 类模块是合理的改进方向。如果当前模型的问题是整体精度已经很高但某个类别数据量过少那加模块未必能解决反而可能过拟合。2.4 为什么小目标和低光场景更容易受益低光环境下图像亮度低、对比度低目标边缘往往很模糊。网络必须依赖有限的梯度变化来判断目标是否存在。如果特征图传到深层时这些微弱的边缘信息已经被过滤掉检测头就相当于在“盲猜”。局部特征连续传输的思路相当于给网络加了一条“细节优先”通道。它不是简单拉高对比度而是在特征层面让局部响应保持激活。这样一来小目标微弱但关键的边缘、角点、纹理信息能一路传送到检测头。这也是为什么很多 YOLO 改进都愿意叠加类似模块的原因它们针对的是同一个痛点——深层网络对局部细节的不敏感。提醒低光环境下除了网络结构输入图像的质量和预处理也非常重要。模块解决的是特征层的问题如果输入本身噪点过重再强的特征传输也很难完全救回来。3. 在 YOLO26 中接入 LSB 模块一个可执行的接入流程3.1 环境准备和源码结构确认在动手改代码之前先把环境确认好。YOLO26 通常基于 ultralytics 或类似 YOLO 工程结构需要确认几件事Python 版本和 PyTorch 版本是否匹配。是否安装了 ultralytics 源码包或者是直接 clone 的源码。是否已经用自己的数据集跑通基线。建议在独立虚拟环境中进行避免把系统环境搞坏。常见命令conda create -n yolo26 python3.10 conda activate yolo26 pip install ultralytics pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118这里不看 CUDA 版本只提醒一句先跑通官方自带的数据集再进入改进流程。连原版 YOLO26 都跑不通的环境加模块只会更难排查。3.2 用示例代码定义一个 LSB 模块因为我们不知道论文的最终开源实现长什么样下面给的是一个“局部特征连续传输”的示例结构用来演示模块接入流程不是 LSB 的论文复现。import torch import torch.nn as nn class LSB(nn.Module): def __init__(self, c1, c2, kernel_size3): super().__init__() self.conv1 nn.Conv2d(c1, c2, kernel_size, paddingkernel_size // 2) self.conv2 nn.Conv2d(c2, c2, kernel_size, paddingkernel_size // 2) self.act nn.SiLU() self.shortcut nn.Identity() if c1 c2 else nn.Conv2d(c1, c2, 1) def forward(self, x): identity self.shortcut(x) # 第一步局部特征激活 out self.act(self.conv1(x)) # 第二步连续传输把当前输出和原始输入融合 out self.act(self.conv2(out) identity) return out这个示例的核心是“连续传输”的体现第一次卷积激活局部特征第二次卷积在当前特征图上继续做局部变换同时通过 shortcut 把原始输入传回来。这样信息在传递过程中没有中断。3.3 在模块注册表中登记并改 YAML如果用的是 ultralytics 结构通常需要做两步在ultralytics/nn/modules.py或ultralytics/nn/extra_modules.py中注册 LSB 类并加到__all__里。在任务配置 YAML 的backbone或head部分把模块名写进去。示例 YAML 片段backbone: - [-1, 1, Conv, [64, 3, 2]] - [-1, 1, Conv, [128, 3, 2]] - [-1, 3, C2f, [128, True]] - [-1, 1, LSB, [128]] # 自定义模块插入位置 - [-1, 1, Conv, [256, 3, 2]]注意YAML 中的参数必须和模块构造函数对齐。如果__init__接收c1, c2, kernel_size那么 YAML 里需要传通道数等参数。如果不小心写成四参数会直接报错。3.4 推荐的接入位置骨干、颈部、检测头前接入位置直接影响模块是否有效。我一般会这样选接入位置目的风险骨干输出前让深层特征保留更多局部细节可能增加骨干计算量颈部上采样前增强低分辨率特征的局部信息需要处理好通道数匹配检测头前让最终检测层直接拿到增强特征影响最直接但改动量最大从工程经验看优先尝试“骨干输出前”和“颈部融合处”。这两个位置改动小影响范围可控。检测头前虽然效果可能更明显但需要小心结构匹配一旦出错整个输出维度都会乱。3.5 最小可运行验证先用小数据集跑通不要上来就用自己的全量数据集训练。先用coco8这种几十张图片的小数据集验证模块能不能被正确加载、前向传播有没有报错、损失能不能下降。from ultralytics import YOLO model YOLO(yolo26n-lsb.yaml) model.train(datacoco8.yaml, epochs50, imgsz640, device0)这里的关键不是训练出一个高精度模型而是确认流程是通的。如果小数据集上能正常跑通再换到大数据集。如果小数据集上就出现 NaN、显存溢出或损失不下降那问题往往出在模块实现而不是数据。建议在写模块时先打印每一层的输入输出 shape确认和 YAML 配置完全一致。形状不匹配的问题在 YOLO 改进里是最常见的。4. 训练 YOLO26 LSB 模块时的关键参数和调优思路4.1 先跑小模型、小数据集验证收敛当你给 YOLO26 加了一个新模块最怕的是什么不是精度不涨而是训练根本跑不稳。损失曲线震荡、梯度爆炸、显存溢出这些问题会消耗大量时间。正确做法是先做一个“最小实验”使用 YOLO26n 这种轻量版本。使用 100 到 500 张图片的小数据集。训练 30 到 50 轮。学习率保持默认或稍微降低比如lr00.001。这一步不是看最终 mAP而是看有没有明显 bug。如果小实验都没问题再回到完整数据。4.2 分阶段训练冻结骨干、低学习率、逐步放开加了新模块后建议不要一开始就全量训练。因为随机初始化的模块可能会在早期破坏预训练权重已经学好的特征表达。更稳妥的路径是冻结骨干只训练模块所在的层和后续检测头。这样可以快速让模块“适应”现有特征。解冻部分骨干使用较低学习率。让骨干微调但不要被模块的随机梯度带偏。最后再全局训练使用余弦退火或适当的数据增强。在 ultralytics 中可以通过freeze参数来控制model.train(datacustom.yaml, freeze10, lr00.001, epochs100)freeze10表示冻结前 10 层具体层数要看网络结构。这样做的好处是训练更稳定坏处是总训练时间会变长。4.3 常见训练问题排查顺序如果训练出现问题不要一上来就改代码。按照下面的顺序排查现象优先检查可能原因loss 为 NaN输入、学习率、模块有没有除零学习率过高、特征值爆炸loss 不下降小数据集、预训练权重、模块位置模块没有参与梯度流动显存溢出批量大小、图像尺寸、模块参数模块引入了过大中间张量精度低于基线接入位置、是否分阶段训练模块破坏原有特征分布其中最容易忽略的是“模块没有参与梯度流动”。如果模块在 YAML 中定义正确但没有被真正用在主干路径上损失会下降但因为模块没有影响最终输出所以精度不会变化。这种问题单看 loss 曲线很难发现需要对比“带模块”和“不带模块”的验证集结果。4.4 对比实验设计保证结论可解释很多改进方案最后被否定不是因为模块没用而是对比实验做得不严谨。YOLO26 本身对随机种子、数据增强、训练轮数都很敏感。为了让结论可信至少要满足这几个条件同一份训练集和验证集。相同的图像尺寸、批量大小、学习率、数据增强策略。模块是唯一变量。训练多次或至少观察稳定趋势。如果带模块的实验只在某一轮跑出高 mAP而换一次随机种子就下降那说明模块本身的稳定性存疑。更强的做法是画几条损失曲线和验证曲线不做单点比较而是比较整体趋势。5. 部署阶段容易忽略的三件事5.1 导出 ONNX/TensorRT 时自定义模块可能踩的坑训练完成后如果要在工程里用都会走导出流程。YOLO26 通常可以导出 ONNX、TensorRT 等格式。但自定义模块一旦包含不可 trace 的操作导出就会失败。建议在定义模块时避免使用复杂控制流和动态 Python 运算。比如尽量不要在 forward 里写if x.shape[2] 32这样的逻辑。尽量只使用nn.Conv2d、nn.BatchNorm2d、nn.SiLU、torch.add这些可 trace 操作。导出命令示例yolo export modelruns/train/exp/weights/best.pt formatonnx imgsz640导出后可以用onnxruntime或者trtexec简单验证一下输入输出是否正确。如果导出时报错关键在自定义模块就先回到模块实现里把不支持的算子替换掉。5.2 计算量变化和推理速度评估模块不是免费的。局部特征连续传输虽然能改善细节保留但如果每一层都额外接一个 LSB推理速度很可能下降明显。在部署前至少要看三个指标参数量Parameters计算量FLOPs单张图片推理延迟ms可以这样对比模型Params (M)GFLOPs推理延迟 (ms)YOLO26n 原版基线基线基线YOLO26n LSB增加量增加量增加量如果增加量在可接受范围内再考虑部署。如果增加量过大建议减少模块数量或者只在检测头前插入一个 LSB而不是每个 stage 都加。5.3 低光环境部署预处理和后处理配合如果你想用改进后的模型做低光环境检测不能只改网络结构。输入图像本身对比度低、噪声大预处理和后处理同样重要。常见做法是将图像从 BGR 转 RGB。做直方图均衡化或 Retinex 增强。归一化时采用适合暗光数据集的均值方差。后处理阶段适当降低置信度阈值因为低光目标响应通常较弱。LSB 模块提升的是特征层的表达能力但最终 NMS 阈值、输入大小、灰度范围都会影响检测结果。不要指望改一个模块就解决全部低光问题。6. 适用边界和长期建议6.1 适合什么场景LSB 这类局部特征连续传输模块更适合这样的场景模型已经跑通但小目标检测效果差。低光、雾天、遮挡环境下漏检率偏高。有足够的数据量和训练资源愿意做分阶段训练。对推理速度有一定冗余可以接受少量延迟增加。如果你正被这些问题困扰把 LSB 放到 YOLO26 里做实验是合理的探索方向。6.2 不适合什么场景它也有明显的边界。如果满足下面任意一条我会建议你谨慎项目已经接近上线推理硬件非常紧张多 1ms 延迟都不能接受。数据集很小过拟合风险大。还没有跑通 YOLO26 原版基线就想先加模块。只看别人说“即插即用”没有时间和精力做对比实验。尤其最后一条最容易把时间浪费在没有结论的调参上。6.3 一个可复用的改进流程把这次经验沉淀下来可以形成一个通用的 YOLO 改进流程基线复现用官方默认配置复现 YOLO26保存权重和指标。小实验验证用小数据集验证模块能跑通、不报错、损失下降。模块接入从骨干输出、颈部、检测头前三个位置选一个开始保留原结构作为对照组。分阶段训练先冻结骨干再放开避免模块随机初始化破坏预训练特征。对比分析在相同超参下比较 mAP、loss、推理速度。部署验证导出 ONNX/TensorRT在目标平台上确认精度和速度。按这个流程走能避免“改了模块但不知道有没有用”的尴尬。6.4 从“插上就有效”到“插对才有效”最后想多说一句。YOLO 系列的改进现在已经进入一个更细的阶段。不是随便加一个注意力模块就能涨点也不是名字里带 2025 就一定适合你的项目。LSB 模块的价值在于它把“局部特征连续传输”这件事摆到了台面上。它提醒我们目标检测网络不仅需要更深还要让信息流动得更连续、更稳定。对开发者来说这种思路比追着新模块跑更重要。如果你正在做 YOLO26 改进不妨先从一个小实验开始把 LSB 放到你想改进的痛点上跑通、对比、分析再决定要不要长期使用。一个好模块是起点真正让项目跑起来的是你的实验设计和工程判断。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进