
简介面向深度学习实例分割与农业智能化应用的数据集资源适合使用YOLOv8进行模型训练的学生、研究人员与开发者。资源按yolov8格式组织共453条训练数据与91条验证数据图像与txt标注一一对应可直接接入训练流程减少格式转换成本。应用场景覆盖果园精细管理、自动化采摘、芒果质量分级与病虫害检测等便于按需扩展或迁移到相似农产品检测任务。资源包共有1088个文件以542张png图像和542个txt标注文件为主体另含json与cache格式的标签映射和缓存信息压缩包整体约187.03MB目录划分清晰适合本地或云端训练。目前已761人学习使用具备一定参考价值通过该数据集可快速验证实例分割模型效果也能用于开展小样本场景下的目标检测与分割算法实验还可结合真实农业场景做精度调优为机器人采摘或果园监测提供视觉基础。1. 芒果实例分割数据集为什么我拿到 453 条训练数据先做体检做果实分拣、果园测产或者采后分级的朋友多半会卡在同一个地方公开的果实检测数据集一抓一大把真到实例分割阶段能直接用来训练的芒果数据却少得可怜。这份芒果实例分割数据集正好补上这个缺口——标注已经是 YOLOv8 需要的格式包含 453 条训练数据和 91 条验证数据拿到手不需要从 Labelme 重新导出配好 data.yaml 就能直接跑 yolov8 的训练。这套体量对验证算法完全够用但对「直接生产」来说偏小所以训练时要用预训练权重和数据增强兜底。适合两类人一是想在水果场景验证 YOLOv8 实例分割效果的学生和工程师二是做芒果计数、成熟度分析但手头没有标注资源的项目组。我先说结论这套数据跑通流程没问题但拿到手别急着开训先用半小时做一次格式体检能省下后面一整天的排错时间。2. 读懂 YOLOv8 实例分割标注格式为什么单张图变成一个同名 txt 里的多边形开始训练之前先把 YOLOv8 实例分割的标注格式讲透。实例分割和目标检测的 YOLO 标注都放在 txt 文件里但检测格式是class_id x_center y_center width height而分割格式是变长的多边形顶点坐标。理解这个差异你才知道 453 条训练数据里装的是什么。2.1 数据集目录结构与文件命名规则YOLOv8 数据集的目录通常长这样这份芒果数据集也不例外mango_seg_dataset/ ├── data.yaml ├── images/ │ ├── train/ │ │ ├── mango_001.jpg │ │ ├── mango_002.jpg │ │ └── ... │ └── val/ │ ├── mango_401.jpg │ └── ... └── labels/ ├── train/ │ ├── mango_001.txt │ ├── mango_002.txt │ └── ... └── val/ ├── mango_401.txt └── ...图片和标注靠文件名一一对应images/train/mango_001.jpg对应labels/train/mango_001.txt。后缀必须完全匹配图片是.jpg文件标注就找同名.txt有一张图找不到标注训练时 ultralytics 会跳过它并打 WARNING。常见做法是把图片名统一成纯数字或固定前缀避免中文名、空格以及 Windows 路径分隔符带来的坑。提示拿到数据集先跑一个find命令对比两个目录的文件差集比等到训练日志里冒 WARNING 再回头排查要快得多。目录划分上训练集 453 条、验证集 91 条合计 544 条验证集占比约 16.7%接近常见的 8:2 划分。这个比例对实例分割来说偏紧但不算离谱关键看验证集的分布是否和训练集一致——这一点后面避坑章节会专门讲。2.2 标注字段解析归一化坐标与多边形顶点打开任意一个 txt每一行代表一个芒果实例格式是class_id x1 y1 x2 y2 x3 y3 ...其中x1 y1是多边形第一个顶点的归一化横纵坐标x2 y2是第二个顶点依此类推。归一化意味着坐标值被图像宽高除过范围在 0 到 1 之间。假设某张 1920x1080 的图里芒果轮廓的一个顶点在原图上位于 (960, 540)txt 里记录的就是 (0.5, 0.5)。每行的顶点数不固定一个完整的掩膜轮廓最少 3 个点多则上百个。这是 YOLOv8 实例分割和检测标注最本质的区别——检测框是固定四个数分割掩膜是多边形描述顶点越密轮廓越贴合芒果边缘但训练时计算量也越大。这份数据集标注的是单个芒果的轮廓不是整棵树的果实簇所以每行对应一个独立可分割的实例。2.3 用可视化脚本给标注做一遍「体检」这里分享一个我每次拿到新数据集都先跑一遍的脚本作用是把 txt 里的多边形画回原图看看标注到底长什么样、有没有贴住芒果边缘import cv2 import numpy as np def load_yolo_seg_label(txt_path, img_w, img_h): 读取 YOLOv8 分割标注返回类别列表和多边形顶点列表 classes [] polygons [] with open(txt_path, r) as f: for line in f: line line.strip() if not line: continue parts line.split() classes.append(int(parts[0])) # 归一化坐标还原到像素坐标 xy np.array(parts[1:], dtypenp.float32).reshape(-1, 2) xy[:, 0] * img_w xy[:, 1] * img_h polygons.append(xy.astype(np.int32)) return classes, polygons img cv2.imread(images/train/mango_001.jpg) h, w img.shape[:2] classes, polygons load_yolo_seg_label(labels/train/mango_001.txt, w, h) for cls_id, poly in zip(classes, polygons): cv2.polylines(img, [poly], isClosedTrue, color(0, 255, 0), thickness2) cv2.putText(img, fcls_{cls_id}, tuple(poly[0]), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 0, 255), 2) cv2.imwrite(check_mango_001.jpg, img) print(f共 {len(polygons)} 个实例)这段代码做的事情很直接把标注文件里归一化的顶点坐标乘回图像的宽高再用cv2.polylines把多边形画在原图上。如果画出来的轮廓明显偏离芒果边缘、或者框住了大片背景说明标注质量有问题训练出来的掩膜也不会准。我一般会从训练集和验证集各抽 10-20 张图跑这个脚本重点看三类问题多边形是否严重锯齿、芒果之间有没有互相重叠、类别 ID 是否一致。这一步属于「花小钱办大事」半小时的抽查能过滤掉大部分后期训练陷阱。2.4 验证 91 条数据的分布是否合理最后检查验证集的代表性。453 条训练数据和 91 条验证数据如果来自同一次拍摄、同一批芒果的不同角度那么验证指标会很漂亮但换个果园就露馅。常见做法是看文件名是否有分组信息比如batch1_mango_001.jpg这类前缀如果有就按批次划分训练验证而不是按单张图随机切。另一个检查点是类别均衡。这份数据集如果只有一个mango类别那不需要做什么如果有多个类别比如按成熟度分成green、ripe、overripe就要确认训练集和验证集里每个类别的比例接近。类别失衡会让训练过程看起来正常但 mAP50-95 在少数类上惨不忍睹这属于实例分割里典型的「数据看着没问题一划分就有问题」的场景。3. 用 453 条数据跑通 yolov8-seg 训练环境配置、data.yaml 与训练命令格式验证完接下来就是把训练真正跑起来。这一步的核心是三件事搭环境、改配置、起训练。很多人卡在环境搭建上其实 ultralytics 已经把安装精简到一条命令真正值得花心思的是 data.yaml 和训练参数。3.1 在 Ubuntu 20.04 上搭建 YOLOv8 环境CPU 与 GPU 两种路径常见做法是用 conda 建一个独立环境避免把系统 Python 搞乱。Ubuntu 20.04 下CPU 版本和 GPU 版本的区别主要在 torch 的安装源上# 创建环境 conda create -n yolov8 python3.10 -y conda activate yolov8 # CPU 版本适合快速验证不装 CUDA 相关组件 pip install torch torchvision --index-url https://download.pytorch.org/whl/cpu pip install ultralytics # GPU 版本先确认 nvidia-smi 能看到显卡再装 CUDA 版 torch pip install torch torchvision --index-url https://download.pytorch.org/whl/cu121 pip install ultralytics如果是在 ubuntu20.04 上搭建 yolov8 环境并选择 CPU 版本重点是别装错 torch 来源。CPU 版 torch 体积小、不依赖 CUDA 库用 453 条数据、imgsz640跑 100 个 epoch 大概需要二十分钟到一小时看机器性能GPU 版则把训练压到几分钟级别。验证安装是否成功跑一句yolo predict modelyolov8n-seg.pt sourcehttps://ultralytics.com/images/bus.jpg能输出检测结果就说明环境没问题。注意如果你已经有别的深度学习项目在用 torch不要急着覆盖安装。用 conda 新建环境是最稳妥的隔离方案版本冲突是训练跑不起来的第一大原因。3.2 修改 data.yaml路径、训练验证目录与类别名ultralytics 用 data.yaml 描述数据集这份芒果数据集需要自己补上这个文件。最简配置如下# data.yaml path: /data/mango_seg_dataset # 数据集根目录改成你自己的绝对路径 train: images/train # 训练图像目录相对于根目录 val: images/val # 验证图像目录 names: 0: mango # 类别 ID 与名称这里有两个容易被忽略的点。第一train和val指向的是images下的子目录而不是labels下的ultralytics 会自动把images替换成labels去加载标注文件。第二names的索引必须从 0 开始且和 txt 里的class_id严格一致如果这份数据集的标注里只写了 0但 data.yaml 里把 0 写成了 apple模型不会报错但验证指标会全线归零。路径建议写绝对路径避免相对路径在不同工作目录下解析不一致的问题。如果数据集和训练脚本在同级目录也可以省略path直接写train: /data/mango_seg_dataset/images/train两种写法 ultralytics 都支持我倾向于写全。3.3 最小训练命令从预训练权重开始环境就绪、data.yaml 写好之后训练命令非常短# 进入数据集上级目录确保相对路径不踩坑 cd /data # 用 yolov8n-seg 预训练权重训练芒果实例分割模型 yolo segment train \ data/data/mango_seg_dataset/data.yaml \ modelyolov8n-seg.pt \ epochs100 \ imgsz640 \ batch16 \ patience20 \ device0 \ workers4 \ cacheTrue这条命令的核心逻辑从 COCO 上预训练过的yolov8n-seg.pt开始把芒果数据集喂进去做微调。n是 nano 版本模型最小、速度最快对 453 条训练数据来说是合理的起点——模型容量和样本量要匹配直接上 xl 版本在不到 500 张图上几乎必然过拟合。cacheTrue的意义在于把图片一次性读入内存544 张图完全装得下训练每个 epoch 不用反复读磁盘时间能省 30% 左右。patience20表示验证集指标连续 20 个 epoch 不提升就早停小数据集训练经常 30 个 epoch 就到瓶颈早停能避免无效等待。3.4 训练完成后看什么损失曲线与 mask 指标训练结束后runs/segment/train/目录下会生成weights/best.pt、weights/last.pt、results.png等文件。results.png 里画了训练损失、验证损失以及 mAP50、mAP50-95 的曲线这是判断训练是否正常的首要依据。正常曲线应该是box_loss 和 seg_loss 前 20 个 epoch 快速下降之后缓慢收敛mAP50 从 0 附近爬升最终稳定在某个区间。如果看到 mAP50 一直在 0 附近波动或者 loss 曲线出现断崖式跳变就要回到第 4 章做排查。训练完先别急着部署用下面这条命令在验证集上确认最终指标yolo segment val \ model/data/runs/segment/train/weights/best.pt \ data/data/mango_seg_dataset/data.yaml输出里重点看两行mAP50和mAP50-95。前者对边缘要求宽松适合快速判断有没有学会后者更严格接近实际分割质量。单类别芒果数据集上mAP50 能到 0.9 以上、mAP50-95 在 0.7 以上基本都是收敛良好的信号。需要说明的是具体数值高度依赖数据本身难度——如果芒果密集重叠mAP50-95 掉到 0.5 也不一定是训练出了问题而是数据本身难。4. 训练芒果分割模型避坑排查五个让 mAP 翻车的细节这一章把我会踩的坑一次性讲完。实例分割训练脚本报错的概率不高翻车基本都在数据和参数这类“看不见”的地方。按「现象 → 原因 → 解决」的顺序把高频问题拆开讲。4.1 标签加载失败训练日志里的 WARNING 与缺失 txt 文件现象训练刚开始终端刷出大量WARNING: ignoring corrupt image / labels跑了一两个 epoch验证集指标全是 0。原因最常见是图片文件和标注文件不同名。比如图片是mango_001.jpgtxt 却叫mango_001.txt这是对的但如果图片是.JPG大写后缀或者标注文件名带空格ultralytics 就会匹配不上。另一个高频原因是某些 txt 是空文件或者文件末尾有多余空行被解析成了空标注。解决先用脚本对比 images 和 labels 两个目录的文件集合缺什么一目了然# 找出没有对应标注的图片 for img in images/train/*.jpg; do base$(basename $img .jpg) [ ! -f labels/train/${base}.txt ] echo 缺少标注: $img done文件名大小写统一用rename或mv批量处理。空文件直接删掉对应图片或者补标注空行问题基本是标注导出工具导致的直接用sed -i /^$/d清一遍即可。这个检查一定要放在训练之前带着 WARNING 训练出来的模型掩膜质量基本没法看。4.2 训练 loss 不降反升数据增强太猛与学习率过高现象前几个 epoch 的 box_loss 和 seg_loss 不降反升或者降到一半突然跳变到很大的值再也没回来。原因两个最常背锅的变量——学习率和数据增强。YOLOv8 默认学习率 0.01 对 nano 模型通常没问题但如果你把 batch 调得很小比如 4实际梯度噪声变大同样的学习率会显得偏大。数据增强方面453 条数据很容易让人想去加强增强参数但hsv_h、scale调过头会让模型学到的芒果颜色和尺度偏离真实分布训练损失自然压不下去。解决先复位到默认增强参数只调学习率。在训练命令里加lr00.005试一轮如果 loss 开始正常下降再逐步回调增强强度。另外检查 hsv 参数芒果的颜色是重要特征hsv_h超过 0.02 会把青芒果和熟芒果的颜色搅浑模型很难收敛。我的血泪经验是小数据集在增强上「宁稳勿猛」先保证能收敛再谈泛化。4.3 mAP 一直为 0类别 ID 与 data.yaml 映射不一致现象训练正常结束loss 曲线也漂亮但验证集 mAP50 恒等于 0。原因txt 里的class_id和 data.yaml 中names的索引对不上。比如标注文件写的是1data.yaml 里names只有0: mangoultralytics 会认为类别 1 不存在匹配不上真实类别mAP 自然归零。还有一种隐蔽情况txt 里第一个数字不是类别 ID而是从 1 开始的序号转换工具没有减 1。解决写个脚本扫描所有 txt统计出全部出现的 class_id# 统计训练集和验证集里出现过的类别 ID cat labels/train/*.txt labels/val/*.txt | awk {print $1} | sort -n | uniq -c输出应该只有一行544 0假设只有 mango 这一个类别。如果出现了多个数字或者最大值超过了 data.yaml 里定义的类别数减一就要回头审视标注文件的来源。确认 ID 范围后把 data.yaml 里的names改为对应的类别名即可。4.4 显存溢出batch_size 与 imgsz 的平衡现象训练在第一个 epoch 中途中断报CUDA out of memory。原因实例分割比目标检测吃显存因为每个实例多了一份掩膜分支的计算。在 8GB 显存上直接跑默认的batch16 imgsz640超出显存是家常便饭。453 条训练数据根本不需要大 batch——batch 从 16 降到 8显存占用减半梯度质量在这么小的数据集上差别不大。解决先nvidia-smi看显存总量8G 以下建议batch8起步imgsz从 640 降到 512 也能显著降低显存占用代价是掩膜边缘精度略微下降。此外workers4过多也会在数据加载时占额外内存但一般不会触发显存不足优先调 batch 和 imgsz。如果显存还是不够检查有没有其他进程占着显存fuser -v /dev/nvidia*能查到占用者。4.5 验证集指标虚高训练验证数据泄漏的隐患现象验证集 mAP50 高达 0.98拿到新图片上一测却明显分割不准边缘贴合很差。原因训练集和验证集来自同一批拍摄序列同一颗芒果的多张角度照片被同时分到了 train 和 val。这是数据集划分最常见的问题——按单张图随机划分看起来验证集独立但图像特征高度相似模型相当于「记住了」这批芒果遇到没见过的场景就露馅。我在农田无人机影像上踩过类似的坑按时间戳随机划分数据验证集指标漂亮得不敢信换了片区直接掉 20 个点。解决按拍摄来源分组来划分验证集。先看文件名有没有批次或日期信息比如20240512_blockA_001.jpg这种有就按前缀分组没有的话用聚类或目视判断哪些图来自同一场景确保同一颗芒果的所有角度全部落在训练集或全部落在验证集。91 条验证数据不多但代表的是「模型没见过的新场景」这个独立性比数量更重要。重新划分后mAP50 可能会掉到 0.85 甚至更低这是正常的更接近真实部署水平。5. 小样本数据增强与训练参数调优把 453 条训练数据用到极致453 条训练数据训实例分割属于典型的少样本场景。上一章解决了「能不能跑通」的问题这一章讲「怎么让它更好」。核心思路就一条——用尽可能强的正则化手段和迁移学习把模型往「学芒果共性的形状特征」上逼而不是让它死记这 453 张图。5.1 内置增强参数哪些值得动哪些保持默认YOLOv8 内置了一套数据增强参数在训练命令里用前导参数覆盖就行。以这份芒果数据集为例我会这样设置yolo segment train \ data/data/mango_seg_dataset/data.yaml \ modelyolov8n-seg.pt \ epochs150 imgsz640 batch16 \ hsv_h0.015 hsv_s0.5 hsv_v0.4 \ fliplr0.5 flipud0.0 \ scale0.5 translate0.1 \ mosaic1.0 close_mosaic10 \ mixup0.0逐项说明。hsv_h保持 0.015 的小值芒果的绿色和黄色是分割的重要线索色相变化太大会让模型混淆成熟度hsv_s和hsv_v可以给到 0.5 和 0.4模拟不同光照条件这在果园拍摄数据里非常实用。fliplr0.5水平翻转对芒果形状没有影响放心开flipud保持 0因为实际部署时几乎没有上下颠倒的画面开了反而引入无关变化。scale0.5和translate0.1模拟相机远近和轻微偏移对果实这类近似椭圆的目标帮助明显。mosaic1.0保留它把四张图拼成一张训练是小样本数据的核心增强手段配合close_mosaic10让最后 10 个 epoch 关掉 mosaic避免模型在真实分布上微调时被拼接痕迹干扰。mixup我建议 0芒果之间没有语义叠加的需求混叠会生成不伦不类的纹理。5.2 从 yolov8s-seg 开始而不是 nano模型容量与样本量的权衡第 3 章建议用 nano 起步那是为了先跑通流程。真要追求更好的掩膜精度可以换yolov8s-seg.pt甚至yolov8m-seg.pt试试。少样本场景下「模型越大越好」是个错觉——但「模型越大一定过拟合」也是错觉。关键在于数据增强和正则化能不能跟上。453 条训练数据配合mosaic、翻转和尺度增强每个 epoch 模型看到的有效样本远超 453 张s 版本的多层特征对芒果边缘的刻画比 nano 细腻得多。我的做法是 n 和 s 各跑一遍对比验证集 mAP50-95如果 s 版本在验证集上明显占优且在训练集上没有完全拟合就说明增强策略撑住了更大的模型。5.3 冻结主干网络freeze 参数在小数据集上的迁移学习价值YOLOv8 支持在训练时冻结部分层参数是freezeyolo segment train \ data/data/mango_seg_dataset/data.yaml \ modelyolov8s-seg.pt \ epochs100 imgsz640 batch16 \ freeze10freeze10表示冻结前 10 层。对 453 条数据来说冻结主干前几层的收益是让预训练提取的底层特征边缘、纹理、颜色块不要被少量芒果数据带偏模型专注学习芒果的形状组合和掩膜头。如果训练数据只有几百张直接全量微调常常把 COCO 上预训练学到的好特征给「冲掉」冻结是个便宜且有效的正则化手段。提一句和 yolov8 改进相关的话题有些同学喜欢在 head 上动刀改结构但在小数据集上任何结构改动都会放大过拟合风险。我一般建议先用原版架构跑通确认 mAP50-95 达标后再谈改进否则很难判断指标变化是改进带来的还是训练噪声。5.4 五折交叉验证让 91 条验证数据发挥更大作用91 条验证数据只够看一次结果而且划分的随机性会直接影响结论。更稳妥的做法是五折交叉验证用脚本把 544 张图按来源分组切成 5 份每次取 4 份训练、1 份验证跑 5 轮最后把 mAP 取平均。import os import random from collections import defaultdict # 按文件名前缀分组避免同源图像被拆散 groups defaultdict(list) for f in os.listdir(images/train) os.listdir(images/val): if f.endswith(.jpg): prefix f.split(_)[0] # 假设文件名形如 batch1_mango_001.jpg groups[prefix].append(f) # 打乱组顺序划分 5 折 keys list(groups.keys()) random.shuffle(keys) folds [keys[i::5] for i in range(5)] # 每折约 20% 的组 for i, val_keys in enumerate(folds): train_keys [k for k in keys if k not in val_keys] print(ffold {i}: train groups{len(train_keys)}, val groups{len(val_keys)}) # 这里生成对应的 train.txt / val.txt 清单文件供训练使用这个脚本的核心逻辑是「按组划分」保证同一拍摄批次不会被切到两个集合里。五折跑完后把每一折的 mAP50-95 汇总看均值和方差——方差大说明数据本身分布不均换个随机种子结果就不同这时要回头查数据划分而不是继续调参。提示五折交叉验证只用来评估和选参最终生产模型还是在全部 544 张图上重训。交叉验证的结论是「这个方案稳不稳」最终模型要的是「数据再多一点」。6. 验证分割结果与导出 ONNX掩膜边缘比 mAP 更值得盯训练结束不是终点如何确认模型真的能用、怎么导出部署才是最后一道工序。我的习惯是先用验证集做一次带预测图输出的评估再导出 ONNX最后在真实场景图上看掩膜边缘。验证集评估加上预测图保存命令是这样yolo segment val \ model/data/runs/segment/train/weights/best.pt \ data/data/mango_seg_dataset/data.yaml \ save_jsonTrue save_txtTrue save_confTruesave_txtTrue会把每张验证图的预测掩膜保存成 txtsave_jsonTrue输出 COCO 格式的评估结果。除了看 mAP 数值我会重点翻runs/segment/val/里保存的预测叠加图mAP 是统计指标可能被简单样本拉高而边缘贴合度必须靠肉眼确认。芒果之间互相遮挡时两个实例的掩膜是干净分开还是糊成一团NMS 处理得好不好mAP 不一定看得出来人眼扫一遍就有数。部署导出 ONNX 的命令也很直接yolo export model/data/runs/segment/train/weights/best.pt formatonnx opset12 imgsz640导出后用一行 Python 做单图推理验证from ultralytics import YOLO model YOLO(/data/runs/segment/train/weights/best.onnx) results model.predict(test.jpg, conf0.25, iou0.5) print(results[0].masks.data.shape) # (实例数, 640, 640) 的掩膜矩阵masks.data是模型输出的原始掩膜shape 里第一个维度是检测到的实例数随后是掩膜的高和宽。导出后对比 ONNX 和 PyTorch 权重的预测结果形状和置信度应该几乎一致如果差很多检查opset和输入分辨率是否匹配。最后说一个收尾习惯我每次换数据集都会先抽 20 张图做标注可视化确认没毛病才开训模型训练完再抽 20 张真实拍摄图看掩膜边缘而不是只盯着 mAP 数字。这个习惯帮我躲过了大半翻车场景——数据有硬伤时训练日志不会直接告诉你但可视化一定藏不住。希望帮到你。本文还有配套的精品资源点击获取