尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

YOLOv5-seg实例分割实战:从数据标注到模型部署全流程指南

YOLOv5-seg实例分割实战:从数据标注到模型部署全流程指南 1. 项目概述从目标检测到实例分割的跨越如果你已经玩转了YOLOv5的目标检测看着模型精准地框出图片里的每一个目标那么是时候迈向下一个阶段了——让模型不仅能“看到”目标在哪里还能“看清”目标的精确轮廓。这就是YOLOv5-seg分割版要干的事。它基于经典的YOLOv5架构集成了实例分割能力可以同时输出目标的边界框和像素级的掩码Mask。简单来说就是从“画框”升级到了“抠图”。这个项目标题“Yolov5-seg 训练自己的数据集”核心诉求非常明确摆脱对公开数据集的依赖针对自己业务场景下的特定物体比如工业零件缺陷、医疗影像中的病灶区域、农业中的特定作物或害虫完成从数据准备、标注、训练到最终部署的全流程。这不再是简单的调参跑demo而是将一个先进的计算机视觉模型真正“驯化”为自己所用的过程。无论是做产品质检的工程师、研究生物形态的科研人员还是开发智能应用的开发者掌握这套流程都意味着能将最前沿的视觉AI能力快速落地到具体问题中。与单纯的目标检测相比实例分割的标注成本更高、模型训练更吃资源但带来的价值也是巨大的。它能提供物体的精确形状信息这对于测量尺寸、计算面积、判断粘连或重叠情况至关重要。接下来我会结合自己多次从零开始搭建分割项目的经验拆解其中的每一个环节分享那些官方文档里不会写的“坑”和技巧。2. 核心思路与方案选型为什么是YOLOv5-seg在决定动手之前我们得先搞清楚几个关键问题为什么在众多实例分割模型如Mask R-CNN, Detectron2, MMDetection等中选择YOLOv5-seg它适合我的场景吗2.1 YOLOv5-seg的核心优势解析YOLOv5-seg并非一个完全从零设计的模型而是在YOLOv5目标检测的坚实基础上增加了一个分割头Segmentation Head。这个设计带来了几个无可替代的优势极高的工程效率与易用性YOLOv5系列以其极简的工程实现闻名。一个git clone一个pip install -r requirements.txt环境基本就绪。其代码结构清晰配置文件.yaml管理模型结构和训练参数对于快速实验和迭代非常友好。相比其他框架动辄复杂的配置和环境冲突YOLOv5能让你把精力集中在数据和业务上。速度与精度的平衡YOLO系列天生的优势就是快。YOLOv5-seg继承了这一特性在保持实时推理速度的同时提供了颇具竞争力的分割精度。对于需要部署在边缘设备如Jetson系列、手机或对实时性要求高的场景如视频流分析这是一个关键考量点。无缝衔接的生态如果你已经是YOLOv5的用户那么切换到seg版本的学习成本几乎为零。数据准备格式相似训练命令几乎一样连模型导出到ONNX、TensorRT等的流程都一模一样。这种连续性大大降低了技术栈切换的风险和成本。活跃的社区与持续更新虽然Ultralytics官方重心已转向YOLOv8但YOLOv5的社区依然非常活跃大量的问题和解决方案都可以在网上找到。而且其代码和预训练模型非常稳定足以满足绝大多数工业级应用的需求。2.2 方案选型背后的现实考量选择YOLOv5-seg通常基于以下现实考量资源有限可能没有庞大的GPU集群只有一两张消费级显卡如RTX 3080/4090。YOLOv5-seg的小模型如YOLOv5s-seg在单卡上就能高效训练。需求明确不需要最顶级的学术精度SOTA更需要一个稳定、可快速部署、且维护简单的解决方案。渐进式升级业务原本使用YOLOv5做检测现在需要分割信息。采用YOLOv5-seg可以最大程度复用之前的代码、工具链和部署经验。注意如果你的场景对分割精度要求极高例如医疗影像诊断或者物体非常小、边界极其模糊可能需要考虑专精于分割的模型如Mask R-CNN或基于Swin Transformer的架构。但对于大多数工业检测、机器人视觉、通用场景理解YOLOv5-seg是一个绝佳的起点。2.3 项目整体流程地图在开始写代码之前我们必须对全局流程心中有数。一个完整的“训练自己的数据集”项目通常遵循以下闭环数据收集 - 数据标注 - 数据格式整理 - 环境配置 - 模型训练 - 性能评估 - 模型导出 - 部署应用其中数据标注与整理环节会消耗整个项目70%以上的精力也是决定项目成败的天花板。模型训练更像是一个“炼丹”过程而数据质量直接决定了能炼出什么品质的“丹”。接下来我们就从最关键的基石——数据准备开始。3. 数据准备高质量数据集的构建艺术模型性能的上限由数据决定。对于实例分割任务数据要求比检测更高因为需要像素级的真值。3.1 数据收集与清洗原则代表性你的数据集必须覆盖实际应用场景中可能出现的所有情况。包括不同的光照条件顺光、逆光、昏暗、拍摄角度俯视、平视、倾斜、目标形态完整、部分遮挡、严重遮挡、背景复杂度以及目标尺度的变化远距离小目标、近距离大目标。数据量这是一个常见问题。对于分割任务一个类别的目标至少需要200-300个高质量的标注实例才能让模型学到有效的特征。当然更多数据总会更好。如果数据稀缺必须高度重视数据增强策略。图像质量尽量使用高分辨率、对焦清晰、噪声少的原始图像。模糊、过曝、欠曝的图像会增加模型的学习难度甚至引入噪声。负样本收集一些完全不包含目标物体的图像纯背景图加入训练集有助于降低模型的误检率False Positive。3.2 标注工具选择与实操要点标注是体力活更是技术活。工具选得好事半功倍。推荐工具LabelMe为什么是LabelMe开源、免费、跨平台Windows/macOS/Linux支持多边形Polygon标注这正是实例分割所需的格式。它生成JSON文件可以轻松转换为YOLO格式。实操命令安装pip install labelme然后命令行运行labelme即可打开图形界面。标注核心技巧点密度控制勾勒轮廓时点的疏密要合适。对于平滑边缘点可以稀疏一些对于复杂弯曲的边缘点需要密集一些。但切忌过于密集否则会增加标注工作量且可能引入抖动噪声。一个原则是用尽可能少的点准确地描述轮廓。遮挡处理如果一个物体被另一个物体部分遮挡只标注可见部分的轮廓。不要试图去“想象”被遮挡部分的形状。小目标标注对于很小的物体比如图像中只有几十个像素精确的多边形标注可能非常困难且不稳定。可以考虑使用一个紧密的矩形框等同于检测框来近似或者在评估时对这类小目标放宽掩码精度要求如使用更宽松的IoU阈值。其他工具参考CVAT功能更强大的在线标注系统支持团队协作、视频标注、自动预标注适合大型项目。Roboflow在线平台提供数据标注、增强、版本管理一站式服务有免费额度。3.3 数据格式转换从LabelMe到YOLOv5-seg这是新手最容易出错的一环。YOLOv5-seg需要一种特定的格式。LabelMe输出每张图片对应一个.json文件里面包含了图像尺寸、以及每个标注物体的多边形点坐标基于图像宽度和高度的绝对值和类别标签。YOLOv5-seg所需格式目录结构my_dataset/ ├── images/ │ ├── train/ │ │ ├── image1.jpg │ │ └── ... │ └── val/ │ ├── image2.jpg │ └── ... └── labels/ ├── train/ │ ├── image1.txt │ └── ... └── val/ ├── image2.txt └── ...标签文件.txt内容每一行代表一个实例。class_id x1 y1 x2 y2 ... xn ynclass_id物体的类别索引从0开始。x1 y1 x2 y2 ... xn yn归一化的多边形坐标。注意这里是多边形点序列而不是检测框的x_center y_center width height每个x和y都需要除以图像的宽度和高度将其归一化到[0, 1]区间。转换脚本示例Python 这是一个关键操作务必理解每一行代码。你需要编写一个脚本读取LabelMe的JSON文件提取多边形点进行归一化然后按上述格式写入txt文件。import json import os from pathlib import Path def labelme_to_yolo_seg(json_path, label_save_dir, class_list): with open(json_path, r) as f: data json.load(f) img_width data[imageWidth] img_height data[imageHeight] txt_filename Path(json_path).stem .txt txt_save_path os.path.join(label_save_dir, txt_filename) with open(txt_save_path, w) as f_txt: for shape in data[shapes]: label shape[label] if label not in class_list: continue # 或者将未知类别加入列表 class_id class_list.index(label) # 提取多边形点 points shape[points] # [[x1, y1], [x2, y2], ...] # 归一化 normalized_points [] for point in points: norm_x point[0] / img_width norm_y point[1] / img_height normalized_points.append(norm_x) normalized_points.append(norm_y) # 写入文件类别id 归一化的多边形点序列 line str(class_id) .join([f{p:.6f} for p in normalized_points]) \n f_txt.write(line) # 用法示例 class_list [cat, dog] # 你的类别列表顺序决定了class_id labelme_json_dir /path/to/labelme_jsons yolo_label_dir /path/to/my_dataset/labels/train os.makedirs(yolo_label_dir, exist_okTrue) for json_file in Path(labelme_json_dir).glob(*.json): labelme_to_yolo_seg(json_file, yolo_label_dir, class_list)实操心得在转换后务必进行可视化检查写一个简单的脚本读取生成的txt文件将多边形点还原并画到原图上确保标注没有错位、遗漏或顺序错误。这是避免后续训练出现诡异问题的关键一步。3.4 数据集划分与配置文件准备划分训练集、验证集、测试集通常按70:20:10或80:10:10的比例随机划分。验证集用于训练过程中监控模型性能、调整超参数测试集用于最终评估在训练过程中绝对不可见。可以使用sklearn.model_selection的train_test_split函数。创建数据集配置文件dataset.yaml这是YOLOv5训练时读取数据的入口。# my_dataset.yaml path: /absolute/path/to/my_dataset # 数据集根目录 train: images/train # 训练集图像路径相对于 path val: images/val # 验证集图像路径相对于 path # test: images/test # 可选测试集路径 # 类别数量与名称 nc: 2 # 你的类别数量例如2 names: [cat, dog] # 类别名称顺序必须与标注时的class_id对应 # 可选下载地址/说明 # download: ...将这个yaml文件放在YOLOv5项目的根目录下。4. 模型训练全流程解析与实操环境与数据就绪终于可以开始“炼丹”了。4.1 环境配置与依赖安装建议使用Conda或Venv创建独立的Python环境避免包冲突。# 1. 克隆YOLOv5仓库使用官方或稳定的fork git clone https://github.com/ultralytics/yolov5.git cd yolov5 # 2. 创建并激活虚拟环境以Conda为例 conda create -n yolov5-seg python3.8 conda activate yolov5-seg # 3. 安装依赖 (PyTorch请根据你的CUDA版本从官网获取安装命令) pip install -r requirements.txt # 确保torch和torchvision版本匹配且支持GPU4.2 训练命令详解与关键参数核心训练命令如下python segment/train.py --data my_dataset.yaml \ --weights yolov5s-seg.pt \ --img 640 \ --batch-size 16 \ --epochs 100 \ --name my_first_seg_exp让我们拆解每个参数背后的考量--data: 指向我们刚创建的数据集配置文件。--weights: 指定预训练模型。强烈建议使用预训练模型yolov5s-seg.pt是在COCO数据集上预训练好的分割模型。使用预训练权重可以极大加速收敛提升最终精度尤其是在自己数据量不大的情况下。这是迁移学习的核心。--img: 输入图像尺寸。YOLOv5会将所有图像缩放到此尺寸进行训练。640是一个在速度和精度间取得良好平衡的常用值。如果你的目标物体都非常小可以尝试增大到1024但会显著增加显存消耗和训练时间。反之如果物体很大且显存紧张可以降低到512。--batch-size: 批大小。这是最重要的参数之一。在显存允许的前提下尽可能设大。更大的batch size通常意味着更稳定的梯度估计和更快的收敛。你需要根据GPU显存来调整。例如RTX 308010G上img640时batch-size16可能刚好。如果出现CUDA out of memory错误就减小这个值或者减小--img。--epochs: 训练轮数。100是一个常见的起点。可以通过观察验证集损失和精度曲线来判断是否早停Early Stopping。--name: 本次实验的名称。所有输出模型权重、日志、可视化结果都会保存在runs/train-seg/{name}目录下。进阶重要参数--device: 指定GPU。如--device 0或--device 0,1多卡。--workers: 数据加载的线程数。对于高速SSD可以设置为CPU核心数如8。用于加快数据读取避免GPU等待数据。--patience: 早停耐心值。如果验证集指标在连续N个epoch没有提升则停止训练。例如--patience 30。--hyp: 指定超参数配置文件。YOLOv5有一套精心调校的默认超参data/hyps/hyp.scratch-low.yaml等初学者不建议修改。进阶用户可以尝试微调学习率、数据增强强度等。4.3 训练过程监控与解读训练开始后控制台会输出日志更重要的是要关注TensorBoard或本地生成的结果图表。损失曲线losses.pngtrain/box_loss,train/obj_loss,train/cls_loss,train/seg_loss训练集各项损失。理想情况下应平滑下降并逐渐趋于平缓。val/box_loss等验证集损失。它也应该下降但可能会在训练后期略有波动。关键是要看验证集损失是否明显高于训练集损失如果是可能出现了过拟合。性能指标曲线metrics.pngmetrics/mAP_0.5以IoU0.5为阈值计算的平均精度mAP。这是检测框的精度。metrics/mAP_0.5:0.95IoU阈值从0.5到0.95步长0.05的平均mAP是更严格的指标。metrics/mask_mAP_0.5:0.95这是分割掩码的mAP是我们最关心的核心指标。它衡量模型预测的掩码与真实掩码的匹配程度。验证结果可视化val_batch_labels.jpg val_batch_pred.jpg**定期查看验证集上的真实标签_labels和模型预测_pred对比图。这是最直观判断模型好坏的方式。看看框是否准掩码边缘是否贴合。注意事项训练初期指标波动很大是正常的。通常需要跑完至少50个epoch才能对模型性能有一个初步判断。如果mask_mAP一直很低首先要怀疑的是数据标注质量和数据格式是否正确。4.4 数据增强策略调优YOLOv5内置了强大的数据增强Mosaic, MixUp, 色彩抖动随机透视等默认是开启的。这些增强能极大地提升模型的泛化能力。对于小数据集务必开启并可能还需要加强增强。可以在hyp.yaml文件中调整增强概率和强度例如增大hsv_h色调、hsv_s饱和度、hsv_v明度的抖动范围或提高degrees旋转角度、scale缩放的范围。对于特殊场景如果您的场景有特定规律如摄像头角度固定可以关闭一些不相关的增强。例如如果目标不可能上下翻转可以关闭flipud上下翻转如果视角固定可以减少随机透视变换的强度。自定义增强YOLOv5的增强代码在utils/augmentations.py中。如果需要极特殊的增强如模拟特定类型的运动模糊、雨雪噪声可以在这里进行修改。5. 模型评估、优化与问题排查训练完成后我们得到了模型权重best.pt和last.pt。接下来是检验成果和精调的时刻。5.1 模型性能评估使用验证集或独立的测试集进行评估python segment/val.py --data my_dataset.yaml \ --weights runs/train-seg/my_first_seg_exp/weights/best.pt \ --img 640 \ --task val # 或者 --task test命令会输出详细的评估表格包括每个类别的精确率Precision、召回率Recall、mAP0.5、mAP0.5:0.95以及对应的掩码指标mask mAP。重点关注mask mAP0.5:0.95它是衡量分割性能的综合指标。5.2 常见问题与解决方案速查表以下是我在多个项目中遇到的典型问题及排查思路问题现象可能原因排查与解决方案训练损失不下降或震荡剧烈1. 学习率LR过高。2. 数据标注错误严重如类别错标、多边形点顺序错乱。3. 数据格式转换错误归一化出错。1. 使用预训练权重时初始LR不宜过大。YOLOv5默认的LR调度通常很鲁棒但如果从头训练scratch需使用更小的LR。2.立即停止训练可视化检查标注数据用3.3节提到的检查脚本。3. 检查标签txt文件确认坐标值是否在[0,1]区间内。验证集损失远高于训练集损失过拟合1. 训练数据量太少。2. 模型复杂度如YOLOv5x相对于数据量过高。3. 数据增强不够。1. 收集更多数据或使用更激进的数据增强。2. 换用更小的模型如YOLOv5s-seg。3. 在hyp.yaml中增强正则化项如增加weight_decay或使用--label-smoothing参数。mask mAP很低但box mAP正常1. 分割头学习失败。2. 标注的掩码质量差边缘粗糙、多边形点太少。3. 小目标分割任务本身难度大。1. 确保使用yolov5s-seg.pt而非yolov5s.pt检测权重初始化。2. 提高标注精度对边缘复杂的物体增加多边形点密度。3. 尝试增大输入图像尺寸--img 1024让小目标有更多像素信息。模型对某一类别完全检测不到1. 该类别训练样本数量严重不足。2. 该类别样本特征与其他类别混淆。1. 增加该类别数据的收集和标注或使用过采样Oversampling技术。2. 检查该类别的标注是否正确特征是否明显。可以考虑为该类别单独调整分类损失权重需要修改代码。推理速度慢1. 模型过大如使用了YOLOv5x-seg。2. 推理图片尺寸--img设置过大。1. 换用更小的模型s-m-l-x速度递减精度递增。2. 在满足精度的前提下减小推理时的--img参数。也可以使用半精度--half推理加速。5.3 模型优化与迭代策略超参数调优在初步训练得到一个baseline后可以系统性地调优。工具如Weights Biases (WB)或Optuna可以帮助你自动化超参数搜索但手动调整几个关键参数通常更高效--lr0: 初始学习率。如果收敛慢可适当增大如从0.01到0.02如果震荡则减小。--warmup_epochs: 学习率热身epoch数。对于小数据集可以适当增加热身epoch让模型更稳定地进入训练。--hyp: 尝试不同的超参数配置文件如hyp.finetune.yaml通常比hyp.scratch-low.yaml学习率更小更适合微调。模型集成训练多个不同初始化或不同数据增强下的模型在推理时将它们的结果进行融合如加权平均掩码往往能提升1-2个点的mAP但会增加计算开销。测试时增强TTA在推理时对图像进行多种变换翻转、缩放等将多个预测结果合并。这会显著提升精度但也会成倍增加推理时间。可通过python segment/val.py --weights best.pt --data my_dataset.yaml --tta来测试TTA效果。6. 模型导出与部署推理模型训练评估满意后下一步就是让它跑在真正的应用环境中。6.1 模型导出为不同格式YOLOv5提供了极简的导出脚本支持多种后端python export.py --weights runs/train-seg/my_first_seg_exp/weights/best.pt \ --include torchscript onnx engine \ --img 640 --batch 1 --device 0--include: 指定导出格式。torchscript: PyTorch自家的中间表示可用于C LibTorch推理。onnx: 开放神经网络交换格式通用性最强可以被TensorRT, OpenVINO, ONNX Runtime等众多推理引擎支持。engine: 专指NVIDIA TensorRT引擎需要在有TensorRT环境的机器上导出能获得在NVIDIA GPU上的极致推理速度。--img,--batch: 指定导出的输入尺寸和批次。部署时通常使用batch1。--device: 指定导出时使用的设备。导出ONNX时的关键点确保ONNX模型能被目标推理引擎正确识别。有时需要简化模型--simplify或添加动态维度--dynamic以支持可变输入尺寸。导出后务必用ONNX Runtime或Netron工具检查模型结构是否正确。6.2 使用训练好的模型进行推理YOLOv5提供了方便的推理脚本python segment/predict.py --weights best.pt \ --source my_image.jpg \ --img 640 \ --conf-thres 0.25 \ --iou-thres 0.45 \ --hide-labels \ --save-txt--source: 输入源可以是图片、视频、文件夹路径、摄像头ID如0或URL。--conf-thres: 置信度阈值。低于此值的预测框会被过滤掉。根据你的场景调整追求高召回率就调低如0.1追求高精确率就调高如0.5。--iou-thres: 非极大值抑制NMS的IoU阈值。用于合并重叠的预测框。值越小合并越严格留下的框越少。--hide-labels/--hide-conf: 隐藏标签或置信度。--save-txt: 将预测结果框和掩码的多边形点保存为YOLO格式的txt文件便于后续分析。6.3 集成到自有应用Python示例更多时候我们需要将模型集成到自己的Python程序中import torch import cv2 import numpy as np from pathlib import Path # 加载模型 model torch.hub.load(ultralytics/yolov5, custom, pathruns/train-seg/my_first_seg_exp/weights/best.pt, force_reloadTrue) model.conf 0.25 # 置信度阈值 model.iou 0.45 # NMS IoU阈值 # 推理单张图片 img cv2.imread(my_image.jpg)[..., ::-1] # BGR to RGB results model(img, size640) # 指定推理尺寸 # 解析结果 predictions results.pandas().xyxy[0] # 检测框信息 (pandas DataFrame) masks results.masks # 分割掩码信息 if masks is not None: masks masks.data.cpu().numpy() # 转换为numpy数组 [N, H, W] for idx, mask in enumerate(masks): # mask是二值掩码与原图同高宽 # 可以将其转换为多边形轮廓 contours, _ cv2.findContours(mask.astype(np.uint8), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # 在原图上绘制轮廓 cv2.drawContours(img, contours, -1, (0, 255, 0), 2) # 显示或保存结果 cv2.imshow(Result, img[..., ::-1]) # RGB to BGR for display cv2.waitKey(0)这段代码展示了如何加载模型、进行推理并获取检测框和分割掩码。results.masks返回的是每个实例的二进制掩码你可以用它来计算面积、提取轮廓、做进一步的空间分析等。6.4 部署到生产环境的考量性能优化TensorRT如果部署在NVIDIA GPU上强烈推荐将ONNX模型转换为TensorRT引擎。这通常能带来数倍甚至十数倍的推理速度提升。可以使用trtexec工具或TensorRT Python API进行转换和部署。ONNX Runtime跨平台CPU/GPU推理的良好选择支持多种硬件加速后端CUDA, TensorRT, OpenVINO等。量化将模型从FP32转换为INT8可以大幅减少模型体积和提升推理速度精度损失通常很小。TensorRT和ONNX Runtime都支持量化。前后端分离对于Web服务或移动App通常采用后端服务器运行模型提供API接口如FastAPI, Flask前端发送图片并接收JSON格式的检测和分割结果。持续监控与更新部署后需要收集模型在真实场景中的表现数据可能通过人工抽检或困难样本挖掘用于发现模型盲区为下一轮数据收集和模型迭代提供方向。训练自己的YOLOv5-seg模型是一个系统工程从数据准备到最终部署每一步都需要耐心和细心。最大的体会是数据质量决定上限模型调优决定下限。很多时候花时间清洗和修正一批错误标注的数据比调一个月参数提升的效果都要大。另外不要迷信某个模型或某个技巧最适合自己业务场景的方案往往是在深刻理解自己数据特点的基础上通过多次实验迭代出来的。先从一个小而精的数据集开始跑通整个流程再逐步扩展数据和优化模型是风险最低、成功率最高的路径。
返回列表