简介:本资源为面向YOLO系列算法目标检测任务的萝卜检测数据集,适合从事农业视觉识别、目标检测模型训练与验证的开发者及学生使用。数据集已按训练与验证需求划分完毕,并附带data.yaml配置文件,可直接适配yolov5、yolov8、yolov9、yolov7、yolov10及yolo11等主流框架,省去自行标注与划分的繁琐流程。压缩包共2000个文件,包含1000个xml标注文件、999个txt标注文件及1个yaml配置文件,整体约32.8MB;其中txt文件采用YOLO格式,记录类别索引与归一化后的中心点坐标、宽高比例,xml文件则为VOC格式,两种标注可分别用于不同训练流程。目前已有63人学习下载。借助该数据集,读者可快速完成模型训练、验证与测试,理解标注格式转换与配置文件编写,为白萝卜检测项目提供可直接复用的数据基础。
1. 白萝卜检测数据集到底能解决什么:从1000张带标签图像说起
去年帮一个做农机视觉的朋友调模型,他拿了一堆大棚里拍的白萝卜照片,想做一个自动计数和分级的东西。结果卡在第一步:网上公开的萝卜类数据集几乎找不到,COCO 里没有,ImageNet 里也没有细分类别。最后只能自己扛着相机去地里拍,回来再一张张标。所以当我看到「YOLO算法-白萝卜检测数据集-1000张图像带标签.zip」这个标题时,第一反应是:这东西对做农业视觉的人来说,省掉的是最枯燥的那两周。
这个数据集的核心价值在于「带标签」三个字。1000 张图像如果只是图片,那叫素材库;带上 YOLO 格式的标注框,才叫可训练数据集。它解决的是从零标注到能跑通训练之间那段最耗人力的环节。适合谁用?做智慧农业的算法工程师、农学院里想验证检测方案的研究生、以及想拿一个真实场景练手 YOLO 的开发者。你不需要自己搭标注环境,不需要纠结标签格式转换,拿到就能直接喂给 YOLOv5 或 YOLOv8 跑起来。
但这里有个前提得说清楚:1000 张在目标检测里属于小样本量级。它能让你快速验证流程、跑通 baseline,但别指望直接拿去产线部署。我一般会把它当作「冷启动数据集」——先用它把训练管线跑通,确认数据增强、anchor 设置、评估指标都正常,再决定要不要扩标到 5000 张以上。这个定位想明白了,后面的每一步才不会走偏。
2. 拿到压缩包先别急着解压:目录结构与标签格式的核对方法
2.1 一个合格的白萝卜检测数据集应该长什么样
在动手写任何训练脚本之前,先花十分钟把数据集的目录结构摸清楚。这不是浪费时间,而是避免后面训练到一半发现标签对不上号。常见的 YOLO 数据集有两种组织方式:一种是 images 和 labels 平行目录,另一种是 train/val 下各带 images 和 labels。不管哪种,核心是图像文件和标注文件必须一一对应,文件名相同、扩展名不同。
白萝卜这个场景有个特殊之处:萝卜在地里是半埋状态,叶片和根茎交界处容易混淆。所以标注质量比格式更重要。你打开几张标注可视化图,重点看三个地方:一是萝卜主体框有没有把叶片也框进去,二是相邻萝卜有没有框重叠,三是小目标萝卜有没有被漏标。这三点直接决定模型学到的边界在哪里。
我一般会写一个快速统计脚本,先看类别分布和框的尺寸分布。如果发现某个尺寸区间的框特别少,后面训练时就要针对性做尺度增强。这个动作花不了几分钟,但能让你对数据集的「脾气」有个底。
2.2 用 Python 脚本核对图像与标签的配对情况
下面这段代码做三件事:统计图像数量、检查每个图像是否有对应标签、输出标注框的宽高分布。你拿到任何 YOLO 格式数据集都可以先跑一遍。
import os import glob from collections import Counter # 数据集根目录,按实际路径修改 root = "./bailuobo_dataset" img_dir = os.path.join(root, "images") lbl_dir = os.path.join(root, "labels") # 支持的图像扩展名 img_exts = ["*.jpg", "*.jpeg", "*.png", "*.bmp"] img_files = [] for ext in img_exts: img_files.extend(glob.glob(os.path.join(img_dir, ext))) print(f"图像总数: {len(img_files)}") missing_label = [] empty_label = [] box_w_list = [] box_h_list = [] for img_path in img_files: base = os.path.splitext(os.path.basename(img_path))[0] lbl_path = os.path.join(lbl_dir, base + ".txt") if not os.path.exists(lbl_path): missing_label.append(base) continue with open(lbl_path, "r") as f: lines = [l.strip() for l in f if l.strip()] if len(lines) == 0: empty_label.append(base) continue for line in lines: parts = line.split() # YOLO 格式: class_id x_center y_center width height (归一化) if len(parts) >= 5: box_w_list.append(float(parts[3])) box_h_list.append(float(parts[4])) print(f"缺失标签的图像数: {len(missing_label)}") print(f"空标签文件数: {len(empty_label)}") if box_w_list: print(f"标注框总数: {len(box_w_list)}") print(f"框宽归一化均值: {sum(box_w_list)/len(box_w_list):.4f}") print(f"框高归一化均值: {sum(box_h_list)/len(box_h_list):.4f}") # 按面积粗略分档 small = sum(1 for w,h in zip(box_w_list, box_h_list) if w*h < 0.02) mid = sum(1 for w,h in zip(box_w_list, box_h_list) if 0.02 <= w*h < 0.2) large = sum(1 for w,h in zip(box_w_list, box_h_list) if w*h >= 0.2) print(f"小目标框数: {small}, 中目标框数: {mid}, 大目标框数: {large}")这段代码的逻辑很直白:先收集所有图像路径,然后逐个去找同名 txt。缺失标签和空标签要分开统计,因为处理方式不同——缺失可能是漏标,空标签可能是负样本。框的宽高是归一化值,乘以图像尺寸才是像素值。面积分档的阈值 0.02 和 0.2 是我自己的习惯,你可以根据白萝卜在画面中的实际占比调整。
参数说明:root改成你解压后的实际路径;如果数据集是 train/val 分目录的,把img_dir和lbl_dir分别指向对应子目录再跑一次。跑完之后,如果缺失标签超过 5%,建议先补齐再训练,否则模型会学到错误的背景信息。
3. 从零跑通 YOLOv8 训练:配置文件、命令与参数含义
3.1 数据集 YAML 怎么写才不出错
YOLOv8 用 YAML 文件描述数据集路径和类别。这个文件看着简单,但路径写错一个字符就是「No labels found」的报错。我一般把 YAML 放在数据集根目录下,用相对路径引用,这样整个文件夹拷到别的机器上也能直接用。
# bailuobo.yaml path: ./bailuobo_dataset # 数据集根目录 train: images/train # 训练集图像相对路径 val: images/val # 验证集图像相对路径 nc: 1 # 类别数,白萝卜只有一类就是1 names: 0: bailuobo # 类别名称,英文避免编码问题这里有几个容易翻车的点。第一,path如果写绝对路径,换机器就废了,建议用相对路径。第二,train和val是相对于path的路径,不是相对于 YAML 文件本身。第三,如果你的图像和标签不在平行目录,比如标签统一放在labels/train,那 YOLOv8 默认会去找images同级的labels,路径结构要提前对齐。
类别名用英文是血泪经验。中文类别名在某些版本的训练日志里会乱码,虽然不影响训练结果,但排查问题时看着难受。白萝卜写成bailuobo或者radish都行,保持前后一致就好。
3.2 训练命令与关键参数逐个拆解
环境装好之后,一条命令就能启动训练。但这条命令里的每个参数都值得说清楚,因为默认值不一定适合白萝卜这个场景。
yolo detect train \ data=./bailuobo.yaml \ model=yolov8n.pt \ epochs=100 \ imgsz=640 \ batch=16 \ lr0=0.01 \ patience=20 \ augment=True \ project=./runs/bailuobo \ name=exp1model=yolov8n.pt选的是 nano 版本,参数量最小,适合先跑通流程。1000 张图用 nano 模型,在单张消费级显卡上大概十几分钟一个 epoch。如果你有更好的显卡,可以换yolov8s.pt或yolov8m.pt,但小数据集上大模型更容易过拟合,n 和 s 通常够用。
epochs=100配合patience=20是早停策略:如果 20 个 epoch 验证指标没提升就自动停。白萝卜数据集小,实际可能 60 到 80 个 epoch 就收敛了。batch=16是保守值,显存够可以加到 32,显存不够就降到 8,但太小会让 BatchNorm 统计不稳定。
lr0=0.01是初始学习率,YOLOv8 默认用 SGD 时这个值比较稳。如果你换成 AdamW,学习率要降到 0.001 量级。augment=True开启默认增强,包括 HSV 抖动、随机翻转、缩放。白萝卜在地里光照变化大,HSV 增强很有必要,但要注意翻转增强对垂直生长的作物可能不适用——萝卜倒过来还是萝卜,所以问题不大。
训练开始后,重点盯三个输出:box_loss是否稳定下降、mAP50是否在涨、val/box_loss和train/box_loss的差距。如果训练 loss 降但验证 loss 涨,就是过拟合信号,该减模型或加数据了。
3.3 训练完怎么看结果:混淆矩阵和 PR 曲线
训练结束后,runs/bailuobo/exp1目录下会生成一堆可视化文件。别只看最后的 mAP 数字,我一般会重点看两张图:confusion_matrix.png和PR_curve.png。
混淆矩阵里,如果白萝卜被大量分到 background,说明漏检严重,可能是标注框太小或者置信度阈值太高。如果 background 被分成白萝卜,说明误检多,可能是背景里有类似形状的物体。PR 曲线看的是不同置信度下的精确率和召回率平衡点,白萝卜检测如果用于计数,召回率比精确率更重要,曲线要往右上角靠。
还有一个val_batch0_pred.jpg这样的预测可视化图,直接看模型在验证集上的实际表现。我习惯挑几张预测错的图,对照原图看是标注问题还是模型问题。如果是标注框本身偏了,那再怎么调参也没用,得回去修标签。
4. 白萝卜检测的避坑清单:从标注到推理的五个翻车点
4.1 标注框把叶片框进去导致模型学偏
现象:训练 loss 正常下降,mAP 也有 0.7 左右,但推理时模型总是把萝卜叶片一起框进去,框比实际萝卜大一圈。
原因:标注时为了省事,把整棵萝卜连叶片一起框了。模型学到的是「萝卜+叶片」的组合特征,而不是萝卜主体。白萝卜的叶片形状和杂草接近,这会让模型在复杂背景里分不清。
解决:重新检查标注,只框萝卜露出地面的根茎部分。如果叶片遮挡严重,宁可标小一点也不要扩大框。改完标签后重新训练,mAP 可能暂时下降,但推理框会准很多。
4.2 验证集 mAP 很高但实际推理一塌糊涂
现象:验证集 mAP50 到 0.85,但拿手机拍几张新照片推理,漏检率超过一半。
原因:1000 张图如果都来自同一块地、同一个时间段、同一种光照,验证集和训练集分布几乎一样,mAP 虚高。换一个场景,模型就崩了。
解决:划分验证集时按拍摄批次或地块划分,不要随机分。如果数据集本身多样性不足,训练时加大 HSV 增强的饱和度和亮度范围,同时加随机裁剪和旋转。推理时如果场景差异大,考虑用测试时增强(TTA)临时补救。
4.3 小目标萝卜在 640 分辨率下直接消失
现象:图像里远处的萝卜在标注时存在,但训练后模型完全检测不到。
原因:YOLOv8 默认 640 输入,下采样 32 倍后,小于 20 像素的物体在特征图上只剩不到一个像素。白萝卜如果占画面比例很小,特征直接丢了。
解决:两个方向。一是提高输入分辨率到 1280,但显存和推理时间翻倍。二是用切片推理,把大图切成小块分别检测再合并。我一般先统计标注框的像素尺寸分布,如果小目标占比超过 30%,就直接上 1280 训练。
4.4 标签文件里的类别 ID 从 1 开始
现象:训练时报错「Label class 1 exceeds nc=1」,或者训练完模型把所有东西都预测成背景。
原因:YOLO 格式要求类别 ID 从 0 开始。有些标注工具导出时从 1 开始,或者手动改标签时没注意。
解决:写个脚本把所有标签文件的第一列减 1,同时确认没有负数。改完再跑一遍 2.2 节的核对脚本,确认类别 ID 范围在 0 到 nc-1 之间。
4.5 数据增强把萝卜转没了
现象:训练几个 epoch 后,模型突然开始预测大量空框,loss 震荡。
原因:YOLOv8 默认增强里有随机旋转和剪切,如果萝卜在图中本来就靠近边缘,增强后可能被裁掉大半,标签框还在但目标已经没了。这种「标签存在但目标不可见」的样本会严重干扰训练。
解决:检查增强后的可视化图,如果发现大量目标被裁切,降低degrees和shear参数,或者开启mosaic时注意边界。我一般会在训练前用yolo detect train的save_datasets选项导出增强后的图看一眼,确认没有明显异常再正式跑。
5. 把 1000 张用出 5000 张的效果:小数据集上的进阶技巧
1000 张图训练一个能用的白萝卜检测模型,关键不在于模型多大,而在于怎么把每一张图榨干。我自己的习惯是分三步走:先跑一个 baseline 确认流程,再用迁移学习和增强策略提升,最后用半自动标注扩数据。
第一步,baseline 用yolov8n.pt预训练权重,冻结 backbone 前几层训练 50 个 epoch。这一步的目的是确认数据管线没问题,mAP 能到 0.6 以上就说明标签质量过关。如果连 0.5 都到不了,别急着调参,回去查标签。
第二步,解冻全部层,用余弦退火学习率从 0.01 降到 0.0001,训练 150 个 epoch。同时开启mixup和copy_paste增强。copy_paste对小目标检测特别有用,它把一张图里的萝卜复制粘贴到另一张图上,相当于免费扩样本。但要注意粘贴后的边界融合,YOLOv8 内置的版本已经处理了这个问题。
第三步,用训练好的模型对未标注的田间照片做推理,把置信度高于 0.7 的预测框转成 YOLO 标签,人工复核一遍。这一步能把 1000 张扩到 3000 张以上,而且新样本来自不同光照和角度,比单纯复制粘贴更有价值。复核时重点看边缘框和重叠框,这两类最容易出错。
验证方法上,我一般留出 10% 的数据做「锁定测试集」,训练过程中完全不碰。等所有调参结束后,用这个测试集跑一次最终评估。如果锁定测试集的 mAP 和验证集差距在 5 个点以内,说明没有过拟合验证集,模型可以拿去实际场景试跑。
最后说一个我踩过的坑:别在 1000 张图上反复调参超过两周。小数据集的性能上限是肉眼可见的,与其死磕 mAP 从 0.82 到 0.84,不如花时间标 500 张新图。数据量翻倍带来的提升,比任何调参技巧都直接。希望帮到你。
本文还有配套的精品资源,点击获取