☰
YOLOv5水果检测数据集实操:从标注格式到训练推理全流程
2026/9/28 12:12:47 网站建设 项目流程

简介:面向目标检测学习者和算法工程师的YOLOv5水果检测数据集,涵盖菠萝、李子、红番茄、西瓜四类常见水果。图片标注完整,训练集、验证集、测试集已按目录划分完毕,并附有可直接读取的data.yaml配置说明,适用于YOLOv5、YOLOv7、YOLOv8等主流检测算法的模型训练与效果验证。压缩包共1107个文件,其中553张jpg图片与553个txt标签文件一一对应,每张图片均包含对应类别与边界框信息,另含1个yaml配置文件,整体大小31.72MB,目录结构遵循YOLO系列常见工程布局,设置好数据路径后即可直接运行训练脚本。目前已有841人学习下载,省去自行整理标注数据和划分数据集的繁琐过程,拿到后即可开始训练调试。该数据集可直接作为目标检测入门的练习数据,也便于对比不同YOLO版本的检测效果,尤其适合快速验证模型改进思路或完成课程设计中的目标检测模块。

1. 一份命名规整的水果检测数据集,到底能省你多少事?

做视觉检测的同行应该都有过这种经历:模型结构调通了、训练脚本跑顺了,却卡在数据上——自己拍照标注几百张图片,一个周末就搭进去;从网上爬图拼数据集,标签混乱得让人想摔键盘。yolov5水果检测数据集 fruit-detect-yolov5-5.zip这个标题指向的,就是一份已经整理成 YOLOv5 训练格式的现成水果检测数据包。这类资源在开发者手里是刚需:解压之后改一下数据配置文件,就能直接丢进 YOLOv5 开始训练,省掉从零标注和格式转换的两大块脏活。

这份数据集的定位很明确:面向目标检测里的常见水果类别(苹果、香蕉、橙子这类),图片尺寸和标签格式都按 YOLOv5 的默认约定组织。适合的人群分两类——第一是刚入门 YOLOv5、想用现成数据跑通整个训练流程的新手,第二是做农产品分拣、无人零售货柜这类场景验证的工程师,需要先用公开数据把流程跑通、把超参数摸出个大概,再换自己的业务数据。正文里我会按数据集解压后的目录结构、标签格式验证、训练参数设置、常见坑点排查、以及训练后如何导出做批量推理这条线,把这个数据包的完整用法拆给你看。

2. 解压后先别急着训练:fruit-detect 数据集的目录结构与标签格式

