首页 / 资讯中心 / 文章详情

YOLOv8实例分割实战:芒果数据集从标签校验到模型训练与部署

YOLOv8实例分割实战:芒果数据集从标签校验到模型训练与部署 ★ FEATURED ARTICLE
简介这是一套面向农业场景的芒果实例分割数据集已转换为YOLOv8可直接训练的格式包含453条训练数据与91条验证数据适用于目标检测、实例分割等深度学习任务。数据集覆盖精准农业管理、自动化采摘定位、芒果质量分级与病虫害识别等典型场景适合算法工程师、科研人员以及农业智能设备开发者用于算法验证与工程落地。资源包共1088个文件以542对图像与标注txt为主另含2个json标注文件和2个cache加速文件整体压缩后约187MB结构清晰导入YOLOv8项目后即可开展训练。目前已有761人学习或下载在计算机视觉与智慧农业项目中具有较高的实用价值。通过这套数据还可以进一步分析芒果的形状、大小和颜色特征为采摘机械臂、果园监测系统等任务提供可靠的数据支撑。1. 芒果实例分割数据集先别急着跑训练先把这45391条数据吃透做芒果分拣或成熟度检测的CV项目最难的不是模型而是标注数据。能直接给yolov8用的实例分割数据集市面上很少果树类目标的中文场景就更稀缺。这个芒果实例分割数据集提供了453条训练数据和91条验证数据标签已经是yolov8的txt格式拿过来改个yaml就能开始训练省掉了从coco或labelme转格式的整个过程。和商用标注动辄几万张不同它的量不大但场景非常聚焦同一个俯拍或斜拍视角下的芒果个体轮廓背景多为分拣线、托盘或树叶。这决定了它能解决什么问题。你不需要再花两到三周去标轮廓可以直接拿它对yolov8-seg做完整训练或迁移学习验证成熟度分级、病斑面积估算、采摘点定位这类需要像素级mask的落地需求。适合三类人想快速跑通实例分割流程的初学者做农业智能装备但缺数据的一线工程师以及需要小样本baseline来对比改进算法的研究者。数据量不大但你要是先把格式核对和参数选好照样能把它训练到mAP50接近0.9的水平急着开训反而容易翻车。2. 看清yolov8格式的底细芒果数据集的txt标签与目录结构2.1 yolov8实例分割和检测的标签格式区别很多从coco或labelme转过来的人第一次看yolov8的分割标签会有点懵。目标检测标签是class_id cx, cy, w, h而实例分割标签是class_id 多边形归一化顶点坐标每个实例一行顶点数量不固定。比如一个芒果被标成六边形这一行就是0 0.5123 0.4211 0.6232 0.4504 ...坐标全部除以图片宽高归一化到0到1之间。归一化意味着标签与图片尺寸解耦换分辨率不用重标。这里有个容易被忽略的点yolov8的实例分割标签里没有mask矩阵也没有每个顶点的闭合标记。坐标点按顺序连起来既是轮廓也是mask的polygon输入。ultralytics训练时会把多边形栅格化成mask。所以一旦顶点顺序错了或者有人从labelimg/exel格式直接复制坐标就会出现mask被扭成蝴蝶结形状的情况但训练脚本不会报错。2.2 芒果数据集的目录组织与训练/验证划分这个数据集既然是“yolov8格式”那大概率遵循ultralytics默认的目录结构。常见做法是数据集根目录下分images和labels各自里面再分train和val。也就是mango_dataset/ ├── images/ │ ├── train/ │ │ ├── mango_001.jpg │ │ └── ... │ └── val/ │ ├── mango_412.jpg │ └── ... └── labels/ ├── train/ │ ├── mango_001.txt │ └── ... └── val/ ├── mango_412.txt └── ...拿到数据集后先用find命令确认目录层级再检查图片和txt是否一一对应。很多“数据集”其实只是把图片和txt塞进同一个文件夹yolov8会提示找不到标签。find /path/to/mango_dataset -type d | sort find /path/to/mango_dataset/images -type f | wc -l find /path/to/mango_dataset/labels -type f | wc -l前一条命令看目录树后两条分别数图片和标签数量。如果数量不一致说明有图片没有标签或者有孤儿标签文件。正规的数据集应该两边数量完全一致训练453张对应453个txt验证91张对应91个txt。你还可以用ls | sed s/.*\.//之类的方式看后缀确认jpg/png和txt不乱。2.3 用脚本核对标签是否真的能用拿到数据别直接开训先做一次自动化检查。我用Python统计每个txt的行数、顶点坐标是否越界、类别id是否连续顺便输出每类实例数量。这个检查能过滤掉大部分“标签出错了但训练不报错”的坑。import os from glob import glob label_dir labels/train class_counts {} bad_files [] for txt_path in glob(os.path.join(label_dir, *.txt)): with open(txt_path, r) as f: lines f.read().strip().splitlines() if not lines: bad_files.append((txt_path, empty)) continue for line in lines: parts line.split() class_id int(parts[0]) class_counts[class_id] class_counts.get(class_id, 0) 1 coords list(map(float, parts[1:])) if len(coords) 6: # 至少三个点才能构成多边形 bad_files.append((txt_path, polygon_too_small)) if any(c 0 or c 1 for c in coords): bad_files.append((txt_path, coord_out_of_range)) print(每类实例数:, class_counts) print(异常文件数:, len(bad_files)) if bad_files: print(bad_files[:10]) else: print(标签格式核验通过)这段脚本的逻辑不复杂逐行读txt把第一列当类别id统计其余坐标全部按浮点解析检查是否都在0到1之间同时统计顶点数量。实际跑一次你会发现最常见的问题是从labelme转出来的文件忘了归一化坐标直接写成像素值。yolov8遇到这种标签不会崩但loss会莫名变大mask轮廓错位最后mAP低得离谱。我习惯在训练前把异常文件挑出来重修而不是抱着“先跑跑看”的心态训练。3. 用yolov8-seg在本地跑通芒果分割训练从yaml到命令行3.1 环境安装与验证ultralytics版本与torch的搭配yolov8实例分割的实现主要在ultralytics这个包。如果你在NVIDIA显卡上训练先确认驱动和CUDA能正常工作再安装带cuda的torch最后装ultralytics。新手最容易翻车的地方是直接pip install torch拿到的是cpu版本训练慢得怀疑人生。# 先看nvidia-smi里的CUDA版本再装对应torch nvidia-smi pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118 pip install ultralytics装完验证一下import torch import ultralytics print(torch.__version__, torch.cuda.is_available()) print(ultralytics.__version__)如果torch.cuda.is_available()输出False说明torch装成了cpu版本或者CUDA驱动不匹配。别慌用pip list | grep torch看当前torch版本重新指定cu118/cu121的轮子安装。ultralytics版本建议保持最新因为实例分割的mask解码和copy_paste增强在旧版本里不完整。3.2 写data.yaml路径与类别名要严格对应yolov8训练不读文件夹名只认data.yaml里的路径和类别列表。芒果分割如果只有一类类别名可以叫mango如果有多个品种要按0、1、2顺序写。这个顺序必须和标签txt里第一列数字一致否则训练过程不报错但模型学会了把类别互换验证mAP只有0.5甚至更低。# mango.yaml path: /home/user/mango_dataset # 数据集根目录建议写绝对路径 train: images/train # 相对根目录的训练图片路径 val: images/val # 相对根目录的验证图片路径 # test: images/test # 如果没有测试集可以注释掉 names: 0: mango 1: mango_brown 2: mango_green如果数据集里只有一个类别就只留0: mango。注意yaml里不要用tab缩进yolov8的yaml解析对空格敏感。path字段写绝对路径能避免你在不同工作目录下运行时找不到数据。train和val不要写成./images/trainyolov8会自动拼接path train加./反而容易出问题。3.3 选模型yolov8n-seg.pt还是yolov8s-seg.pt小数据集为什么先选nyolov8提供n/s/m/l/x五个尺寸的分割模型文件名对应yolov8n-seg.pt、yolov8s-seg.pt等。453条训练数据单类任务yolov8n-seg是默认首选。n规模大概3M参数显存占用低速度快在GTX 1660Ti上也能跑得动。s比n复杂度高理论上mAP更高但小数据集上很容易过拟合。如果时间不太敏感可以先n跑通流程再换s看提升幅度。不要一上来就用x3060上x-seg很容易显存溢出。模型参数量约推荐显存小数据集表现yolov8n-seg3M4GB可用速度快适合baselineyolov8s-seg11M6GB可用平衡453条可到高mAPyolov8m-seg27M8GB可用需要更多数据yolov8l-seg48M12GB以上小样本容易过拟合yolov8x-seg65M14GB以上不建议小数据实际参数量以官方模型文件为准但选型逻辑是小数据集优先用结构简单、正则效果强的模型。你还可以在yaml里给模型加dropout但通过增强来控制过拟合更有效。对于这个芒果数据集如果你只想验证流程n足够想做精度较高的成熟度分割s是性价比最高的一档。3.4 启动训练一条命令跑起来命令行方式yolo segment train data./mango.yaml modelyolov8n-seg.pt epochs150 imgsz640 batch8 patience20 project./runs namemango_seg等价Python方式from ultralytics import YOLO model YOLO(yolov8n-seg.pt) results model.train( data./mango.yaml, epochs150, imgsz640, batch8, patience20, project./runs, namemango_seg, verboseTrue, )这段代码的含义model从yolov8n-seg.pt预训练权重开始微调epochs设150图片resize到640x640batch为8patience20表示连续20轮验证指标没有提升就早停。训练结束后runs/mango_seg/weights/下会有best.pt和last.pt。整个训练过程在453张图上如果是3060或以上显卡十几分钟到半小时就能看到收敛趋势。GTX 1660Ti跑n-seg也比较轻松只是每个epoch会多花几秒。如果显存只有4GB可以把batch降到4imgsz降到512。小数据集上imgsz从640降到512对mAP影响不大但能大幅缓解显存压力。如果batch降到2还OOM就需要检查是不是别的进程占了显存或者用了太大的模型。4. 把453条数据榨干小样本训练的增强与超参数4.1 mosaic、copy_paste与旋转哪些增强对芒果分割真正有效yolov8默认开了很多增强包括mosaic、hsv、flip等。对小数据集mosaic是双刃剑它把4张图拼到一起变相增加样本但会裁切出不自然的色块边界对芒果这种圆润目标来说拼出来的边界很容易和芒果边缘混淆。我一般会把mosaic从默认的1.0降到0.5同时开启copy_paste实例级复制粘贴它能把别的图里的芒果抠出来贴进当前图随机缩放旋转比mosaic更符合实例分割任务。from ultralytics import YOLO model YOLO(yolov8s-seg.pt) # 也可以接自己训练好的best.pt做二次增量 model.train( data./mango.yaml, epochs200, imgsz640, batch8, workers4, mosaic0.5, copy_paste0.5, hsv_h0.01, # 色调扰动要小芒果颜色是分割关键 hsv_s0.5, hsv_v0.4, degrees30, translate0.1, scale0.5, fliplr0.5, )注意copy_paste需要ultralytics 8.0.43以上版本老版本会报错“unexpected keyword argument”。degrees30表示随机旋转±30度对芒果这种无方向性目标很友好但如果要做精确的成熟度分级旋转角度太大会让果柄位置不可控建议不要超过30度。scale0.5是随机缩放50%到150%配合copy_paste更容易提升小目标的mask分数。HSV扰动要克制芒果成熟度本身靠颜色区分你把饱和度调得太狠模型就分不清青芒果和黄芒果了。4.2 关键超参imgsz、batch、epoch、patience怎么定453条训练数据epoch不是越多越好。我一般用150到300之间patience设20模型通常在120轮左右收敛。batch大小不直接决定效果但batch8和batch16之间验证mAP的波动通常只在0.02以内所以优先让batch能适配显存。如果追求稳定batch固定8就好不要频繁改。参数推荐值说明epoch150-300小样本多轮才够收敛但要早停imgsz512或640芒果占比大用512小目标多就用640batch4-16按显存来4GB显存就设为4patience20连续20轮无提升就停止workers4-8Windows上设0Linux设4以上pretrainedTrue用coco预训练权重做迁移imgsz的选择要单独说。如果芒果在图片里占比很大比如整个画面就三五个果512就够如果图片是果园场景芒果只占画面一小块用640能保留更多细节。不要为了追求mAP把imgsz调到1280小数据集的增益撑不起显存和训练时间的代价。如果训练时发现val的mask边缘非常粗糙优先降mosaic和copy_paste而不是提高imgsz。4.3 从损失曲线判断训练状态训练跑起来后不要只盯mAP损失曲线才是判断过拟合和调整增强的窗口。ultralytics在runs/mango_seg/下保存results.csv里面有train/box_loss、train/seg_loss、val/box_loss、val/seg_loss和mAP50。我习惯画一张曲线图import pandas as pd import matplotlib.pyplot as plt df pd.read_csv(runs/mango_seg/results.csv) plt.figure(figsize(8, 5)) plt.plot(df[epoch], df[train/box_loss], labeltrain box_loss) plt.plot(df[epoch], df[val/box_loss], labelval box_loss) plt.plot(df[epoch], df[train/seg_loss], labeltrain seg_loss) plt.plot(df[epoch], df[val/seg_loss], labelval seg_loss) plt.legend() plt.xlabel(epoch) plt.ylabel(loss) plt.yscale(log) plt.savefig(loss_curve.png) plt.show()如果val loss在40轮后开始反弹train loss还在降说明过拟合要调小增强或减少epoch。如果val loss和train loss都平稳但mAP不涨说明增强过强模型学不到稳定的语义信息这时把mosaic降到0.2copy_paste降到0.3再试试。很多人第一次用yolov8画损失函数曲线图时不知道results.csv里列名带前缀直接用csv模块读容易解析错用pandas读就省心。5. 训练中的避坑清单格式、类别、显存与mAP的5个血泪教训5.1 标签编号从0开始类别顺序和yaml对不上现象训练时loss正常下降验证时mAP50一直只有0.4-0.5看起来像没学会。原因txt里的第一列类别id从1开始写了而data.yaml的names列表从0开始像0: mango, 1: mango_brown。导致模型把所有真实类别都当成第0类或第1类的偏移。解决写脚本把txt第一列统一减1再确认names顺序和标注工具导出时的顺序一致。这是labelme导出时最常见的坑。我遇到过一次训练了200轮才发现验证集标签的类别id全部偏了一位mAP直接掉到0.3。5.2 归一化坐标被误写成像素坐标现象训练时loss能降但val预测出来的mask轮廓明显和芒果边缘错位甚至缩在画面角落。原因标注工具直接输出像素坐标没有除以图片宽高。解决用第2章的脚本检查坐标范围如果最大值远大于1就按每张图的实际宽高做归一化。注意一个实例可能有几十个顶点必须整行一起除。脚本落地时先读取图片尺寸再把txt每个顶点坐标除以对应的宽高。不要只除以1000这种投机取巧的办法不同图片宽高可能不同。5.3 验证集没有对应标签导致eval报错现象训练刚启动就提示“val: No labels in ...”。原因labels/val目录下没有txt或者txt文件名和验证图片对不上。yolov8会扫描images/val下的图片然后去labels/val找同名txt找不到就跳过验证集。解决确认labels/val和images/val文件名一一对应可以用diff (ls images/val | sed s/\.jpg$//) (ls labels/val | sed s/\.txt$//)检查。我踩过一次把训练标签复制了一份放val结果验证图片和标签完全错位训练过程不报错但mAP波动极大。5.4 显存不足时直接把batch调小训练速度变慢现象batch8时OOM改成2后能跑但每个epoch耗时翻了好几倍。原因batch小了每个epoch的更新次数变多梯度噪声也变大收敛更慢。解决优先降imgsz到512或448不要一直降batch。4GB显存跑yolov8n-segimgsz640 batch4基本是极限。还可以加cacheTrue把图片缓存到内存减少数据读取瓶颈但会吃内存。如果还不行就尝试rectTrue让图片按长边比例分组batch减少填充区域这对不同分辨率的图片很有效。5.5 mAP一直很低但loss正常检查类别不均衡和mask的点数现象训练过程loss曲线很平滑mAP50始终在0.6以下。原因数据里某一类实例数量极多另一类只有几个yolo对少数类几乎学不到。另一个常见原因是标签里一个实例的顶点数超过100标注误差被放大。解决对每一类实例画数量柱状图少于10个的类别直接合并到相邻类别或改用单类训练。对于顶点数过大的标签用Douglas-Peucker简化多边形保留20-30个点足以描述芒果轮廓。很多标注工具默认多边形太细碎简化后mask边缘反而更干净mAP能回升0.1。6. 训练之后用训练好的权重做预测、评估和部署到rk3588的要点6.1 用best.pt对验证集做预测并保存mask训练完best.pt在runs/mango_seg/weights/下。用它对验证集做一次推理亲眼确认mask边缘不是“粘在背景上”的粗轮廓yolo segment predict model./runs/mango_seg/weights/best.pt source./mango_dataset/images/val saveTrue save_txtTrue conf0.5或者用Python接口方便后续接面积计算from ultralytics import YOLO model YOLO(runs/mango_seg/weights/best.pt) results model.predict( sourcemango_dataset/images/val, saveTrue, conf0.5, line_width2, ) for r in results: print(r.masks is not None, len(r)) # 输出是否检测到mask和实例数注意推理时返回的mask坐标是原图尺寸不是640归一化后的坐标这样直接用来算芒果投影面积很方便。conf阈值设在0.5是通用值如果现场遮挡严重建议0.3但误检会增多。6.2 用val.py/Result计算mAP50与mAP50-95训练和推理都跑通后再算一次正式指标yolo segment val model./runs/mango_seg/weights/best.pt data./mango.yaml它会输出每个类别的mAP50和mAP50-95。这里有个容易被忽略的边界val时的imgsz一定要和训练时保持一致。我试过训练用512验证用640mask头输出的特征图尺寸变了mAP被虚高0.05看起来好看换到实际部署又打回原形。另一个顺手的技巧是ultralytics的mask分支在推理时默认会做mask_ratio压缩如果你在GPU上部署可以在配置里把mask_ratio调成1保留更高分辨率的mask。这个参数只影响输出质量不影响训练。6.3 rk3588部署从torchscript到rknn的转化注意点部署到rk3588是这个数据集常见的落地方向。常见做法是先把best.pt导出成onnx再用rknn-toolkit2转成rknn。这里最大的坑是ultralytics导出onnx时默认包含后处理节点rknn编译器经常不支持。导出要加opset12和simplifyTrueyolo export model./runs/mango_seg/weights/best.pt formatonnx opset12 simplifyTrue导出后把mask分支的输出头和box分支的head拆开rknn推理时拿到的是原始tensor不能直接按yolo内置格式解析。mask分支的channel数不是最终类别数需要自己reshape到[1, num_classes, 160, 160]再上采样。建议先用rknn-toolkit2的模拟器在PC上推理同一个onnx对比输出shape再在板子上实现解码。这一步的血泪经验是别急着烧板先在PC端把onnx的输出形状确认清楚能省一整天调试时间。6.4 一套顺手的小样本验证习惯最后分享一个习惯不管拿到多小的数据集我都会先用随机权重跑10个epoch确认数据读取和标签解析没出问题再用预训练权重跑全量。这个习惯帮我少翻了很多次车。这个芒果数据集也一样先跑n-seg、150epoch看val的box_loss有没有在30轮内明显下降如果mAP50能到0.85以上再考虑换s模型或加入外部芒果图片做增量训练。希望帮到你。本文还有配套的精品资源点击获取
阅读完成 · 觉得有帮助?
咨询建站