尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

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

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

YOLOv5-seg实例分割实战:从数据标注到模型部署全流程详解 1. 从YOLOv5到YOLOv5-seg为什么选择它来做实例分割如果你用过YOLOv5做目标检测并且觉得它又快又好那么当你需要更进一步不仅要“框出”物体还要“抠出”物体的精确轮廓时YOLOv5-seg就是那个最顺手的升级选项。我最初接触实例分割任务时也考虑过Mask R-CNN这类经典的两阶段网络但最终选择YOLOv5-seg核心原因就一个在保证相当精度的前提下它把部署和迭代的效率拉满了。YOLOv5-seg并不是一个全新的模型它更像是YOLOv5目标检测框架的一个“官方插件”。它的主干网络、Neck部分和YOLOv5-det检测版本基本一致主要区别在于Head部分。检测版本的Head输出的是边界框Bounding Box的坐标、置信度和类别概率而分割版本的Head在输出这些信息的同时还并行输出了一个掩码Mask分支。这个掩码分支会为每个检测到的目标生成一个低分辨率的原型掩码Prototype Mask再通过一个类似上采样的过程与网络中间层的特征图进行融合最终生成与输入图像同分辨率的二值分割掩码。听起来有点绕你可以这么理解YOLOv5-seg的检测头负责“找到并分类物体”而新增的分割头则像一个“精细的画笔”根据检测头提供的位置信息在那个小区域内把物体的轮廓“画”出来。这种设计带来的好处非常直接训练和推理速度快由于共享了绝大部分特征提取的计算增加分割头带来的额外计算开销相对较小。相比Mask R-CNN那种先提候选框再对每个框做分割的串行流程YOLOv5-seg的并行化设计在速度上优势明显。实测下来在相同硬件上YOLOv5-seg的推理速度通常是Mask R-CNN的2-3倍。部署极其友好YOLOv5的工程化做得非常出色提供了完整的PyTorch训练到ONNX、TensorRT等格式导出的链路。YOLOv5-seg完全继承了这一点。你可以用熟悉的PyTorch训练完模型然后几乎不改动代码就能导出为ONNX并部署到NVIDIA Jetson、安卓手机或者各种边缘计算设备上。这对于需要落地的工业项目来说省去了大量的适配工作。生态和资料丰富YOLOv5拥有庞大的社区和数不清的教程、预训练模型。YOLOv5-seg作为其一部分可以无缝享用这些资源。当你遇到问题时更容易找到解决方案和参考代码。当然它也有其局限性。YOLOv5-seg生成的分割掩码分辨率通常不如一些专门的高精度分割模型如DeepLabV3对于边界极其复杂、或者目标非常小的物体细节可能会丢失。但对于大多数工业质检、遥感图像分析、自动驾驶感知如可行驶区域分割等场景它的精度已经足够而速度优势则是决定性的。所以当你手头有一个自定义的数据集需要快速实现一个既能检测又能精确分割的模型时YOLOv5-seg几乎是一个“开箱即用”的最佳选择。接下来我就以一次完整的工业零件分割项目为例带你走通从数据准备到模型训练、再到结果评估的全过程。2. 数据准备比标注更重要的“预处理”与格式转换训练自己的数据集八成的工作量和坑都在数据准备阶段。很多人以为标注完就万事大吉其实数据的组织形式、标注的质量和格式转换直接决定了模型训练的天花板。我这次用的数据集是大约2000张工业零件图像任务是分割出零件上的特定区域如螺丝孔、磨损面。2.1 数据标注工具与规范工欲善其事必先利其器。对于实例分割标注工具首推Roboflow或Label Studio。它们都支持多边形Polygon标注这是生成分割掩码的基础。我更喜欢用Label Studio因为它开源、可私有化部署并且标注界面非常灵活。在标注时有以下几个经验性的规范能极大提升后续训练效果标注一致性这是最重要的原则。同一个物体在不同图像中的标注精细度要一致。比如对于零件边缘不能这张图标得毛毛糙糙下一张又标得光滑无比。建议团队内部先统一标注标准甚至可以制作一些标注范例。紧贴边缘多边形点要尽可能地紧贴物体真实边缘。特别是对于不规则物体点可以密一些在弯曲处多打几个点。YOLOv5-seg最终学习的就是这些点的位置所围成的形状。处理遮挡与粘连当多个同类物体部分重叠时必须将它们分开标注成不同的实例。即使重叠部分很大也要尽最大努力根据可见部分勾勒出各自的轮廓。模型需要学习“这是一个独立个体”的概念。背景与困难样本不要只标注“明显好认”的物体。对于一些模糊的、部分出镜的、或者光照很差的物体也要进行标注。这些“困难样本”能增强模型的鲁棒性。同时确保图像中不存在大量未标注的同类物体否则模型会困惑。标注完成后Label Studio可以导出为COCO JSON格式。COCO格式是当前实例分割领域的事实标准它包含了图像信息、标注信息类别、边界框、分割多边形点集的完整结构。2.2 从COCO到YOLO格式的转换逻辑YOLOv5-seg训练所需的数据格式是YOLO格式的一个扩展。它需要两种类型的标签文件.txt文件每个图像对应一个同名的txt文件。每一行代表一个物体实例格式为class_id x1 y1 x2 y2 ... xn ynclass_id物体的类别索引从0开始。x1 y1 x2 y2 ... xn yn归一化的多边形点坐标。注意这里的坐标不是边界框而是分割多边形的所有顶点坐标。x和y都需要除以图像的宽度和高度进行归一化值在0到1之间。segmentation信息实际上上述的坐标序列就是分割信息本身。YOLOv5-seg直接读取这些归一化的多边形点来学习分割。因此我们需要将COCO JSON格式转换为YOLO格式的txt文件。网上有很多转换脚本但很多都有隐藏的坑。我推荐使用YOLOv5官方仓库中utils文件夹下的脚本或者自己写一个以确保可控。转换的核心步骤如下解析COCO JSON获取images和annotations列表。遍历每张图像找到其对应的所有标注annotation。对于每个标注获取其category_id和segmentation字段。segmentation是一个列表其中每个元素是一个多边形点列表[x1, y1, x2, y2, ...]。将多边形点的绝对坐标分别除以图像的width和height进行归一化。将category_id通常COCO从1开始转换为从0开始的索引。将class_id和归一化后的坐标序列写入到{image_name}.txt文件中一行一个实例。这里有一个关键点COCO的segmentation字段对于单个物体可能包含多个多边形如果物体中间有洞。YOLOv5-seg也支持这种“带洞”的标注。在转换时你需要将多个多边形序列按顺序拼接在一起写入同一行。在YOLO格式中它们被依次排列。模型会识别这种结构。2.3 数据集目录结构的组织清晰规范的目录结构是避免后续路径错误的基础。我建议的目录结构如下your_dataset/ ├── images/ │ ├── train/ │ │ ├── image1.jpg │ │ └── ... │ └── val/ │ ├── image1001.jpg │ └── ... └── labels/ ├── train/ │ ├── image1.txt │ └── ... └── val/ ├── image1001.txt └── ...images/train和images/val分别存放训练集和验证集的图像。labels/train和labels/val分别存放对应的YOLO格式标签文件。图像和标签文件的名称不含后缀必须严格一致。准备好这个结构后你还需要创建一个数据集配置文件例如dataset.yaml内容如下# dataset.yaml path: /path/to/your_dataset # 数据集根目录 train: images/train # 训练集图像相对路径 val: images/val # 验证集图像相对路径 # 类别名称和数量 nc: 2 # 类别数例如我的零件数据集有2类 names: [part_A, part_B] # 类别名称列表顺序与class_id对应这个yaml文件是连接你的数据和训练脚本的桥梁。注意在划分训练集和验证集时通常按照8:2或9:1的比例。更重要的是要确保验证集能代表真实场景的分布。如果数据有批次、光照、背景的变化尽量让这些变化在训练集和验证集中都有体现避免验证集过于“简单”或“特殊”导致评估结果失真。3. 环境搭建与模型选择避开版本依赖的“暗礁”YOLOv5的生态迭代很快不同版本之间的代码和依赖可能有细微差别直接git clone最新版然后pip install -r requirements.txt看似简单却最容易出问题。尤其是涉及到PyTorch、CUDA和一些自定义算子如NMS时。3.1 创建隔离的Python环境第一步永远是创建独立的虚拟环境。这能保证你的项目依赖不会污染系统环境也方便管理多个不同版本的项目。conda create -n yolov5_seg python3.8 # 推荐Python 3.8兼容性好 conda activate yolov5_seg3.2 克隆与安装特定版本YOLOv5的master分支可能包含未稳定的特性。对于生产或严肃的实验我建议使用一个稳定的发布版本标签。你可以去GitHub仓库的Release页面查看。git clone https://github.com/ultralytics/yolov5.git cd yolov5 # 查看标签选择一个稳定的例如 v7.0 git checkout tags/v7.0然后安装依赖。这里有个大坑requirements.txt里的torch和torchvision通常是CPU版本或者可能和你的CUDA版本不匹配。最好的做法是先根据你的CUDA版本去PyTorch官网获取正确的安装命令。假设你的CUDA版本是11.3可以这样安装pip install torch1.12.1cu113 torchvision0.13.1cu113 --extra-index-url https://download.pytorch.org/whl/cu113安装完PyTorch后再安装其他依赖pip install -r requirements.txt这样能最大程度避免因PyTorch版本问题导致的编译错误或运行时错误。3.3 模型选择YOLOv5s-seg vs. YOLOv5m-seg vs. YOLOv5l-segYOLOv5提供了多种尺寸的预训练模型从轻量级的YOLOv5n-seg到大型的YOLOv5x-seg。选择哪个取决于你的数据量、任务复杂度和对速度/精度的权衡。YOLOv5s-seg参数量最小速度最快。适合移动端/边缘设备部署或者数据量很小几百张、物体特征明显的简单场景。如果精度不达标这是第一个可以放弃的选项。YOLOv5m-seg我最常使用的起点。它在速度和精度之间取得了很好的平衡。对于大多数自定义数据集几千张图像几个到十几个类别从YOLOv5m-seg开始微调通常能得到不错的结果。它是一个可靠的“基线模型”。YOLOv5l-seg和YOLOv5x-seg参数量大精度潜力高但训练和推理速度慢且更容易过拟合。只有当你的数据集很大上万张、类别多、物体小且密集、或者对精度有极致要求时才考虑使用。并且需要配合更强大的正则化手段如更大幅度的数据增强、DropOut等。一个实用的策略是先用YOLOv5m-seg快速跑通整个流程得到一个基准结果。如果精度不够再尝试用更大的模型或者回过头来优化数据质量和训练策略。不要一开始就追求最大的模型。预训练模型可以从YOLOv5的官方GitHub Release页面下载或者训练脚本会自动下载。对于分割任务务必下载带有-seg后缀的模型文件例如yolov5m-seg.pt。这些模型是在COCO数据集上预训练好的其骨干网络已经学会了提取通用特征这对我们微调自己的数据集至关重要。4. 训练配置与核心参数解析训练脚本的核心命令看起来简单但里面的每一个参数都影响着模型的最终性能。以YOLOv5m-seg为例一个完整的训练命令可能如下python segment/train.py \ --data dataset.yaml \ --weights yolov5m-seg.pt \ --img 640 \ --batch-size 16 \ --epochs 100 \ --name my_part_seg_exp \ --project runs/train \ --device 0 \ --workers 8 \ --optimizer AdamW \ --lr0 0.01 \ --cos-lr下面我们来拆解其中最关键的几个参数并解释我为什么这样设置4.1 数据与模型参数--data dataset.yaml指定我们之前准备好的数据集配置文件路径。--weights yolov5m-seg.pt指定预训练模型的路径。使用预训练权重进行迁移学习是快速收敛的关键。--img 640输入图像的长边会被缩放到这个尺寸保持宽高比短边会进行填充padding以达到正方形。640是一个在精度和速度之间平衡的常用值。如果你的目标物体都非常小可以尝试增大到1024甚至1280但这会显著增加显存消耗和训练时间。--batch-size 16批次大小。这是最影响显存占用的参数。在显存允许的前提下较大的batch size如16, 32通常能使训练更稳定梯度估计更准确。你需要根据你的GPU显存来调整。如果出现CUDA out of memory错误就减小这个值或者尝试使用--multi-scale训练动态调整输入尺寸但会慢一些。4.2 优化器与学习率策略--optimizer AdamW优化器选择。YOLOv5默认使用SGD但我个人在分割任务上更倾向于AdamW。AdamW对于学习率不那么敏感在初始阶段收敛更快尤其适合我们这种基于预训练模型的微调场景。SGD配合精调的学习率衰减策略最终可能达到略好的精度但AdamW更容易上手且稳定。--lr0 0.01初始学习率。这是一个需要谨慎调整的参数。对于微调学习率不宜过大。使用预训练模型时网络权重已经在一个很大的数据集COCO上得到了良好的初始化。我们只是在小数据集上对其进行“微调”。过大的学习率会“冲毁”这些预训练好的特征。我通常从0.01开始对于AdamW如果训练过程中损失出现NaN或者震荡会降低到0.001或0.0001。对于SGD可以从0.01或0.001开始尝试。--cos-lr使用余弦退火学习率调度器。这是我强烈推荐开启的选项。它让学习率随着训练过程从初始值平滑地衰减到0遵循余弦曲线。这种策略通常比简单的阶梯式下降step decay能获得更好的模型性能和更稳定的收敛。4.3 数据增强与正则化YOLOv5内置了强大的数据增强管道这对于防止过拟合、提升模型泛化能力至关重要。相关参数主要在data/hyps/hyp.scratch-low.yaml等超参数文件中定义也可以在命令行覆盖。几个关键增强包括Mosaic将四张训练图像拼接成一张进行训练。这能极大地增加模型看到不同上下文和尺度的机会是YOLO系列性能强大的秘诀之一。通常默认开启。MixUp将两张图像以一定比例混合。也是一种非常有效的正则化手段。随机透视、缩放、平移、旋转模拟拍摄物体时的视角和位置变化。色彩空间增强调整HSV空间的色调、饱和度和明度模拟光照变化。对于自定义数据集数据增强的强度需要根据数据特点调整。如果你的数据本身变化就很大如不同角度、光照的工业零件可以适当降低增强强度如减小旋转、缩放的范围。如果你的数据比较单一则需要更强的增强来模拟真实世界的多样性。一个常见的错误是在数据已经足够复杂的情况下仍然使用过强的增强导致模型学习困难。4.4 训练监控与日志训练开始后YOLOv5会在--project指定的目录下如runs/train/my_part_seg_exp生成大量有用的文件weights/best.pt训练过程中在验证集上表现最好的模型权重。weights/last.pt最后一个epoch的模型权重。results.csv和results.png记录每个epoch的训练损失、验证损失、精度mAP0.5, mAP0.5:0.95、分割指标mask mAP等。这是你诊断训练过程最重要的依据。confusion_matrix.png混淆矩阵查看各类别间的误检情况。val_batch0_pred.jpg验证集第一批次的预测结果可视化可以直观地看到模型当前的表现。训练时要密切关注results.png中的曲线训练损失平稳下降验证损失也同步下降这是理想情况。训练损失下降但验证损失上升或持平这是典型的过拟合迹象。需要增强正则化如增加数据增强、使用DropOut、减小模型容量或者收集更多样化的训练数据。训练损失震荡剧烈可能是学习率设置过高或者batch size太小。尝试降低学习率或增大batch size。5. 评估与调优不仅仅是看mAP训练完成后我们得到了一个best.pt模型。是骡子是马得拉出来溜溜。评估不仅仅是跑一个脚本看分数更需要深入分析模型在哪里犯了错。5.1 核心评估指标解读使用以下命令进行验证python segment/val.py --data dataset.yaml --weights runs/train/my_part_seg_exp/weights/best.pt --img 640脚本会输出一系列指标其中最重要的几个是mAP0.5 (mAP_0.5)在交并比IoU阈值为0.5时的平均精度Average Precision。这是最常用的指标可以理解为“框得大概正确”的精度。对于分割任务这里计算的是基于掩码IoU的mAP。mAP0.5:0.95 (mAP_0.5:0.95)在IoU阈值从0.5到0.95步长0.05上计算的平均mAP。这是一个更严格的指标要求预测的掩码与真实掩码重叠度更高。这个指标更能反映分割边界的精确度。如果你的应用对轮廓精度要求高应该主要关注这个指标。Mask Precision Mask Recall掩码级别的精确率和召回率。精确率Precision高说明模型预测出的正样本中真实的正样本比例高误报少召回率Recall高说明模型找出了大部分的真实目标漏报少。通常需要在两者之间权衡。5.2 可视化分析与错误排查指标只是一个数字更重要的是知道模型错在哪里。YOLOv5的验证脚本会生成一系列可视化结果val_batchX_labels.jpg和val_batchX_pred.jpg对比显示真实标签和模型预测。这是最直接的诊断工具。漏检False Negative真实存在的物体没有被检测/分割出来。可能原因物体太小考虑减小--img尺寸不对应该增大尺寸或使用更密集的特征金字塔、物体与背景对比度低数据增强中加强色彩扰动、训练数据中该类样本不足。误检False Positive背景或其他物体被错误地预测为目标。可能原因背景中存在与目标相似的纹理或形状需要更多包含复杂背景的负样本、模型置信度阈值过低在推理时可以提高--conf-thres。分割边界不准确框住了物体但掩码边界粗糙或偏离。可能原因标注本身就不够精细回溯数据质量、模型容量不足换用更大的模型如YOLOv5l-seg、用于分割的特征图分辨率不够尝试修改模型结构这比较复杂通常不推荐初学者做。confusion_matrix.png混淆矩阵。主要看非对角线上的亮斑。如果A类别经常被预测为B类别说明这两个类别在视觉上可能比较相似需要检查数据或者考虑在数据增强时专门针对这两个类别做文章或者增加它们之间的差异特征但这属于高级技巧了。5.3 基于分析的迭代调优根据可视化分析的结果进行有针对性的调优这是一个迭代过程针对漏检首先检查训练集中该类别的样本数量是否足够。如果不足可以进行数据增强如复制、旋转、颜色变换来增加该类别样本的多样性。其次可以尝试在训练时调整--cls损失权重在超参数文件中给难以学习的类别更高的权重但需谨慎使用。针对误检在推理时提高置信度阈值--conf-thres默认0.25可以尝试0.3, 0.4。如果误检物体有规律如总是把某种阴影预测为零件可以考虑在数据集中加入更多包含这种干扰物的图像并明确标注为背景即不加任何标注。针对分割不精这是实例分割的难点。除了检查标注质量可以尝试使用更大的输入分辨率--img 1024。这能为分割头提供更高分辨率的特征但代价是显存和速度。尝试更大的模型YOLOv5l-seg。更大的模型有更强的特征提取和细节保持能力。调整分割损失权重在超参数文件如hyp.scratch-low.yaml中有box_loss_gain,cls_loss_gain,dfl_loss_gain对于分割任务还有一个mask_loss_gain。适当提高mask_loss_gain比如从默认值提高1.5倍可以让模型在训练时更关注分割精度的优化。这是一个进阶技巧调整后需要重新训练观察效果。记住没有一劳永逸的参数。最好的模型是建立在高质量的数据和基于对错误的深刻理解进行的持续调优之上的。6. 模型推理与部署实战模型训练和评估满意后下一步就是让它真正“跑起来”处理新的图像或视频。YOLOv5-seg提供了非常便捷的推理脚本。6.1 使用Python脚本进行推理与可视化最基本的推理命令如下python segment/predict.py --weights runs/train/my_part_seg_exp/weights/best.pt --source path/to/your/test_image.jpg --conf-thres 0.25 --iou-thres 0.45 --hide-labels --hide-conf--source可以是一张图片、一个包含图片的文件夹、一个视频文件、或者0代表摄像头。--conf-thres置信度阈值。高于此值的检测框才会被保留。根据之前验证的结果调整在减少误报和避免漏报之间取得平衡。--iou-thres非极大值抑制NMS的IoU阈值。用于合并重叠的预测框。默认0.45通常效果不错。--hide-labels和--hide-conf隐藏标签和置信度让可视化结果更干净。但更多时候我们需要将推理集成到自己的Python项目中。下面是一个更灵活的示例脚本import cv2 import torch from pathlib import Path # 加载模型 model torch.hub.load(ultralytics/yolov5, custom, pathruns/train/my_part_seg_exp/weights/best.pt, force_reloadFalse) model.conf 0.25 # 置信度阈值 model.iou 0.45 # NMS IoU阈值 # 推理单张图片 img_path test.jpg results model(img_path) # 结果解析 # results.pandas().xyxy[0] # Pandas格式的检测框信息 (x1, y1, x2, y2, confidence, class, name) # results.xyxy[0] # Tensor格式的检测框信息 # results.masks # 分割掩码信息 # 获取原始图像上的掩码布尔矩阵 if results.masks is not None: masks results.masks.data # [N, H, W] 其中N是检测到的目标数 boxes results.xyxy[0] # [N, 6] (x1, y1, x2, y2, conf, cls) # 遍历每个检测到的目标 for i, (mask, box) in enumerate(zip(masks, boxes)): # 将mask转换为0-255的灰度图方便可视化或保存 mask_np mask.cpu().numpy().astype(uint8) * 255 # 可以根据box裁剪出ROI区域的掩码 x1, y1, x2, y2 map(int, box[:4]) roi_mask mask_np[y1:y2, x1:x2] # 保存掩码 cv2.imwrite(fmask_{i}.png, mask_np) cv2.imwrite(froi_mask_{i}.png, roi_mask) # 直接生成带标注的可视化图像 results.render() # 在原图上绘制框和掩码 for img in results.imgs: cv2.imshow(Result, img) cv2.waitKey(0) cv2.destroyAllWindows()这个脚本展示了如何加载模型、进行推理、以及如何从结果中提取原始的分割掩码数据。你可以将这些掩码用于后续的计算比如计算像素面积、分析形状特征等。6.2 模型导出迈向生产部署要将模型部署到生产环境如服务器、嵌入式设备通常需要将其转换为更高效的推理格式。YOLOv5支持一键导出为多种格式。导出为ONNX格式python export.py --weights runs/train/my_part_seg_exp/weights/best.pt --include onnx --img 640 --batch-size 1 --dynamic--include onnx指定导出为ONNX格式。--img 640指定模型的输入尺寸必须与训练时一致。--batch-size 1指定批处理大小对于部署常设为1。--dynamic允许动态的输入尺寸batch, height, width维度。如果部署时输入尺寸固定可以不加此参数性能会稍好。ONNX模型可以被 OpenCV DNN、ONNX Runtime、TensorRT 等多种推理引擎加载跨平台性非常好。导出为TensorRT引擎针对NVIDIA GPUpython export.py --weights runs/train/my_part_seg_exp/weights/best.pt --include engine --img 640 --batch-size 1 --device 0这需要你的环境已安装TensorRT。导出的.engine文件在NVIDIA GPU上能获得极致的推理速度。6.3 部署中的性能优化与坑点在实际部署中你可能会遇到以下问题速度不达标首先检查是否使用了TensorRT或ONNX Runtime等优化后的推理后端。其次可以尝试降低输入图像分辨率--img 480但这会牺牲精度。还可以尝试使用更小的模型如从YOLOv5m-seg换到YOLOv5s-seg。显存占用过高在导出时指定--batch-size 1。在推理时确保没有不必要地保留中间变量。对于视频流处理可以考虑使用管道化pipeline来重叠数据预处理和推理时间。分割掩码后处理耗时results.masks.data返回的是整张图大小的二值掩码如果目标很多且图像很大处理这些掩码可能会成为瓶颈。如果后续只需要目标区域内的掩码可以像上面示例一样根据边界框进行裁剪只处理ROI区域。类别错误或漏检增多部署环境光照、相机角度、背景与训练数据差异过大。这就是所谓的“域偏移”Domain Shift。解决办法是收集部署环境下的数据对模型进行微调增量训练哪怕只有几十张新环境下的标注图像也能极大提升模型在该环境下的表现。7. 进阶技巧与避坑指南在多次项目实战后我积累了一些在官方文档里不会明确写出来的经验和教训这些往往能帮你节省大量时间。7.1 处理类别不平衡问题如果你的数据集中某些类别的样本数量远多于其他类别例如“合格零件”有5000张“缺陷零件”只有200张模型会严重偏向于多数类。解决方法数据层采样在加载数据时对少数类进行过采样重复使用或对多数类进行欠采样。YOLOv5的训练脚本支持通过--oversample参数进行过采样但更推荐在数据准备阶段就做好平衡。损失函数加权YOLOv5的损失函数中包含分类损失cls loss。可以为不同类别设置不同的权重。这需要在代码层面修改损失函数相对复杂。一个更简单实用的方法是复制少数类别的图像并施加更强的数据增强如随机旋转、颜色抖动、模糊等人工增加其多样性和数量。7.2 利用预训练权重进行增量训练当你已经有一个训练好的模型best.pt但收集到了一批新的数据可能来自新的场景你不需要从头开始训练。python segment/train.py --data new_dataset.yaml --weights runs/train/previous_exp/weights/best.pt --epochs 50 --name incremental_training --img 640 --batch-size 16 --lr0 0.001 # 使用更小的学习率关键点使用更小的学习率--lr0 0.001或更低因为模型已经在旧数据上收敛权重处于一个较好的局部最优点。新数据是为了对这个点进行微调过大学习率会导致“灾难性遗忘”Catastrophic Forgetting即模型完全忘记了旧数据上学到的知识。可以混合新旧数据将新数据与一部分旧数据混合在一起训练效果通常比只在新数据上微调更好能更好地保持模型原有的能力。冻结部分层对于数据量特别小的新场景可以尝试冻结骨干网络Backbone的权重只训练检测头和分割头。这能极大减少过拟合的风险。在YOLOv5中可以通过修改模型定义文件来实现但对于初学者调整学习率是更安全的方法。7.3 常见错误与解决方案训练时Loss为NaN首要原因学习率太大。立即降低学习率--lr0尝试1e-4, 1e-5。数据问题检查数据集中是否有损坏的图像用OpenCV的imread检查或者标签文件中是否有非法的坐标值如归一化后大于1或小于0。梯度爆炸可以尝试使用梯度裁剪--gradient-clipping在训练命令中加入--gradient-clipping 1.0。验证mAP很低但训练Loss正常下降过拟合这是最可能的原因。增加数据增强的强度或者使用更激进的正则化如更小的模型、DropOut。检查训练集和验证集的数据分布是否差异过大。验证集标注质量差检查验证集的标签文件是否正确是否有漏标、错标。评估参数不一致确保验证时使用的--img尺寸和训练时一致。推理时速度比预期慢很多检查是否在CPU上运行。确保--device参数正确设置为GPU如--device 0。检查输入图像尺寸是否过大。predict.py默认会按照模型导出时的尺寸进行推理但如果你用Python接口传入的图像尺寸会影响速度。如果是视频流检查是否每一帧都重新初始化了模型应该只初始化一次然后循环调用。导出的ONNX模型在其他框架中报错确保导出ONNX时使用的PyTorch和ONNX版本与目标推理环境兼容。尝试导出时不加--dynamic参数使用固定尺寸。使用ONNX Simplifier工具对导出的模型进行简化python -m onnxsim yolov5s-seg.onnx yolov5s-seg-sim.onnx。训练自己的YOLOv5-seg模型是一个系统工程从数据准备到模型调优每一步都需要耐心和细致的分析。没有“银弹”参数最好的结果来自于对你自己数据的深入理解以及基于实验反馈的持续迭代。希望这篇从实战中总结出来的长文能帮你避开我踩过的那些坑更高效地构建出满足业务需求的实例分割模型。记住当模型表现不如预期时第一个应该怀疑的是数据第二个是数据第三个还是数据。
返回列表