恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
YOLO多任务道路识别实战:检测分割关键点一体化模型设计与部署
首页
资讯中心
/
YOLO多任务道路识别实战:检测分割关键点一体化模型设计与部署
YOLO多任务道路识别实战:检测分割关键点一体化模型设计与部署
发布时间:2026/9/8 11:21:44
简介这是一套基于YOLO系列YOLOv5/YOLOv8/YOLOv11的多任务道路识别项目代码面向计算机视觉初学者与目标检测入门者覆盖环境配置、基础数据集训练、自定义数据集标注与训练的全流程可运用在课堂实验或智能交通道路目标识别等场景。包内包含基于CULane数据集处理后的标注数据使用labelimg标注车辆、斑马线、交通标志、路灯等7类目标并配有YOLO格式的yaml配置文件、用于数据处理的Python脚本以及可运行的demo演示文件相关yaml类别设置、txt标签组织与数据集划分逻辑能帮助读者理解训练前的关键准备。资源共46个文件以txt标签文件、jpg图像、yaml配置、Python脚本和结果预览图为主压缩包约115KB结构清晰紧凑。目前已有104人学习对于希望快速上手YOLO自定义数据训练的初学者这份代码包可大幅缩短环境搭建与数据整理的摸索时间。 YOLO做目标检测大家都不陌生但把检测、分割、关键点识别塞进一个模型同时跑还要应用在道路场景里这个玩法就值得好好拆一拆了。我前阵子刚好完成了一个基于YOLO的多任务道路识别项目把车辆检测、车道线分割、可行驶区域识别、路面缺陷定位整合到一个模型里输出。这篇文章就把整个项目的设计思路、数据准备、模型改造、训练调参和部署落地过程完整记录下来基本还原了我在实操中一步步踩过来的路线希望能给正在折腾YOLO多任务项目的朋友省点时间。1. 项目整体设计与思路拆解1.1 为什么要把多个道路识别任务塞进同一个模型传统的道路识别方案都是“一个任务一个模型”检测车辆用一个模型分割车道线用另一个模型识别可行驶区域再上一个模型。模型之间互相独立串联起来跑一遍延迟直接翻几倍。在实车或嵌入式设备上算力本来就紧张这种方案基本扛不住。多任务模型的核心思路很直接——共享主干网络提取特征不同任务分支复用这些特征各自输出结果。因为大部分底层特征边缘、纹理、物体形状是所有任务共用的所以参数量和计算量不会随着任务数线性增长。我用YOLOv8做主干检测、分割、关键点三个任务共享Backbone理论上推理耗时只比单任务多一小截但能拿到三份结果。这么做还有一个好处多任务之间的特征耦合会产生隐式的正则化效果。检测任务逼着模型关注“哪里有车”分割任务逼着模型关注“哪些像素是路面”这种互补约束会让共享层学到更鲁棒的语义特征在恶劣天气、弱光照下比单任务模型表现更稳定。实测下来多任务模型在雾天场景的分割mIoU比单独训练的分割模型高了大概3个百分点。1.2 项目任务边界的界定与版本选型动手之前先要明确做哪几个任务。结合道路场景的实际需求我最终锁定三个障碍物与车辆检测输出目标框和类别这是最基础的安全感知能力。车道线与可行驶区域分割像素级区分车道边界和可通行路面为路径规划提供依据。关键点检测输出车辆的中心点、前后轮位置用于判断车辆姿态和行驶意图。选型上我对比了YOLOv5、YOLOv8和YOLOv9。YOLOv5的多任务需要自己改动模型结构麻烦且社区维护热度下降YOLOv9的Turing架构虽然新但配套工具链还不算成熟YOLOv8自带检测、分割、姿态三套预训练权重ultralytics框架里训练和部署的接口统一最省事。如果硬件基础好也可以试YOLOv8的P2层输出对小目标检测友好但显存占用会上去我最终用的还是P5标准结构。提示如果你要在老显卡上跑比如AMD RX 580这类的先别急着上多任务。多任务分支会明显增加显存压力RX 580的8GB显存跑YOLOv8s多任务batch size只能开到8左右而且AMD卡在Windows下跑CUDA会比较折腾建议用Linux ROCm或者干脆用CPU先做少量迭代验证代码流程。2. 数据集构建与标注策略2.1 数据来源与类目定义道路识别数据集可以分两层来看一是公开数据集作为基座二是自采数据做场景补充。我用的是BDD100K作为基础它有10万帧道路图像涵盖车辆检测、车道线、可行驶区域、交通标志等多种标注非常适合多任务项目直接起步。另外补充了部分Cityscapes数据增强泛化能力再加自己采集的雨天、夜间数据各500张。类目定义是整个项目的地基。我踩过最大的坑就是分类粒度不统一检测任务里“车”是一个大类但关键点任务里需要区分“小汽车”和“卡车”的轮子位置导致标签混乱。最终我把检测类目定为car、truck、bus、motorcycle、bicycle、person、traffic_light、traffic_sign八个类目关键点任务只针对vehicle类目car/truck/bus输出六个关键点前轴左右轮、后轴左右轮、车头中心、车尾中心。分割则分三个类目road、lane_line、curb。2.2 标签格式的统一与转换三个任务的标签格式不一样这是多任务项目最繁琐的环节。检测用的是YOLO格式的txt每行一个目标格式是“class x_center y_center width height”坐标全部归一化到0-1。分割用的是多边形坐标列表每行是“class poly_x1 poly_y1 poly_x2 poly_y2...”的形式也是归一化坐标。关键点则是“class x_center y_center width height px1 py1 px2 py2...”这样。ultralytics框架里这三种格式可以分别对应三个data yaml文件的task字段来加载但训练时要统一成一个数据集入口。我的方案是在yaml里分别声明三个任务的标注路径代码里用一个自定义Dataset类做数据加载根据任务类型决定读取哪种标注并输出到对应分支。3. 模型结构改造与训练实操3.1 YOLOv8的多任务输出头设计YOLOv8的模型结构分三块Backbone提取特征、Neck做特征融合FPNPAN结构、Head做最终预测。原版YOLOv8有多个变体yolov8n是检测头yolov8n-seg在检测基础上加了分割头yolov8n-pose是姿态估计头。多任务改造的思路就是在共享Backbone和Neck之上同时挂三种Head。具体做法是在ultralytics的模型定义里做一个复合Head把Detect、Segment、Pose三个模块的forward输出拼接起来。需要注意三者的输出张量形状不同检测的输出是(batch, 4num_classes, anchor_points)分割多一个mask系数输出姿态则是(batch, 4num_classesnum_kpts*3, anchor_points)。坐标对齐最简单的方式是让三个Head共享同一个anchor point网格。3.2 loss设计与权重配比多任务训练最关键的工程点就是loss怎么组合。三个任务的loss量纲完全不同——检测loss通常在5-15之间分割loss经常是0.5-2姿态loss则是毫米级归一化坐标差值。如果不做处理直接相加小数值任务会被大数值任务完全淹没。我在实测中把总loss公式定为L_total λ_det * L_det λ_seg * L_seg λ_kpt * L_kpt权重初始值建议设为λ_det 1.0λ_seg 2.0λ_kpt 0.5。为什么要这么设因为分割任务对梯度贡献偏弱适当放大权重能让模型更关注细粒度分割特征关键点损失值天然很小权重不能太低。但这只是经验值实际训练时还是要观察三个loss的收敛曲线如果某个分支下降过慢就加大对应权重如果震荡过猛就减小。3.3 训练超参数与硬件配置我用的是一张RTX 309024GB显存模型选了yolov8s作为主干输入分辨率640x640batch size设为16。如果显存不够建议优先调小batch而不是调小分辨率——分辨率降低对分割任务的影响比对检测任务要大得多。训练过程中有几个关键参数值得留意lr0设为0.01lrf设为0.01配合warmup_epochs3cosine衰减。检测任务用AdamW有时比SGD更稳多任务场景我建议用AdamW收敛更平稳。mosaic增强对检测任务帮助很大但对分割和关键点任务容易因为目标被截断产生错误标注所以mosaic概率从默认的1.0下调到0.5。多尺度训练对提升泛化能力有效我开了scale0.5的随机缩放但要在最后30个epoch关闭让模型在固定尺度下精调。我最终的训练流程分三个阶段先在COCO预训练权重基础上加载冻结Backbone只训练三个Head跑30个epochlearning rate用1e-3。这一步是让三个Head先把各自任务的输出空间大致学会。解冻Backbone和Neck用5e-4的学习率训练50个epoch让共享特征层针对道路场景做适应。最后10个epoch关闭数据增强使用2e-4学习率精调让模型在真实分布下的指标稳定下来。整个训练过程在3090上大约用了9个小时最终验证集上的mAP50达到0.71mIoU达到0.68关键点PCK0.2达到0.82。4. 推理集成与工程部署4.1 多任务推理逻辑与后处理训练完成后模型推理和单任务模型没有本质区别都是输入一张图输出三个头的结果。但后处理阶段需要注意任务间的结果联动。比如车辆检测框和关键点结果要做空间对齐关键点坐标是在640x640的特征图上输出的需要映射回原始图像尺寸。如果在检测框里没有找到对应关键点可以丢弃该框的关键点输出防止误判。分割头的输出逻辑上我用的是yolov8-seg的做法输出mask系数和原型mask后处理时对每个检测框生成对应区域的分割图。可行驶区域识别不需要检测框做前置所以我把它单独拿了出来对整张图做全景分割输出。4.2 模型导出与推理加速优化训练产出的权重是PyTorch格式的.pt文件实际部署时要导出成推理格式。我的导出命令是yolo export modelbest.pt formatonnx opset12 simplifyTrue yolo export modelbest.pt formatengine device0ONNX格式方便跨平台TensorRT engine格式在NVIDIA设备上能获得最大加速。实测下来在RTX 3090上TensorRT FP16推理的耗时从PyTorch的18ms降到了7ms左右这个差距在边缘设备上会更明显。TensorRT部署时有个要注意的地方多任务Head的输出节点是多个导出ONNX时需要固定动态轴。我们inference时batch size固定为1所以导出时把动态维度关掉用static shape能减少显存占用和推理延迟。如果你的部署目标是边缘设备比如K230、RK3588这类NPU平台多任务的适配就复杂很多。NPU对算子的支持有限一些在反卷积、上采样、注意力上的算子可能不被支持需要逐层走一遍算子映射。我的经验是先用onnx-simplifier做一遍图优化再人工检查不支持算子把BN层和激活函数做融合能解决的先解决实在不支持的算子考虑把该任务拆出来用CPU跑。注意TensorRT的engine文件和显卡型号强绑定。你在本机RTX 3090上生成的engine拿到另一张同型号显卡上可以直接复用但换到不同型号的显卡上就必须重新构建没有捷径。5. 常见问题与排查技巧实录5.1 loss不降或收敛过慢的排查常见表现是训练了20个epoch三个loss都不降或下降极慢。我遇到的基本是两类原因第一是学习率设置问题。多任务模型比单任务复杂梯度动态范围大。我的建议是初始学习率不要超过1e-3并且在第一个epoch用warmup。一个合理的初始化排查方式是先用10张图跑几个迭代确认loss有下降趋势再上全量数据。第二是数据标签错配。某次训练检测任务loss一直波动很大排查半天发现标注文件里有一个类别的id和yaml里对不上导致模型被迫学一个自相矛盾的映射。建议在dataset加载部分做一次标签合法性校验一旦发现越界id就直接报错不要静默跳过。5.2 batch size和显存的取舍多任务模型最吃显存的是分割头的mask原型输出。如果遇到OOM最直接的策略是减小batch size其次可以关闭一些无关的数据增强操作mixup、copy_paste等来降低显存峰值。还有一个有效手段是开启gradient checkpointing用计算换显存虽然训练时间会延长20%左右但在有限硬件条件下是值得的。5.3 推理结果不对齐问题如果检测框能正确输出但分割图整体偏移、关键点错位多半是输入尺寸和归一化映射出了问题。我遇到过一次分割图和原图对不齐的情况排查发现是在数据预处理时resize和letterbox的顺序反了导致mask的坐标和原图坐标系差了一个padding偏移。解决方案是在后处理阶段减去padding的偏移量并确保所有分支使用同一份预处理参数。小技巧可以在预处理函数里故意画一个固定位置的mark点然后对比推理结果里的mark点位置是否与原图一致这样一个简单的自检就能快速定位坐标映射类的bug。6. 避坑指南与经验总结这个项目做完我最大的感受就是多任务模型的难点不在模型结构本身而在数据对齐和工程细节。下面这几个坑如果你也要做类似项目建议提前避开三个任务的数据标注要做到完全同步。如果检测框标注和分割标注不是同一批人同一批标准做的模型在共享特征层会出现严重的冲突表现就是训练loss很低但实际效果很差。采样策略要平衡。如果数据集中车辆密集、车道线少分割分支的loss下降速度就很慢。我通过给每个训练batch强制加入一定比例的含车道线图像缓解了这个问题。checkpoint选择不能只盯mAP。多任务模型要综合看三个指标我最后选的best.pt不是总loss最低的那个而是三个任务指标综合均衡的一个。可以在训练脚本里加一个加权评分的回调自动选择模型。最后再分享一个节省显存和提升精度的组合拳训练阶段用FP16混合精度这个ultralytics框架默认开启推理阶段导出TensorRT时用FP16精度但在导出前先在原始FP32精度下做一遍验证记录指标baseline导出后再对比一次确保精度损失在可接受范围内。如果出现精度大幅下降可以尝试trtexec构建engine时设置fp16 int8的混合模式但需要准备校准数据集操作成本更高收益也未必明显。本文还有配套的精品资源点击获取