ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

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

YOLOv5-seg实例分割实战:从数据标注到模型训练与部署全流程 1. 项目概述从目标检测到实例分割的实战跨越如果你已经用YOLOv5玩转过目标检测看着模型在图片里框出一个个物体觉得挺酷那么是时候进入下一个阶段了让模型不仅能框出物体还能精确地勾勒出物体的轮廓。这就是YOLOv5-seg分割版要干的事。简单来说它是在经典的YOLOv5目标检测框架上增加了一个分割头segmentation head让模型在输出边界框BBox和类别Class的同时还能输出一个与物体形状一一对应的掩码Mask。这个掩码是一个二值图物体区域是1背景是0从而实现像素级的识别。这有什么用场景可太多了。在工业质检里你需要精确知道一个零件表面的划痕或缺陷的具体形状和面积一个粗糙的框是远远不够的。在农业遥感中你需要统计果园里每棵果树的树冠覆盖面积一个精准的树冠轮廓至关重要。在医疗影像分析中肿瘤的形态、大小变化是关键的诊断指标必须依赖精确的分割结果。YOLOv5-seg继承了YOLO系列速度快、部署方便的优点同时提供了实用的分割能力对于很多需要兼顾实时性和精度的场景是一个非常有吸引力的选择。训练自己的数据集就是把这套强大的能力应用到你自己关心的特定物体上。无论是生产线上的特定工件还是野外监测的某种珍稀动物或是你自家花园里需要自动识别的花草你都可以通过准备数据、标注、训练这一套流程得到一个专属于你的“火眼金睛”。这个过程听起来专业但跟着步骤一步步来你会发现它比你想象的要更接地气。2. 核心思路与方案选型为什么是YOLOv5-seg在决定使用YOLOv5-seg之前我们得先理清自己的需求并看看市面上有哪些“家伙什”。深度学习分割任务主要有两大门派语义分割和实例分割。语义分割是把图片里所有属于“人”的像素都涂成一种颜色所有“车”的像素涂成另一种颜色但它不区分个体——如果图里有两个人它们会被涂成同一种颜色。实例分割则更进一步它不仅要区分类别还要区分个体第一个人一个颜色第二个人另一个颜色。YOLOv5-seg干的就是实例分割的活。那么为什么在众多实例分割模型如Mask R-CNN, Detectron2, SOLO等中我推荐从YOLOv5-seg开始尤其是当你已经有了YOLOv5检测的经验后2.1 生态延续与学习成本低最大的优势是继承性。如果你熟悉YOLOv5的训练流程、数据格式YOLO格式的txt标注文件和配置文件data.yaml,hyp.yaml那么切换到YOLOv5-seg几乎是无缝的。你的大部分知识、脚本和经验都可以复用。数据准备流程高度相似只是标注内容从“框”变成了“轮廓多边形”。这极大地降低了学习门槛和试错成本。2.2 速度与精度的平衡YOLO系列的核心优势就是快。YOLOv5-seg在保持较高推理速度的前提下提供了足够实用的分割精度。对于许多实时或准实时应用如视频流分析、机器人视觉引导这种平衡至关重要。Mask R-CNN虽然精度可能更高但其速度在边缘设备上往往难以满足要求。2.3 部署友好YOLOv5的工程化做得非常出色提供了完善的导出支持可以轻松地将训练好的模型转换为ONNX、TensorRT、CoreML等格式方便在各种平台从服务器到嵌入式设备如Jetson系列、树莓派上部署。YOLOv5-seg完全继承了这一优点让你在模型落地时省心不少。2.4 社区与资源丰富YOLOv5拥有极其活跃的社区。这意味着你在训练过程中遇到的几乎所有问题几乎都能在GitHub Issues、论坛或相关博客中找到讨论和解决方案。丰富的预训练模型、详细的文档和持续的更新为项目成功提供了额外保障。当然它也有其局限性。对于需要极端精细分割边缘的场景如发丝分割、透明物体专门的语义分割模型如U-Net, DeepLab系列或更先进的实例分割模型可能效果更好。但对于绝大多数通用物体的实例分割需求YOLOv5-seg是一个稳健、高效且易于上手的起点。注意YOLOv5官方仓库已进入维护模式官方推荐转向Ultralytics的YOLOv8后者提供了更统一、更强大的分割、检测、分类模型接口。YOLOv8-seg在精度和易用性上通常有更好的表现。但YOLOv5-seg因其稳定性、广泛的社区应用和大量的遗留项目依然具有很高的学习价值。本文的流程与思想与YOLOv8-seg高度相通掌握了前者迁移到后者会非常容易。3. 数据集准备与标注从图片到多边形坐标这是整个流程中最耗时但也最关键的一步。模型最终能有多“聪明”很大程度上取决于你喂给它的数据有多“干净”和“标准”。3.1 数据采集原则首先你需要收集图片。数量上对于每个你想识别的类别建议至少准备200-300张以上的有效图片。质量上要尽可能覆盖你的应用场景多样性不同的光照条件白天、夜晚、阴天、逆光、不同的拍摄角度俯视、平视、侧视、不同的背景环境。代表性图片中的物体应该是你实际应用中会出现的典型状态。例如训练一个检测螺丝的模型就要包含正常、生锈、有油污、部分遮挡的螺丝。分辨率适中图片尺寸不宜过小否则细节丢失也不宜过大否则训练速度慢且可能内存溢出。常见的做法是将图片统一缩放到640x640或1280x1280。YOLOv5-seg的训练代码通常会自动进行缩放和填充。3.2 标注工具选择与使用你需要一个工具来为图片中的每个目标物体绘制多边形轮廓并打上类别标签。这里推荐两个主流工具Labelme开源、跨平台Windows, Linux, Mac界面友好非常适合学术和个人项目。它直接保存为JSON格式包含了多边形的所有顶点坐标。CVAT功能更强大的在线标注系统支持团队协作、视频标注、自动标注等高级功能适合更大型的项目。这里以Labelme为例简述标注过程安装Labelmepip install labelme启动在终端输入labelme打开图形界面。打开图片目录使用“创建多边形”工具沿着物体的边缘依次点击形成一个闭合的多边形。尽量让点与点之间的线段贴合物体边缘对于弯曲的边缘可以多取几个点。闭合多边形后会弹出对话框让你输入标签Label例如person,car,defect等。保存后会生成一个同名的.json文件。3.3 标注格式转换从Labelme JSON到YOLO格式YOLOv5-seg训练需要特定的数据格式。每张图片对应一个.txt标注文件文件中的每一行代表一个实例物体。但这一行的格式与目标检测的[class_id x_center y_center width height]不同它包含了多边形的归一化坐标。一行标注数据的格式为class_id x1 y1 x2 y2 ... xn ynclass_id物体的类别索引从0开始。x1 y1 ... xn yn多边形所有顶点的坐标这些坐标是归一化的即x 像素横坐标 / 图片宽度,y 像素纵坐标 / 图片高度。坐标值在0到1之间。Labelme生成的JSON文件需要被转换成这种格式。你可以使用以下Python脚本进行批量转换。这个脚本是实践中必不可少的工具。import json import os from pathlib import Path def labelme2yolo_seg(json_dir, output_label_dir, class_list): 将Labelme标注的JSON文件转换为YOLO分割格式的txt文件。 Args: json_dir: 存放所有JSON文件的目录路径。 output_label_dir: 输出YOLO格式txt文件的目录路径。 class_list: 类别名称列表如 [person, car, dog]。 json_dir Path(json_dir) output_label_dir Path(output_label_dir) output_label_dir.mkdir(parentsTrue, exist_okTrue) # 创建输出目录 # 构建类别名到索引的映射 class_map {name: idx for idx, name in enumerate(class_list)} # 遍历所有JSON文件 for json_file in json_dir.glob(*.json): with open(json_file, r, encodingutf-8) as f: data json.load(f) image_height data[imageHeight] image_width data[imageWidth] txt_filename output_label_dir / (json_file.stem .txt) lines [] # 处理每个标注形状 for shape in data[shapes]: label_name shape[label] # 检查标签是否在预定义的类别列表中 if label_name not in class_map: print(f警告在文件 {json_file.name} 中发现未知标签 {label_name}已跳过。) continue class_id class_map[label_name] points shape[points] # 这是一个列表每个元素是[x, y] # 将多边形坐标归一化 normalized_points [] for x, y in points: norm_x x / image_width norm_y y / image_height # 确保坐标在[0,1]范围内理论上应该都在 norm_x max(0.0, min(1.0, norm_x)) norm_y max(0.0, min(1.0, norm_y)) normalized_points.extend([norm_x, norm_y]) # 构建YOLO格式的一行class_id x1 y1 x2 y2 ... line f{class_id} .join([f{p:.6f} for p in normalized_points]) lines.append(line) # 将内容写入txt文件 if lines: with open(txt_filename, w, encodingutf-8) as f: f.write(\n.join(lines)) else: # 如果图片中没有目标可以创建一个空文件或者不创建取决于训练代码要求 # 通常YOLO训练可以处理没有标注文件的图片视为负样本 pass print(f转换完成标注文件已保存至{output_label_dir}) # 使用示例 if __name__ __main__: # 你的类别列表必须与标注时使用的标签名一致 my_class_list [cat, dog] # 例如只标注了猫和狗 labelme2yolo_seg( json_dir./labelme_annotations, # 你的JSON文件夹路径 output_label_dir./yolo_labels, # 输出txt文件夹路径 class_listmy_class_list )3.4 数据集目录结构组织转换完成后你需要按照YOLOv5的标准格式组织你的数据集。一个清晰的结构会让后续的配置和训练变得非常简单。my_custom_dataset/ ├── images/ │ ├── train/ │ │ ├── image1.jpg │ │ ├── image2.jpg │ │ └── ... │ └── val/ │ ├── image100.jpg │ ├── image101.jpg │ └── ... └── labels/ ├── train/ │ ├── image1.txt │ ├── image2.txt │ └── ... └── val/ ├── image100.txt ├── image101.txt └── ...images/train/和images/val/分别存放训练集和验证集的图片。labels/train/和labels/val/分别存放对应的YOLO格式标注文件.txt文件名不含后缀必须与图片名严格对应。通常建议按照 8:2 或 7:3 的比例随机划分训练集和验证集。可以使用sklearn.model_selection中的train_test_split函数轻松实现。实操心得在标注阶段最容易出问题的地方就是类别不一致和坐标归一化。第一务必在开始标注前就确定好一个固定的class_list所有标注员都使用这个列表里的名字避免出现“cat”、“Cat”、“小猫”这种同义不同名的情况。第二自己写转换脚本或使用别人的脚本时一定要用几张图片验证一下转换结果是否正确。可以写一个简单的可视化脚本把txt文件里的多边形画回原图上看一看确保坐标没有错乱。这个检查步骤能避免后续训练时出现莫名其妙的损失值异常。4. 环境配置与模型准备工欲善其事必先利其器。准备好数据后我们需要搭建训练环境并获取模型代码。4.1 创建Python虚拟环境强烈建议使用Conda或Python的venv创建一个独立的虚拟环境避免与系统或其他项目的包版本冲突。# 使用conda推荐 conda create -n yolov5_seg python3.8 conda activate yolov5_seg # 或者使用venv python -m venv yolov5_seg_env source yolov5_seg_env/bin/activate # Linux/Mac # yolov5_seg_env\Scripts\activate # Windows4.2 克隆YOLOv5仓库并安装依赖YOLOv5的官方仓库包含了seg分支。我们直接克隆并安装所需依赖。# 克隆仓库 git clone https://github.com/ultralytics/yolov5.git cd yolov5 # 安装依赖 (requirements.txt包含了torch但通常我们单独安装特定版本的torch) pip install -r requirements.txtrequirements.txt会安装诸如opencv-python,pillow,matplotlib,pandas,pyyaml,tqdm,seaborn等常用库。4.3 安装PyTorch这是最关键的一步。你需要根据你的CUDA版本如果你有NVIDIA GPU并希望使用GPU加速来安装对应的PyTorch。前往 PyTorch官网 获取适合你系统的安装命令。 例如对于CUDA 11.8pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118如果没有GPU则安装CPU版本pip install torch torchvision torchaudio安装完成后可以在Python中验证import torch print(torch.__version__) # 查看版本 print(torch.cuda.is_available()) # 查看GPU是否可用应返回True4.4 选择与修改模型配置文件YOLOv5-seg提供了不同大小的预训练模型yolov5s-seg.pt,yolov5m-seg.pt,yolov5l-seg.pt,yolov5x-seg.pt从轻量级s到超大型x精度和速度依次递增模型体积也依次增大。yolov5s-seg模型最小速度最快适合移动端或嵌入式设备部署但精度相对较低。yolov5m-seg平衡了速度和精度是大多数场景下的首选起点。yolov5l-seg / yolov5x-seg精度最高但模型大训练和推理慢需要更强的计算资源。对于自定义数据集我们需要修改模型配置文件中的类别数。配置文件位于./models/目录下例如yolov5s-seg.yaml。我们以yolov5m-seg.yaml为例复制一份配置文件并重命名例如yolov5m-seg-custom.yaml。打开文件找到nc:这一行将其值修改为你数据集的类别数量。例如如果你只分割猫和狗就改为nc: 2。# YOLOv5 by Ultralytics, AGPL-3.0 license # Parameters nc: 2 # 修改这里 number of classes depth_multiple: 0.67 # model depth multiple width_multiple: 0.75 # layer channel multiple anchors: - [10,13, 16,30, 33,23] # P3/8 - [30,61, 62,45, 59,119] # P4/16 - [116,90, 156,198, 373,326] # P5/32 # YOLOv5 v6.0 backbone backbone: # [from, number, module, args] [[-1, 1, Conv, [64, 6, 2, 2]], # 0-P1/2 [-1, 1, Conv, [128, 3, 2]], # 1-P2/4 [-1, 3, C3, [128]], [-1, 1, Conv, [256, 3, 2]], # 3-P3/8 [-1, 6, C3, [256]], [-1, 1, Conv, [512, 3, 2]], # 5-P4/16 [-1, 9, C3, [512]], [-1, 1, Conv, [1024, 3, 2]], # 7-P5/32 [-1, 3, C3, [1024]], [-1, 1, SPPF, [1024, 5]], # 9 ] # YOLOv5 v6.0 head head: [[-1, 1, Conv, [512, 1, 1]], [-1, 1, nn.Upsample, [None, 2, nearest]], [[-1, 6], 1, Concat, [1]], # cat backbone P4 [-1, 3, C3, [512, False]], # 13 [-1, 1, Conv, [256, 1, 1]], [-1, 1, nn.Upsample, [None, 2, nearest]], [[-1, 4], 1, Concat, [1]], # cat backbone P3 [-1, 3, C3, [256, False]], # 17 (P3/8-small) [-1, 1, Conv, [256, 3, 2]], [[-1, 14], 1, Concat, [1]], # cat head P4 [-1, 3, C3, [512, False]], # 20 (P4/16-medium) [-1, 1, Conv, [512, 3, 2]], [[-1, 10], 1, Concat, [1]], # cat head P5 [-1, 3, C3, [1024, False]], # 23 (P5/32-large) [[17, 20, 23], 1, Detect, [nc, anchors]], # Detect(P3, P4, P5) [[17, 20, 23], 1, Segment, [nc, anchors, 32, 256]], # Segment(P3, P4, P5) # 分割头 ]注意看最后两行Detect是检测头Segment就是分割头。我们只需要修改nc参数即可。5. 配置文件详解与训练启动环境好了数据齐了模型也配置了现在需要告诉训练脚本去哪里找数据以及如何训练。5.1 创建数据配置文件在YOLOv5目录下或任何方便的位置创建一个YAML文件例如my_dataset.yaml。这个文件定义了数据集的路径、类别名等信息。# my_dataset.yaml # 训练和验证图像的路径相对于当前yaml文件或绝对路径 path: /home/user/datasets/my_custom_dataset # 数据集的根目录 train: images/train # 训练集图片路径相对于 path val: images/val # 验证集图片路径相对于 path # 类别数量 nc: 2 # 与模型配置文件中的 nc 保持一致 # 类别名称列表 names: [cat, dog] # 必须与标注时的 class_list 顺序一致索引0对应‘cat’索引1对应‘dog’path: 数据集根目录的绝对路径或相对路径。train/val: 训练集和验证集图片所在的子目录相对于path。nc和names: 必须与之前模型配置文件和标注转换脚本中的类别定义完全一致。5.2 启动训练命令一切就绪使用train.py脚本开始训练。以下是一个典型的训练命令包含了最常用的参数python train.py \ --weights yolov5m-seg.pt \ # 使用预训练权重强烈推荐能加速收敛提升精度。 --cfg models/yolov5m-seg-custom.yaml \ # 使用我们修改过的模型配置文件 --data my_dataset.yaml \ # 使用我们创建的数据配置文件 --epochs 100 \ # 训练总轮数根据数据集大小调整通常100-300 --batch-size 16 \ # 批次大小根据GPU内存调整。越大越好但受限于显存。 --imgsz 640 \ # 输入图像尺寸默认640。增大可提升精度但消耗更多资源。 --workers 8 \ # 数据加载的进程数用于加速数据读取。 --name my_first_seg_exp \ # 本次实验的名称用于保存结果目录 --project runs/train \ # 结果保存的根目录 --save-period 10 \ # 每N个epoch保存一次检查点 --device 0 # 使用哪块GPU如果是CPU则用 --device cpu参数解析与调优建议--weights:务必使用预训练权重。yolov5m-seg.pt是在COCO数据集上预训练好的包含了丰富的通用特征能让你在小数据集上更快地获得好结果。这是迁移学习的核心。--batch-size: 这是影响训练稳定性和速度的关键参数。在GPU显存允许的情况下尽可能设大。如果出现“CUDA out of memory”错误就减小这个值如16-8。也可以尝试使用--batch-size -1来自动寻找最大可用批次大小。--imgsz: 默认640对于大多数场景足够。如果你的目标物体非常小或者需要精细的边缘可以尝试增大到1280但训练时间和显存消耗会显著增加。--epochs: 不是越大越好。观察验证集指标如mask mAP当指标不再显著上升甚至开始下降时过拟合就可以提前停止训练。可以使用--patience参数设置早停。--workers: 设置为CPU核心数左右可以加快数据加载避免训练时GPU等待数据。执行命令后训练就开始了。你会看到终端输出每个epoch的损失值、评估指标等信息。所有训练日志、模型权重、可视化结果都会保存在runs/train/my_first_seg_exp/目录下。6. 训练过程监控与结果解读训练启动后我们不能干等着。理解训练过程中的输出和生成的结果文件对于判断模型状态、调整超参数至关重要。6.1 终端输出日志解读训练开始后终端会滚动显示信息。一个epoch结束后通常会输出如下格式的信息Epoch gpu_mem box_loss obj_loss cls_loss seg_loss targets img_size 0/99 7.12G 0.09523 0.02345 0.00891 0.15678 32 640: ...gpu_mem: GPU显存使用情况。box_loss,obj_loss,cls_loss,seg_loss: 分别是边界框回归损失、目标置信度损失、分类损失和分割损失。关注它们的下降趋势。训练初期所有损失都应快速下降随后逐渐平缓。如果某个损失特别是seg_loss异常高或波动剧烈可能预示着数据标注或配置有问题。targets: 当前批次中检测到的目标数量平均值。每隔几个epoch会在验证集上评估一次输出类似Class Images Instances Box(P R mAP50 mAP50-95) Mask(P R mAP50 mAP50-95): all 100 1500 0.856 0.792 0.842 0.601 0.821 0.763 0.812 0.523 cat 100 750 0.881 0.805 0.867 0.632 0.845 0.778 0.834 0.561 dog 100 750 0.831 0.779 0.817 0.570 0.797 0.748 0.790 0.485这是最关键的性能指标Box(P/R/mAP...): 目标检测部分的性能。Mask(P/R/mAP...):实例分割部分的性能这是我们最关心的。P(Precision): 精度模型预测为正的样本中真正为正的比例。越高说明误报越少。R(Recall): 召回率所有真实的正样本中被模型预测出来的比例。越高说明漏报越少。mAP50: 在IoU交并比阈值为0.5时的平均精度mean Average Precision。这是最常用的综合指标值在0到1之间越高越好。mAP50-95: 在IoU阈值从0.5到0.95步长0.05区间内mAP的平均值。这是一个更严格的指标要求预测框/掩码与真实框/掩码的重合度更高。6.2 生成的结果文件分析训练结束后runs/train/my_first_seg_exp/目录下会生成一系列文件weights/: 存放模型权重。best.pt是验证集上表现最好的权重last.pt是最后一个epoch的权重。部署时通常使用best.pt。results.png/results.csv: 训练过程的指标曲线图和数据表。这是分析训练过程的核心。损失曲线观察所有损失是否平滑下降至收敛。如果训练损失持续下降但验证损失上升可能是过拟合。精度召回率曲线观察它们在训练过程中的变化趋势是否达到一个平衡的较高值。mAP曲线关注metrics/mAP50(B)和metrics/mAP50-95(B)检测以及metrics/mAP50(M)和metrics/mAP50-95(M)分割。分割的mAP(M)是我们的核心指标。confusion_matrix.png: 混淆矩阵可视化模型在各个类别上的分类错误情况。理想情况下对角线正确分类应该最亮。val_batchX_labels.jpg/val_batchX_pred.jpg: 验证集批次的可视化结果。labels显示真实标注pred显示模型预测。这是最直观的检查方式可以立刻看到模型在哪些图片上表现好哪些图片上分割效果差如边缘粗糙、漏检、误检。6.3 超参数调优浅析如果第一次训练结果不理想除了检查数据还可以调整超参数。YOLOv5的超参数定义在data/hyps/hyp.scratch-low.yaml等文件中。你可以复制一份进行修改并通过--hyp参数指定。lr0: 初始学习率。如果损失震荡大可以调小如从0.01调到0.001如果收敛太慢可以适当调大。warmup_epochs: 学习率热身epoch数。在训练初期使用较低的学习率有助于稳定训练。优化器、数据增强参数等也可以调整。但对于新手建议先使用默认超参数把重心放在确保数据质量和模型结构正确上。默认超参数是作者团队在大量实验中总结出来的对于大多数情况都是一个很好的起点。实操心得不要只看最后的mAP数字一定要看可视化结果val_batchX_pred.jpg有时候mAP看起来不错但可视化发现分割边缘全是锯齿或者小目标根本检不出来。通过可视化你能快速定位问题是标注不准确是目标太小还是类别不平衡此外训练时建议开启TensorBoard--logger tensorboard可以更灵活地实时监控曲线对比。7. 模型验证、推理与部署训练完成后我们得到了一个best.pt文件。接下来就是检验其成色并把它用起来。7.1 模型验证使用val.py脚本在独立的测试集如果你预留了的话或验证集上对最终模型进行系统评估。python val.py \ --weights runs/train/my_first_seg_exp/weights/best.pt \ --data my_dataset.yaml \ --img 640 \ --batch-size 16 \ --task test \ # 如果是测试集需要修改data.yaml中的路径或这里指定--data --name final_eval \ --project runs/val这会生成一份详细的评估报告包含各个类别的P、R、mAP等指标以及混淆矩阵、PR曲线等可视化结果保存在runs/val/final_eval目录下。7.2 使用训练好的模型进行推理这是最有成就感的环节。使用detect.py脚本用你自己的模型对新的图片或视频进行预测。# 对单张图片进行推理 python detect.py \ --weights runs/train/my_first_seg_exp/weights/best.pt \ --source path/to/your/test_image.jpg \ --img 640 \ --conf 0.25 \ # 置信度阈值高于此值的预测才会被显示 --save-txt \ # 保存预测结果的txt文件YOLO格式 --save-conf \ # 在txt文件中保存置信度 --save-crop \ # 保存裁剪出的目标区域 --hide-labels \ # 隐藏标签 --hide-conf # 隐藏置信度 # 对整个文件夹的图片进行推理 python detect.py --weights best.pt --source path/to/images/ # 对视频进行推理 python detect.py --weights best.pt --source path/to/video.mp4 # 使用摄像头实时推理 python detect.py --weights best.pt --source 0预测结果默认会保存在runs/detect/exp/目录下图片或视频上会绘制出彩色的分割掩码和边界框。7.3 模型导出与部署为了在不同平台部署我们需要将PyTorch模型.pt转换为更通用的格式。YOLOv5提供了强大的导出功能。python export.py \ --weights runs/train/my_first_seg_exp/weights/best.pt \ --img 640 \ --batch 1 \ --include onnx engine \ # 导出为ONNX和TensorRT引擎。也可以选择 torchscript, coreml等 --device 0ONNX: 一种开放的模型格式被众多推理引擎如OpenVINO, ONNX Runtime, TensorRT支持。导出后得到一个.onnx文件。TensorRT: NVIDIA的高性能深度学习推理SDK。通过export.py可以直接导出为TensorRT引擎.engine在NVIDIA GPU上能获得极致的推理速度。这通常需要先安装TensorRT。其他格式如TorchScript.torchscript用于PyTorch生态CoreML.mlmodel用于苹果设备。导出后你就可以使用对应的推理库加载模型集成到你的C、Python或各种边缘计算应用中。8. 常见问题排查与实战技巧在实际操作中你几乎一定会遇到各种“坑”。这里汇总了一些典型问题及其解决方案。8.1 训练损失为NaN或突然变得巨大可能原因1学习率过高。这是最常见的原因。尝试大幅降低学习率在hyp.yaml中修改lr0例如从0.01降至0.001或使用更小的预训练模型如从yolov5l换到yolov5m。可能原因2数据标注错误。检查标注文件.txt中归一化坐标是否超出[0,1]范围。使用3.3节提到的可视化脚本进行排查。可能原因3批次大小Batch Size过大导致梯度爆炸。尝试减小--batch-size。可能原因4数据中存在极端异常值。检查图片尺寸是否差异巨大或某些标注多边形点数异常多。8.2 模型精度mAP很低或分割效果很差检查数据质量这是根本。确保标注足够精确多边形紧贴物体边缘。对于小物体标注更要精细。查看val_batchX_pred.jpg看是普遍性问题还是个别类别问题。类别不平衡如果某个类别的图片数量远少于其他类别模型会偏向于多数类。解决方案1收集更多该类别数据2使用数据增强专门针对该类别3在损失函数中为少数类设置更高的权重需要修改代码较复杂。数据增强不足或过度YOLOv5默认开启了较强的数据增强Mosaic, MixUp等。如果数据集本身很小增强有助于防止过拟合。但如果数据集质量不高或非常特殊过强的增强可能有害。可以尝试在train.py中加上--noaug关闭增强看看效果。模型容量不足或过大对于简单场景yolov5s可能就够了对于复杂场景、小目标或需要精细边缘可能需要yolov5l或yolov5x。反之如果数据集很小大模型容易过拟合。输入尺寸imgsz不合适如果目标物体在原始图片中占比很小尝试增大--imgsz如从640到1280让模型“看”得更清楚。8.3 训练速度非常慢确认GPU是否启用检查torch.cuda.is_available()是否为True。训练时终端第一行应显示“Using CUDA device0...” 。调整--workers将其设置为CPU核心数附近的值如4, 8, 16可以加快数据加载。使用更小的模型或输入尺寸yolov5s比yolov5x快得多imgsz320比imgsz640快。检查磁盘IO如果图片数据放在慢速硬盘上数据加载可能成为瓶颈。尝试将数据集复制到SSD上。8.4 推理时分割掩码边缘粗糙或有锯齿后处理问题YOLOv5-seg输出的掩码分辨率通常较低默认是160x160的原图下采样。在detect.py中有一个--mask-ratio参数或相关后处理代码控制掩码上采样回原图大小的方式。可以尝试更平滑的上采样算法。模型本身限制由于网络结构的设计分割头的输出分辨率有限。对于要求极高边缘精度的场景可能需要换用专门的分割模型如U-Net, DeepLab或者尝试YOLOv8-seg它在分割头设计上可能有所改进。训练数据标注边缘不光滑检查你的标注多边形是否本身就有很多锯齿。在Labelme中标注时对于曲线区域点可以取得密一些。8.5 如何提高小目标的分割精度小目标是实例分割的常见难点。数据层面确保小目标在数据集中有足够的数量和质量。标注要格外仔细。增大输入尺寸这是最有效的方法之一。将--imgsz从640提高到1280甚至更高能为小目标提供更多像素信息。修改模型锚框AnchorYOLOv5默认的锚框是针对COCO数据集设计的。如果你的小目标尺寸与COCO差异很大可以针对你的数据集重新聚类生成锚框。使用utils/autoanchor.py脚本。聚焦损失函数可以尝试使用Focal Loss来让模型更关注难分的样本如小目标但这需要修改代码。8.6 增量训练在已有模型上继续训练当你有了新的标注数据不想从头训练时可以使用增量训练。python train.py \ --weights runs/train/previous_exp/weights/last.pt \ # 加载上次训练的最后权重 --data my_dataset.yaml \ --epochs 50 \ # 新的训练轮数 --resume # 这个参数很重要会尝试加载优化器状态、学习率调度器等使训练连续注意新数据最好与旧数据分布一致。如果分布变化很大可能效果不佳甚至导致“灾难性遗忘”。从YOLOv5目标检测到YOLOv5-seg实例分割你迈出了从“知道物体在哪”到“知道物体具体形状”的关键一步。这个过程的核心与其说是调参炼丹不如说是对你自己业务数据的深入理解和细致打磨。数据决定了模型能力的上限而工程技巧只是让我们不断逼近这个上限。当你看到自己训练的模型精准地勾勒出你关心的物体轮廓时那种满足感是对所有繁琐准备工作的最好回报。记住第一次训练结果不理想是常态耐心地分析可视化结果、检查数据、有方向地调整比盲目增加训练轮数有效得多。这套流程不仅适用于YOLOv5-seg其数据准备、训练监控、问题排查的思路对于你未来接触任何深度学习视觉任务都是一笔宝贵的财富。
返回列表