拿到fruit-detect-yolov5-5.zip这份压缩包,常见做法是先解压到 YOLOv5 项目同级目录下。但很多人第一步就跑偏——解压完直接打开 train.py 开训,结果报错找不到图片路径。根源在于:YOLOv5 训练时读取的不是图片路径本身,而是通过数据配置文件(data/*.yaml)里的相对路径定位图片目录,同时通过标签文件里的类别编号映射到类别名字。所以先花五分钟把目录结构和标签内容看明白,比你闷头调参数重要得多。

2.1 压缩包解压:目录结构长什么样

用常见的解压命令把压缩包解开,得到的主目录通常是fruit-detect-yolov5-5,里面按训练集、验证集、测试集划分。规范的 YOLO 检测数据集目录结构一般是:

fruit-detect-yolov5-5/ ├── train/ │ ├── images/ │ │ ├── apple_001.jpg │ │ ├── banana_002.jpg │ │ └── ... │ └── labels/ │ ├── apple_001.txt │ ├── banana_002.txt │ └── ... ├── valid/ │ ├── images/ │ └── labels/ ├── test/ │ ├── images/ │ └── labels/ ├── fruit.yaml (或 dataset.yaml / fruit_detect.yaml) └── README.txt (可选)

images目录放原始图片,labels目录放对应同名 txt 标签文件。图片和标签的文件主名一一对应,后缀不同。解压后第一件事不是看图,而是用文件计数确认三个子集的数量关系——训练集样本数通常占总量的 80% 左右,验证集 20%,测试集可多可少。

在 Windows 上直接右键解压就能看到结构,Linux 或服务器上我用的是:

unzip fruit-detect-yolov5-5.zip cd fruit-detect-yolov5-5 find . -type f | head -20 # 快速看前 20 个文件

参数说明:unzip不加-d参数时会把压缩包内根目录释放到当前路径,如果压缩包作者没有在打包时包一层外层目录,建议先mkdir fruit-detect && unzip fruit-detect-yolov5-5.zip -d fruit-detect/避免文件散落一地。使用find列出文件列表时,重点看 images 和 labels 的配对情况。

2.2 标签格式核验:YOLO 格式的五个数字分别代表什么

水果检测这种单阶段目标检测任务,YOLOv5 默认使用归一化的 YOLO 标签格式。每个 txt 标签文件包含若干行,每行五个数字:

class_id x_center y_center width height

以apple_001.txt为例,文件内容可能是:

0 0.5123 0.4561 0.2345 0.3128 1 0.6789 0.3210 0.1567 0.1984

第一列class_id是类别编号,从 0 开始递增;后面四列分别是目标包围框中心点的 x、y 坐标和包围框的宽、高,全部做了归一化处理——即除以图片本身的宽高,值域在 0 到 1 之间。注意 YOLOv5 要求的中心点坐标和宽高都是相对于整张图片的比例,不是像素绝对值。

拿到数据集后建议写一行命令核对标签格式是否符合预期。我自己惯用一个极简的方式检查——先看类别总数是否跟数据配置文件里的nc一致:

wc -l train/labels/apple_001.txt head -n 3 train/labels/apple_001.txt

wc -l查看一个标签文件里有多少个目标框,head看内容是否规范。从这里能直接分辨出这份数据集标的是单类还是多类。如果标签里有第三列大于 1 的情况,说明这个 txt 可能用了像素坐标或未归一化坐标,训练时 YOLOv5 会警告甚至直接跳过该样本——这个坑后面排查章节还会细讲。

2.3 数据配置文件改写:把 nc 和 names 与你的任务对齐

找到压缩包里的 YAML 文件——一般叫fruit.yaml或fruit_detect.yaml,这是 YOLOv5 训练时的数据入口,内容很短但决定整个训练流程的路径查找。常见写法如下:

train: fruit-detect-yolov5-5/train/images val: fruit-detect-yolov5-5/valid/images test: fruit-detect-yolov5-5/test/images nc: 3 names: ['apple', 'banana', 'orange']

说明:train/val/test下填的是 images 目录的路径,YOLOv5 会自动把同级目录下的labels文件夹当成标签源。我建议你在启动训练前把这个 YAML 文件里的路径改成从 YOLOv5 项目根目录出发的相对路径,避免换一台机器、换一个终端工作目录就找不到文件。nc是类别总数,names是类别名字列表,顺序、数量和标签里的class_id一一对应——如果这份数据集包含的是其他水果,比如苹果、梨、柿子,记得把 names 改成标签里真实的类别名。

熟练之后还可以直接用sed做路径替换,把绝对路径改成相对路径:

sed -i 's|/home/user/old/path|fruit-detect-yolov5-5/train/images|g' fruit.yaml

这里用了sed -i原地替换,注意分隔符用的是|而不是常用/,是为了避免路径里自带斜杠造成转义混乱——这是路径替换时最容易翻车的地方。改完后cat fruit.yaml确认内容无误再启动训练。

3. 从零跑通 YOLOv5 训练:环境准备、数据加载与最小可复现命令

目录结构和标签格式确认无误之后,下一步就是把这份水果数据集喂进 YOLOv5 让它真正跑起来。这一步的难点不在训练本身,而在于把环境和路径问题一次清干净。很多人训练报错,追到底都是同一个原因:数据配置文件里的路径写错,或者标签里有非法字符导致加载中断。

3.1 环境准备:Python 版本、PyTorch 与依赖安装

YOLOv5 对环境要求并不苛刻,但版本组合容易踩坑。个人长期使用的组合是:Python 3.9 或 3.10 + PyTorch 1.12 以上 + CUDA 11.3 以上。如果只是验证这份水果数据集能不能用、跑通训练流程,纯 CPU 也够,但训练速度会慢到让人怀疑人生——一张 RTX 3060 大约 20 分钟能收敛的迭代,CPU 可能要跑三个小时。有条件还是用 GPU。

安装依赖之前先新建虚拟环境,防止把系统 Python 环境搞乱:

conda create -n yolov5 python=3.9 -y conda activate yolov5 pip install -r requirements.txt

requirements.txt在 YOLOv5 项目的根目录下,里面列了torch、opencv-python、numpy、pandas、seaborn等依赖项。如果你不希望 pip 自动安装 CPU 版 PyTorch,建议先手动装 GPU 版本再装其他依赖。一个常见做法是:

pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118 pip install -r requirements.txt

参数说明:第一行指定了 PyTorch 的 CUDA 11.8 版本 wheel 源,如果你本机 CUDA 版本不是 11.8,需要改成对应的 cu117/cu121。这一点不确认,后面torch.cuda.is_available()返回 False,训练白白在 CPU 上打转。

3.2 用一份最小数据配置把训练命令跑通

环境就绪后,把数据 YAML 文件放在 YOLOv5 项目的yolov5/data/目录下比较省事——因为 YOLOv5 源码里的train.py默认从data/目录解析 YAML 路径。当然你也可以把fruit.yaml放在任意位置,在命令里写完整路径即可。我最常采用的是一次性把路径和关键超参数都写在命令行里跑的最小命令:

python train.py \ --data fruit.yaml \ --weights yolov5s.pt \ --img 640 \ --batch 16 \ --epochs 100 \ --device 0

这份命令的参数逐项解释:

  • --data:指向数据配置文件,内容就是我们刚才改好的fruit.yaml,路径相对于当前命令行执行位置。建议写成data/fruit.yaml,避免终端工作目录不一致导致找不到文件。
  • --weights:预训练权重。yolov5s.pt是 YOLOv5 官方发布的 small 版本,模型体积小、训练速度快,适合验证数据质量。YOLOv5 在首次运行时自动从官方仓库下载对应权重,网络环境差时可能失败,可以手动下载后放到项目根目录。
  • --img:输入图片缩放尺寸。水果检测任务里目标通常较大,640是比较稳妥的默认值。如果图片里有很小颗的樱桃、枣子,建议改成960并配合--rect参数做矩形推理。
  • --batch:批次大小。16 是 8GB 显存下比较安全的值;显存紧张调到 8,显存富余(24GB 以上)可以上 32。
  • --epochs:迭代轮数。水果这类少类别、目标显著的检测任务,100 轮足够收敛。数据集样本量小(几百张)时,100 轮以内的早停概率很高。
  • --device:指定训练设备,0 表示第一张 GPU;用cpu表示强制 CPU 训练。

训练开始后,日志里会依次打印每轮的box_loss、obj_loss、cls_loss以及mAP@0.5、mAP@0.5:0.95等指标。第一批次跑完、看到类似Epoch gpu_mem的表格滚出来,就说明数据加载没问题,训练正常进入了。

3.3 数据增强策略的初始设定:水果检测该关掉哪些增强

YOLOv5 默认开了 Mosaic、MixUp、HSV 扰动等一大堆数据增强策略。但对水果检测这个场景,建议先做减法再谈调优。切片操作对机器人抓取场景有实际意义——水果可能密集堆放、互相遮挡,Mosaic 打乱拼接后能增强模型的抗遮挡能力。但有一类增强对水果检测是减分项:旋转和透视变换。水果形状相对规整,苹果、橙子的圆形轮廓被过度拉伸或旋转后,标注框的形状与真实目标严重不匹配,反而拉低收敛速度。

YOLOv5 的超参数文件data/hyps/hyp.scratch-low.yaml里可以手动关掉不需要的增强项:

fliplr: 0.5 # 水平翻转概率,水果检测建议保留 mosaic: 1.0 # Mosaic 增强,样本量少时强烈建议保留 mixup: 0.0 # MixUp 混类增强,水果检测建议关闭 degrees: 0.0 # 旋转角度,设为 0 关闭旋转 translate: 0.1 # 平移,保留小范围平移 scale: 0.5 # 缩放,保证大小泛化

这些参数含义:fliplr是水平翻转概率,对左右对称的水果安全;mixup会把两张图按比例混合成一张图,类别语义会被模糊,水果检测任务里实测容易让模型对边界不敏感;degrees控制随机旋转的角度范围,大多数真实水果检测的部署场景——传送带、货架——目标都是正放,旋转增强性价比不高。这些开关在第一次训练时直接改低,后面如果验证集 mAP 不够再逐步打开,做对照实验。

在 YOLOv5 里,如果不想改默认超参数文件,也可以在训练命令里直接通过--hyp指定自定义超参数文件:

cp data/hyps/hyp.scratch-low.yaml data/hyps/hyp.fruit.yaml python train.py \ --data data/fruit.yaml \ --weights yolov5s.pt \ --img 640 \ --batch 16 \ --epochs 100 \ --device 0 \ --hyp data/hyps/hyp.fruit.yaml

这里先复制了一份默认超参文件再改,避免污染官方默认配置,方便后面做消融对照。训练到 50 轮左右顺手看一眼runs/train/exp/目录下的train_batch0.jpg,如果发现画面里的水果被拉成奇怪的形状,多半是 degrees 或 perspective 没关干净。

4. 训练过程中的关键观察点:loss 曲线、mAP 与过拟合判断

训练脚本能跑起来只是第一步,模型质量高不高,要看训练过程中的曲线变化。很多新手的通病是盯着终端日志一行行刷屏,也不知道哪条指标该看、哪条可以忽略。其实 YOLOv5 训练时最该关注的只有两个:验证集 mAP 和训练集 loss 的收敛趋势。

水果检测数据集通常样本量不算大,train 和 val 的 loss 曲线拉开的时机很关键。正常过程是:前 20 轮 train loss 和 val loss 一起快速下降,20 轮之后 train loss 继续缓慢下降,如果 val loss 开始掉头上升,说明模型开始过拟合了——这时候再怎么训都是白费,正确做法是减少 epochs 或者加强数据增强。YOLOv5 训练日志里每个 epoch 结束都会打印一行val mAP@0.5指标,mAP 值不再增长反而连续五个 epoch 原地波动,就可以考虑提前终止。

在训练跑完之前,还有一个你可能已经踩进去的坑——类别不平衡。假如这份水果数据集的标签分布是苹果 1000 张、香蕉 300 张、葡萄 50 张,那么模型收敛后期,葡萄类别的 AP 会明显低于苹果和香蕉。YOLOv5 的utils/loss.py里默认的类别权重是均等的,数据分布不均时建议手动调整损失权重,或者在训练命令里加上--cls参数提高分类损失的惩罚系数。水果检测这种少类别任务,样本量少的类别往往会成为整体 mAP 的短板,这是我自己多次训练后验证过的规律。

训练结束后的产物全部在runs/train/exp/目录下,里面值得注意的文件有:

  • weights/best.pt:验证集 mAP 最高的权重,部署和推理直接用它
  • weights/last.pt:最后一个 epoch 的权重,如果训练因为中断没跑完,可以从这个权重续训
  • results.png:训练曲线汇总图,包括 loss、mAP、PR 曲线的可视化
  • confusion_matrix.png:各类别之间的混淆矩阵,看哪些水果类别互相误判

checkpoint 的命名规则其实就够日常用了。best.pt是最终选型的依据,但如果训练过程出现 val loss 异常波动,建议看一眼results.png里 PR 曲线的形态——曲线下面积小、整体贴近坐标轴,说明模型对目标位置的定位能力弱,该回头检查标签里的框坐标是否准确。

下一章集中讲训练和推理阶段最常遇到的五类问题,每条都是能直接影响训练成败的实操踩坑经验。

5. 训练与推理的五大踩坑记录:标签错位、路径飘忽、样本失效与性能假象

5.1 现象:训练日志里某个 epoch 的all指标全部变成 0

原因:标签文件里的类别编号class_id超出了数据配置文件里nc定义的范围。比如fruit.yaml声明nc: 3,但某个标签文件里出现了class_id为 4 的行。YOLOv5 在数据加载阶段不会直接中止训练,而是把这条标签视为无效数据,对应图片也会被跳过,具体表现为该 batch 的检测目标数量为零。

解决:写一段快速脚本扫描目录下所有标签文件,找出最大类别编号。通常问题出在数据集的类别顺序跟你自定义的names列表不一致。例如原数据集类别顺序是['apple', 'orange', 'banana'],而你为了业务需要把顺序改成了['apple', 'banana', 'orange']——标签里原来的 1 号类别(orange)现在被当成 banana 训练,数值层面不报错,模型实际学到的语义却乱了。我的习惯是先把标签里的class_id扫描一遍,再对齐names列表顺序。

5.2 现象:训练能启动,但每个 epoch 的img_count远小于数据集实际图片数

原因:数据集里有损坏的图片或空标签文件。fruit-detect-yolov5-5.zip解压后偶尔会出现个别图片文件只有几 KB,视觉上看不出异常,但 OpenCV 读取时直接返回空数组。YOLOv5 的LoadImagesAndLabels遇到这类图片会静默跳过,不中断训练,所以表现为样本量神秘减少。

解决:训练前先做一轮全量清洗:

python - <<EOF import cv2, glob imgs = glob.glob('fruit-detect-yolov5-5/train/images/*.jpg') print(f'total images: {len(imgs)}') broken = [p for p in imgs if cv2.imread(p) is None] print(f'broken images: {len(broken)}') for p in broken: print(p) EOF

这段脚本用cv2.imread读取全部图片,凡是返回None的就是坏图。找到坏图后,把对应的图片和标签一起删掉——注意只删图片不删标签,训练会报标签无匹配。这是最容易被忽略的细节。

5.3 现象:训练时提示AssertionError: train: No labels in ...或label shape错误

原因:标签文件和图片文件名不匹配。常见情况有三种:一是标签文件名带了多余空格或中文字符;二是图片扩展名被改过(.jpg改成.png),导致标签后缀匹配不到图片;三是压缩包在 Windows 上解压时文件名编码出了乱码。YOLOv5 查找标签的逻辑是取图片的完整主名,再尝试拼接.txt,任何一端不一致都会造成标签缺失。

解决:用一段简短的校验脚本检查文件名的严格对应关系:

ls train/images/ | wc -l ls train/labels/ | wc -l comm -3 <(ls train/images | sed 's/\.[^.]*$//') <(ls train/labels | sed 's/\.[^.]*$//')

comm -3能快速找出两个目录下主名不一致的文件——左边独有、右边独有都会列出来。扫描一遍把不配对的文件修正或删掉,比训练中途再去排查高效得多。

5.4 现象:训练 loss 一直在降,但验证集 mAP 卡在 0.2 上下不动

原因:标签框与图片内容错位。这类数据集往往在采集时使用了自动化标注工具,但因为目标分割不准确或人工校验不严谨,部分标注框偏移严重——框只框住了半个苹果,或者把果柄、叶子也圈了进去。YOLOv5 训练不报错,但模型从这类标注里学到的是错误的目标边界信息,表现为 loss 看似正常下降、mAP 始终上不去。

解决:这是数据质量问题的典型症状。打开几张训练图片,调用 YOLOv5 自带的标注可视化工具,直接把标签框叠加到图片上目检:

python detect.py --weights runs/train/exp/weights/best.pt --source fruit-detect-yolov5-5/valid/images/ --conf 0.25

检测结果输出在runs/detect/exp/,把预测框叠加图和原图对比,就能看出标签和实际物体位置的偏移程度。如果确认是标签错位,比较稳妥的办法是找出对应图片,手动用 LabelImg 或 X-AnyLabeling 重新标注,修正后替换原标签文件。

5.5 现象:训练指标 mAP 很高,但部署到实际场景里检测效果一塌糊涂

原因:数据集分布与实际业务场景不一致。常见情况是数据集里的水果图片背景干净、光线均匀、目标大而居中,但实际部署场景——超市货柜、厨房桌面、果园环境——背景杂乱、光照变化大、目标尺度不一。这属于数据集的域偏移问题,模型在验证集上指标再好看,到了真实场景也会翻车。

解决:训练之前先做数据分布比对。把数据集的图片尺寸、目标框大小分布、场景背景类型列出来,与真实部署环境对照。如果两者差别大,优先从实际场景里补充采集数据,加入训练集一起训练,而不是依赖一份公开数据集打天下。这是所有公开数据集落地时必须面对的一关,水果检测尤为典型。我一般把公开数据集当预训练基础,真实场景数据至少要占总量的 30% 以上。

6. 把训练好的权重用起来:批量推理、结果可视化与精度验证

模型训练到收敛、best.pt 保存下来,接下来的问题就变成:怎么快速看到它在真实图片上的表现,以及怎么判断它到底能不能用。YOLOv5 自带的detect.py覆盖了常规的批量推理需求,几行命令就能把验证集或测试集全部跑一遍,输出标记好检测框的图片和一份检测结果汇总。

我最常用的推理命令:

python detect.py \ --weights runs/train/exp/weights/best.pt \ --source fruit-detect-yolov5-5/test/images/ \ --conf 0.25 \ --iou 0.45 \ --save-txt \ --save-conf

参数含义:--conf设成 0.25 表示置信度高于 0.25 的检测框才保留,水果检测这类目标特征明显的任务,0.25 会给出较多候选;但实际部署取 0.3 至 0.4 之间噪音更小。--iou是非极大值抑制的 IoU 阈值,0.45 是 YOLOv5 默认值,目标是密集摆放的水果时建议微调到 0.5——提高 IoU 阈值能让相互重叠的框保留更多有效目标。--save-txt会把每个检测框的类别、置信度、坐标写入 txt 文件,--save-conf在输出框上额外标注置信度数值。检测输出在runs/detect/exp/目录下,每张图片对应一个同名 txt,内容格式是:

class_id confidence x1 y1 x2 y2

从这些 txt 文件里可以直接统计模型的有效检测率。我一般会用一段极短脚本统计被检出目标的数量,验证模型在测试集上是否存在大面积漏检:

python - <<EOF import glob labels = glob.glob('runs/detect/exp/*.txt') detected = sum(1 for l in labels if len(open(l).read().strip()) > 0) print(f'{detected}/{len(labels)} images have detections') EOF

这个统计能快速暴露大规模漏检问题。如果测试集里半数图片没有检测框输出,优先检查推理时的图片分辨率是否与训练一致、目标尺度是否远小于训练集里的常见尺寸。

精度验证方面,除了训练日志里的 mAP,更贴近实际的是在测试集上重新跑一遍验证脚本:

python val.py \ --data data/fruit.yaml \ --weights runs/train/exp/weights/best.pt \ --img 640 \ --conf 0.001 \ --iou 0.6

--conf设成最低值 0.001 是为了让所有候选框都参与评估、画出完整的 PR 曲线,反映模型在低置信度区间的召回能力;--iou 0.6是指检测框与真实标注框 IoU 达到 0.6 以上才算正确命中。打印结果里看mAP@0.5和mAP@0.5:0.95两列,前者是 PASCAL VOC 的经典指标,后者是 COCO 的严格指标,后者比前者通常低 10 到 20 个百分点,属于正常现象。

序列部署前最后一件事,是取几段真实场景视频做连续帧推理。静态图片上的表现经常高估模型能力——水果在传送带上移动时会产生运动模糊,监控场景下分辨率不足也容易漏检。把--source指向一段 mp4 文件或摄像头序号0跑一轮,看到的才是部署后的真实水平。

我自己每次做完一批数据集的训练和验证,都会保留runs/train/exp目录里所有曲线图和权重文件,同一个数据集跑过的不同超参数组合也全部归档——上次跑完确认有效的参数组合,下次换数据重新训练时能省下大量试错时间。训练结果和参数记录整理在一起,比重新读一遍训练日志要高效得多,这也是我踩过几次重复调整参数的坑之后养成的习惯。希望这个数据集的实操拆解能帮你在水果检测这条路上少走一段弯路。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询