资讯动态

YOLO11结合REPVGGOREPA的双目标识别与低延迟定位实战

发布时间:2026/10/23 5:16:55 来源:尧图企业网站定制
上个月接到一个需求需要在入口设备上同时识别两种不同类型的目标并把它们的位置坐标实时传给后端方便后续联动处理。业务方给的数据量不算大但明确提了两个硬指标推理延迟要尽量低误检和漏检要尽量少。先尝试直接套原版目标检测模型实测下来准确率能满足但帧率总差一点而且模型文件膨胀得厉害。后来把骨干部分换成 REPVGGOREPA 风格的结构重参数化设计配合 YOLO11 的检测头重新训练延迟和精度都达到预期。这篇就把这条路线从数据集整理、模型改结构、训练调参、坐标回归到部署推理的完整过程记录下来也把踩过的坑一并说清楚。双目标识别与定位这个说法看着简单实际操作中要处理的问题不少。检测两个类别和检测二十个类别不同数据规模小模型更容易过拟合部署时每个毫秒都很敏感。如果直接套一个二十类的预训练权重再微调效果不一定好原因在于骨干网络对目标特征的表征方式和双类别场景并不完全匹配。选用 YOLO11 做主干再叠加 REPVGGOREPA 的风格化改造核心就是想在推理时不增加任何额外计算量同时提升特征的表达能力。注意这里说的 REPVGGOREPA 并不是 YOLO11 官方仓库内置的标准模块而是社区里基于结构重参数化思路做的一种骨干改造方案需要自己接入代码严格来说属于定制网络。1. 项目拆解双目标识别与定位到底要做什么1.1 双目标识别的真实含义双目标识别指的是模型只需要区分两类目标这里称为目标A和目标B每张图中可能只有A、只有B或者两类同时出现甚至多个同类目标同时出现。定位则是指输出每个目标的像素坐标位置一般表现为检测框的中心点坐标、框宽高或者左上角右下角坐标。很多刚接触检测的开发者会觉得自己还是先做一个图像分类然后再加一个回归分支算定位。但实际工程里一般不会这么做因为目标出现的数量是变动的分类模型天然不擅长处理多目标同时出现的情况。直接使用目标检测框架让模型同时完成分类和回归才是更合理的方案。我在这个项目里就直接把问题定义成“基于两类别目标检测框的位置估计”没有额外设计复杂的候选区域生成逻辑。这个项目的真实需求拆开来看有三层类别识别。对每个检测到的目标给出目标A或者目标B的标签并且给出置信分数。坐标定位。在图像坐标系中给出目标的包围框用归一化坐标或者像素坐标表示方便换算。多目标并发。一张画面同时出现多个目标、多类目标时模型要能分别输出各自的框而不是只输出一个最大目标。1.2 为什么在 YOLO11 上叠加 REPVGGOREPAYOLO11 的默认结构本身已经足够强在公开数据集上表现稳定推理生态也比较成熟。但它在骨干阶段大量使用常规卷积和C3k2结构特征表达能力依赖网络宽度和深度。在数据量不大的双目标场景里单纯加深加宽网络并不能显著提升精度反而会增加延迟。REPVGGOREPA 的改造思路正好对症。它的核心思想可以理解成一个“训练时多分支推理时单分支”的套路。训练阶段用多个卷积分支并行叠加让梯度传播路径更加丰富模型能学到更多特征模式推理前通过结构重参数化把所有分支合并成一个3x3卷积部署时完全没有额外计算开销。这种“训练贵一点推理不贵”的特性非常适合需要在入口设备上跑低延迟推理的场景。可能有人会问为什么不直接用更轻量化的 MobileNet 或者 GhostNet我测试过轻量级网络帧率确实高但小目标召回率偏低。REPVGGOREPA 的好处是它保留了高分辨率特征图上的细节表达能力又通过重参数化把训练阶段的复杂度隐藏掉换来推理时的简洁结构。两者平衡下来在这个项目里表现更合适。OREPA 本身是重参数化方向的改进版本它解决了以往 RepVGG 结构在训练和推理不一致时带来的收敛问题把重参数化过程放到在线训练中同步处理。这样即使我调整了损失函数或者改变训练策略模型也能保持稳定收敛省去了很多调试时间。1.3 整套系统的数据流向整个系统按数据流可以分为三个阶段。阶段一摄像头采集原始图像送入模型前先做尺寸归一化和letterbox处理保持长宽比不变多余区域填充灰色。阶段二模型输出一组检测结果包括类别序号、置信度、xyxy坐标。阶段三后端逻辑对坐标做缩放还原换算到原始图像坐标系再根据业务需求把坐标转发给流程控制系统或者UI展示模块。实际工程中最容易出问题的不是模型训练而是坐标换算和类别映射。模型内部用0和1表示类别业务方可能要求输出“目标A”“目标B”这样的字符串映射关系一旦错位后续逻辑全部白做。因此我在前期就把类别编号固定下来并写进配置文件训练和推理全程共用同一份配置。2. 环境准备与数据集工程2.1 环境与依赖安装先交代我的环境。系统是Linux显卡是消费级8GB显存深度学习框架使用的版本以官方仓库当前稳定版为准。建议在开始之前创建一个独立的虚拟环境不要和系统环境混在一起否则后面装依赖很容易出现版本冲突。需要安装的依赖包括 PyTorch、OpenCV、NumPy、ultralytics 包以及用于后续导出模型的 ONNX 工具包。安装命令很简单但需要注意 PyTorch 的安装方式应该和你的CUDA版本匹配。建议先去 PyTorch 官网选择对应CUDA版本的安装命令再安装其余依赖避免默认安装的CPU版本导致训练慢到无法接受。一个容易踩坑的地方是 ultralytics 包和 PyTorch 版本的兼容性。如果本地装的是较老版本的 PyTorch升级到最新版之后可能会导致原有模型加载失败。我的做法是先固定一个经过验证的版本组合训练阶段不随意升级只有确认迁移到新版本没风险再单独验证。2.2 数据集结构与标注要求双目标场景的数据集目录结构并不复杂按照 YOLO 系列的通用格式来组织就行。根目录下分 images 和 labels 两个目录各自再拆成 train 和 val。全部图片放在 images/train 下对应的标签文件放在 labels/train 下。图片和标签需要保持同名只是扩展名不同。标签文件是纯文本格式每一行代表一个目标框格式是“类别ID 中心点x 中心点y 宽度w 高度h”。注意所有数值都是相对于原始图像宽高的归一化比例范围在0到1之间而不是像素值。我之前见到有人直接写像素坐标训练时loss直接飞到无穷大排查了很久才发现是坐标范围错了。双类别数据集的 labels 里只会出现0和1两个类别ID。我在实际项目中让标注人员在框选目标时统一按先类别A后类别B的顺序操作虽然顺序本身不影响模型训练但能减少人工标注时的错标概率。数据量方面如果每张图像只有一个目标建议每个类别至少准备800张以上且尽量覆盖不同角度、光照、距离。如果条件允许2000张以上效果会更稳。低于500张时模型很容易陷入过拟合哪怕加再多数据增强也很难弥补。2.3 训练集/验证集划分与增强策略划分训练集和验证集最关键的规则是同一场景或同一目标的连续视频帧只能出现在同一侧不能既出现在训练集又出现在验证集。很多人直接从视频中抽帧随机划分导致验证集里出现了和训练集几乎一样的图像评估指标虚高。上线之后遇到新场景效果暴跌就是这个原因。我按场景分组进行划分先把所有图片按照采集场景分组再按7比3的比例划分到训练集和验证集。这样能保证验证集真正反映模型对未知场景的适应能力。数据增强我选择开启Mosaic、翻转、HSV扰动等常规策略。Mosaic把四张图拼成一张训练可以显著增强模型对小目标的检测能力尤其在目标尺寸较小的场景里很有帮助。翻转要注意类别对称性我的两个目标不具备左右对称性所以训练时没有开水平翻转避免出现错误标注。这个细节很容易被忽略但影响非常直接。3. 模型配置与 REPVGGOREPA 模块接入3.1 YOLO11 的模型配置文件结构YOLO11 的模型结构由 YAML 配置文件描述主要包含参数区、骨干网络和检测头三部分。参数区定义了类别数和输入通道数骨干网络列出网络层的串联方式检测头定义了从不同尺度特征图输出预测结果的结构。整体结构不算复杂但理解它的层次关系是后续改动的前提。我要在骨干网络中插入 REPVGGOREPA 模块就必须先找到需要替换的位置。YOLO11 骨干中通常包含若干 C3k2 结构它们的作用是对特征图做进一步的融合和提炼。C3k2 里面用的是 Bottleneck 结构而 REPVGGOREPA 提供的是一种多个卷积分支并行相加的结构。两者目的类似都是增强特征但重参数化结构在推理时能合并成单路卷积这是我选择替换它的原因。替换时我不会删除整个C3k2而是把其中核心的Bottleneck内部卷积替换为重参数化卷积块。其余下采样层和SPPF结构原样保留这样可以最大限度保留预训练权重中已经学到的基础特征。3.2 重参数化模块的前向与融合逻辑REPVGGOREPA 风格的模块在训练阶段包含三条分支一个3x3卷积、一个1x1卷积、一个只做恒等连接的分支。三条分支的输出在通道维度上逐元素相加再经过批量归一化和激活函数。这样的结构在训练时相当于多个“视角”的组合能捕捉更丰富的特征同时多分支带来的额外计算量在训练时是可以接受的。推理阶段的融合逻辑才是关键。三个分支合并时要做两件事第一将每个分支的卷积层和它后面的批量归一化层融合成一个卷积层因为批量归一化在推理时可以完全吸收进卷积的权重和偏置里第二将三个分支的卷积核对齐到同一个3x3尺寸。1x1卷积核需要在周围补零变成3x3恒等分支则需要构造一个相当于单位矩阵卷积核的3x3卷积。三者相加后得到一个融合后的3x3卷积之后整个模块就变成单路径的普通卷积结构。这个操作的数学原理听起来简单代码实现时涉及大量维度和索引的对应。我在接入时遇到了通道数不匹配的问题排查后发现是恒等分支在通道数变化时不能直接使用必须把输入沿着通道方向重复或者采用分组方式处理。了解这一点之后改造速度会快很多。3.3 双类别输出的检测头配置检测头部分需要把最后的输出类别数改成2也就是在配置文件的 nc 字段写上2。这一步在 YAML 配置里改动很小但背后影响的是检测头最后的卷积输出通道数量。YOLO11 的每个anchor位置输出通道数为 (类别数 4 1) 乘以预测层数其中4是边界框的坐标回归参数1是置信度。类别数为2时输出通道比默认的80类小很多检测头参数量大幅下降这也会带来可感知的推理速度提升。如果只是想快速验证项目可行性最简单的办法就是下载 YOLO11 官方预训练权重修改 nc 后直接微调。但如果已经改动了骨干网络结构就不能直接加载完整权重了。原因很简单预训练权重保存的是原版骨干的参数骨干结构变了参数名称和形状都对不上。我的做法是分两步加载权重。第一步用 strictFalse 加载现有权重的backbone部分跳过不匹配的层让模型先有一个比较高的初始化起点。第二步针对替换过的模块和检测头通过微调让它们自适应新任务。实际效果显示这种加载方式比从零开始训练收敛快很多最终精度也更高。4. 训练实战参数选择与过程记录4.1 预训练权重与模型微调策略在双目标场景下我强烈不建议从随机初始化开始训练。哪怕数据集很干净从零训练一个检测器也需要很长时间才能把低层特征学好。我下载了官方的轻量级预训练权重虽然骨干结构不完全匹配但前面几层卷积提取的是边缘、纹理、颜色这些通用特征迁移价值很大。加载权重时报告了几个不匹配的层名集中在被替换的重参数化模块和新检测头上。对这类不匹配的层我保留默认的随机初始化其余层正常加载。训练前期迭代速度会稍慢因为新模块需要从零学习但整体收敛速度仍然远快于完全重训。实际训练中我使用了冻结策略。前30个epoch把骨干部分全部冻结只训练检测头。原因是预训练权重中的低层特征已经很通用不需要在用少量数据训练的早期就剧烈变动。等检测头基本收敛后再解冻所有层用小学习率对整个网络做微调。两阶段策略在数据量偏少时非常有效极大减少了对数据增强的依赖。4.2 训练超参数怎么定训练超参数的选择需要结合数据量和硬件条件来定。这是比较重要的一个环节。图像输入尺寸设定为640像素这是YOLO系列比较常用的平衡点。如果目标尺寸非常小可以提高到768或者1024但训练耗时和显存都会明显增加需要根据实际资源来权衡。批量大小设成16在8GB显存下可以稳定训练不会触发显存溢出。学习率初始值设成0.01这是YOLO系列比较典型的默认值。如果数据量极少或者目标特征非常相似建议降到0.005避免早期震荡。训练轮数设定为100轮配合早停策略如果验证集指标连续20轮没有改善就自动停止这样既不会浪费算力也能防止训练后期过拟合。其中有一点需要特别关注学习率与批量大小的匹配关系。如果从16的批量加大到32理想情况下学习率也应该适当调大一点因为更大的批量提供的梯度估计更稳定。训练时最好参考官方提供的自动超参数建议不要拍脑袋设置也不要迷信别人分享的一组超参数。4.3 loss 曲线分析与过拟合处理训练过程中需要盯三个主要指标box_loss 表示边界框回归的误差cls_loss 表示分类损失dfl_loss 表示分布焦点损失。前几十轮看到三类损失整体下降是正常现象中间出现短暂的上下波动也属于预期范围真正的警惕信号是训练损失持续下降但验证集的 mAP 开始明显停滞或下降。我这次训练到约60轮时已经发现验证集精度不再提升这基本就是模型开始过拟合的边界。由于前面已经开启了早停机制训练在约75轮时自动停止保留的最佳epoch是65轮。从收集到的模型文件来看最佳权重对应的验证集mAP50得分明显高于最后一轮的参数这也是早停机制的实战价值体现。如果想进一步缓解过拟合可以从两个方向入手。数据侧增加Mosaic增强强度或者加入随机擦除让模型看到更多样化的输入算法侧用更小的学习率继续微调并把验证集指标作为保存权重的唯一依据。模型侧则可以在最终部署时通过更多测试集来评估真实泛化性能。双目标场景中由于类别少相对不容易发生严重过拟合但如果数据和场景单一依然要有这个风险意识。5. 推理与定位功能落地5.1 模型导出与 CUDA 推理训练完成后直接用原生 PyTorch 模型做推理是可行的但这不是一个低延迟项目的合理做法。原生模型的推理路径中包含大量动态分支在GPU上会带来额外的调度开销。我的做法是先导成 ONNX 格式再从 ONNX 导出 TensorRT 的 engine 文件用 TensorRT 做最终推理。导出 ONNX 时有个关键操作就是要先把模型切换成 eval 模式然后调用导出接口。如果模型停留在训练模式导出的 ONNX 中会包含大量训练专用节点后续转换会各种报错。即便能转换成功推理结果也可能和训练结果对不上因为批量归一化层的行为在两种模式下完全不同。我最初没有显式调用切换导致推理坐标全部偏移排查了很久才定位到原因。TensorRT 的 engine 文件在目标机器上生成时间较长因此我在训练机上完成转换后直接把 engine 文件和配套的类别映射配置一起部署到运行机上。如果运行机的显卡型号与生成环境不同engine文件无法直接复用需要重新生成这点在项目交付时需要提前和对方确认清楚。5.2 检测框坐标到实际定位的换算模型输出的坐标是letterbox处理后的图像坐标系还原到原始图像坐标系时需要做一个逆向变换。流程是这样的记录原始图像的高度、宽度计算letterbox后的缩放比例再根据缩放比例还原边界框的坐标。这个步骤遗漏的话所有检测框会整体偏移位置信息完全不可用。换算公式很简单原始坐标等于处理后的坐标除以缩放比例同时减去padding的偏移量。我建议在代码里封装一个检测结果还原函数一次性把模型输出的xyxy坐标转换成原始图像上的坐标再计算中心点坐标和边框尺寸。如果业务方需要的不是像素坐标而是实际物理空间坐标那就需要引入相机标定了。最简单的方案是测距标定即在固定高度下采集多组目标距离和像素宽度的对应关系拟合一条映射曲线。在入口设备这类固定安装场景中这种方式完全够用实际定位误差可以控制在几个像素以内已经能够满足联动控制的需求。5.3 双目标同时出现的处理逻辑模型输出阶段会同时给出所有目标框双目标场景中最常见的业务判断有两种。第一种只需要知道画面中是否有目标A和是否有目标B那么通过置信度阈值筛选后把类别ID去重即可。第二种需要知道每个目标的具体位置此时要去除掉重叠度高且置信度低的候选框。NMS 会把同一目标上重复的框抑制掉保留置信度最高的那个。类别间的NMS独立处理是一个容易被忽略的点。如果两个类别目标在画面中高度重叠使用统一的NMS可能把其中一类框当成另一类的重复框删掉。我在这个项目里把两个类别分开执行NMS确保目标B被目标A大面积遮挡时依然能保留自己的框实测下来对最终定位的稳定性帮助很大。置信度阈值、NMS的交并比阈值也是需要调节的值。置信度设得过高会把模糊目标全部滤掉导致漏检设得过低则大量误检框涌入。我最终把置信度设置在0.3NMS交并比设置在0.5这个组合对双目标场景效果不错。实际部署时建议根据业务对误检和漏检的容忍程度做一次小规模的阈值扫描找到平衡点。6. 常见问题与排查经验6.1 故障现象与解决方案速查实际开发过程中收集到的问题和对应解决方法整理成了表格方便日后排查时快速对照。这些问题大多是从零搭建双目标检测定位系统时比较常见的现象尤其是坐标偏移和预训练权重加载报错几乎每个新手都会碰到。故障现象可能原因排查步骤与解决办法模型加载预训练权重时报键名错误骨干结构改动导致参数名不匹配确认 strictFalse 是否开启对比 state_dict 键名差异训练早期 loss 极高且波动剧烈学习率过大或标签坐标超出0-1范围先降低学习率到0.001检查标签文件中的数值范围推理结果框位置整体偏移忘了做 letterbox 还原在预处理函数中记录缩放比例与padding复原时用同一个映射两个类别发生明显混淆类别不平衡或特征相似度太高检查训练集中两类目标的样本数补充少数类考虑分阶段训练导出 ONNX 后推理结果异常模型仍在训练模式或包含训练节点显式调 eval 模式重新导出必要时简化动态轴TensorRT 转换失败存在不兼容算子用日志定位到具体层替换为兼容结构后再转换6.2 改动模型结构时的一个关键教训关于模型结构改动这里想重点说一个经验。YOLO11 官方预训练权重是基于特定结构训练的如果你修改骨干后强行加载全部权重即使参数名对上了语义也不一定匹配。不同卷积层提取的特征层次截然不同把深层特征图的权重放到浅层去初始化短期看训练loss在下降但最终精度往往不如随机初始化加正确训练策略。因此我建议任何结构定制项目都建立一个“权重控制清单”详细记录哪些层冻结、哪些层随机初始化、哪些层加载预训练值。训练到一半才发现某个模块被错误初始化重新训练的时间成本很高。这个清单在我实际项目里帮了大忙相当于给模型改造上了个保险。6.3 实测性能与系统稳定性最终部署时输入分辨率640像素模型在消费级显卡上达到单张推理约十几毫秒的水平加上预处理和后处理整体端到端帧率稳定在较高水平。相比原版YOLO11推理耗时几乎没有增加而验证集mAP50提升了可感知的比例。这也是REPVGGOREPA这类结构重参数化方法最明显的收益精度涨点速度不降。稳定性方面需要特别注意显存和内存的长期占用。双目标检测模型本身很小常驻显存占用不算大但连续运行数天之后如果遇到图片解码失败或者特殊分辨率输入内存碎片可能缓慢增长。我在部署端加了一个统一分辨率预处理开关并在异常图片分支里主动释放缓冲区目前连续运行一周没有出现内存异常增长的情况。系统还加了日志回传功能把每一步推理的耗时和检测结果数量记录到本地文件方便出现问题时回溯。这个日志在调试阶段帮了大忙有一次业务反馈某一时段定位不准翻日志发现是某一帧图片在解码时被错误拉伸而不是模型本身的问题。这种问题不通过日志几乎无法定位。从我自己的实操体会来说做这类双目标检测定位系统最核心的其实不是模型选得多新而是数据和坐标换算这两块基础工作。数据质量决定模型上限坐标换算决定系统能否真正被业务使用。REPVGGOREPA 提供的是精度和速度间的一层保障但如果没有把数据工程做好再好的结构也白搭。如果接下来要继续扩展这个项目有两个方向很值得做。一是把定位结果直接联动到云台或机械结构上通过坐标误差反馈做闭环控制这时候需要把检测频率和运动控制的周期做同步不能各跑各的。二是针对特定目标建立模板特征库当模型在某些角度下偶尔漏检时用模板匹配做二次确认减少漏检率。就本篇而言目前从模型训练到坐标输出的完整链路已经能直接复现剩下的细节就需要根据你的实际场景慢慢调了。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