☰
白萝卜检测数据集:1000张图双格式标签,YOLO全系开训指南
2026/10/5 5:28:43 网站建设 项目流程

简介:本资源为面向YOLO系列目标检测算法学习者的白萝卜检测数据集,适用于yolov5、yolov8、yolov9、yolov7、yolov10及yolo11等主流框架,可直接用于模型训练与验证测试,帮助初学者和进阶开发者快速搭建农作物目标检测实验环境。压缩包共2000个文件,包含1000个xml标注文件、999个txt标注文件及1个yaml配置文件,整体约32.8MB,其中txt为YOLO格式标注,xml为VOC格式标注,yaml用于数据集路径与类别配置,两种标注格式分别存放于独立文件夹,文件名末尾附带部分类别名称,便于按类别检索与管理。YOLO格式采用归一化中心点与宽高比例值,符合标准训练输入要求。数据集已完成训练集与验证集划分,省去手动切分步骤,可直接接入训练流程。目前已有63人学习下载,适合需要快速验证检测模型效果或开展农业视觉应用实践的用户参考使用。

1. 白萝卜检测数据集:1000 张图带双格式标签,YOLO 全系直接开训

做农业视觉项目的同行大概率都遇到过这个场景:算法框架搭好了,模型结构也调通了,结果卡在数据上——要么找不到足够数量的白萝卜标注图,要么标签格式对不上自己的训练脚本,要么划分好的训练集验证集比例不合理,重新切分又得折腾半天。这份白萝卜检测数据集就是冲着这个痛点来的:1000 张图像,全部带标签,已经划分好训练集和验证集,同时提供 YOLO 格式的 txt 文件和 VOC 格式的 xml 文件两套标签,附赠 data.yaml 配置文件,yolov5、yolov8、yolov9、yolov7、yolov10、yolo11 都能直接拿来跑。适合谁?做农产品分拣、田间目标计数、采摘机器人视觉模块的工程师,以及想拿一个真实场景数据集练手 YOLO 训练全流程的新手。下面从数据组织、配置对接、训练验证到踩坑排查,一步步拆开讲。

2. 数据集结构与标签格式:先搞清楚手里拿的是什么

2.1 目录组织与文件命名逻辑

拿到压缩包解压后,常见的目录结构是这样的:根目录下分 images 和 labels 两个大文件夹,images 里再按 train 和 val 切分,labels 对应同样的层级。VOC 格式的 xml 文件通常单独放在一个 annotations 文件夹里,不参与 YOLO 训练,但做格式转换或交叉验证时有用。

文件命名方面,从项目正文给出的文件名列表可以看到,图像和标签是成对出现的,比如 img_06_13.txt 对应 img_06_13.jpg(或 .png),img_0639_15.txt 对应 img_0639_15.jpg。这种命名方式的好处是,你写数据加载脚本时不需要额外维护映射表,直接用文件名主干去匹配就行。注意文件名末尾可能带类别名称后缀,这是为了方便人工核对,训练时不影响,YOLO 读取标签只看 txt 内容。

提示:解压后先别急着改目录结构,用find . -name "*.txt" | wc -l和find . -name "*.jpg" -o -name "*.png" | wc -l分别统计标签和图像数量,确认是否一一对应。如果数量对不上,先排查是不是有隐藏文件或解压不完整。

2.2 YOLO 格式标签的字段含义与读取方式

YOLO 格式的 txt 标签每行代表一个目标框,格式为:

<class> <x_center> <y_center> <width> <height>

五个字段用空格分隔。<class>是类别索引,从 0 开始;后面四个都是归一化到 0 到 1 之间的浮点数,分别表示目标框中心点的 x 坐标、y 坐标,以及框的宽度和高度,全部相对于图像宽度和高度做比例。举个例子,如果一张 640×480 的图里有个白萝卜,中心点在 (320, 240),框宽 200 像素、高 150 像素,那么标签行就是:

0 0.5 0.5 0.3125 0.3125

读取时用 Python 解析很简单:

def parse_yolo_label(label_path, img_w, img_h): boxes = [] with open(label_path, 'r') as f: for line in f.readlines(): parts = line.strip().split() if len(parts) != 5: continue cls_id = int(parts[0]) xc, yc, w, h = map(float, parts[1:]) # 转成像素坐标,方便画框验证 x1 = (xc - w / 2) * img_w y1 = (yc - h / 2) * img_h x2 = (xc + w / 2) * img_w y2 = (yc + h / 2) * img_h boxes.append((cls_id, x1, y1, x2, y2)) return boxes

这段代码的关键点在于:归一化坐标乘以图像宽高才能还原到像素空间,画框或做数据增强时必须走这一步。参数上,img_w和img_h必须和实际图像尺寸一致,否则框会偏移。常见翻车点是图像被 resize 过但标签没同步更新,导致框对不上。

2.3 VOC 格式 xml 的用途与转换思路

VOC 格式的 xml 文件保留了绝对像素坐标,结构上包含<size>里的宽高、<object>里的类别名和<bndbox>的 xmin/ymin/xmax/ymax。这份数据集同时给两套格式,实际训练 YOLO 时用 txt 就够了,xml 的价值在于:一是方便用 LabelImg 重新打开做人工复核或增补标注;二是如果你要转成 COCO 格式做对比实验,从 xml 转比从 txt 转更直接,因为 xml 里有原始像素坐标和类别名,不用反归一化。

转换脚本核心逻辑:

import xml.etree.ElementTree as ET def voc_to_yolo(xml_path, class_map): tree = ET.parse(xml_path) root = tree.getroot() size = root.find('size') img_w = int(size.find('width').text) img_h = int(size.find('height').text) lines = [] for obj in root.findall('object'): cls_name = obj.find('name').text if cls_name not in class_map: continue cls_id = class_map[cls_name] bbox = obj.find('bndbox') x1 = float(bbox.find('xmin').text) y1 = float(bbox.find('ymin').text) x2 = float(bbox.find('xmax').text) y2 = float(bbox.find('ymax').text) xc = (x1 + x2) / 2 / img_w yc = (y1 + y2) / 2 / img_h w = (x2 - x1) / img_w h = (y2 - y1) / img_h lines.append(f"{cls_id} {xc:.6f} {yc:.6f} {w:.6f} {h:.6f}") return lines

class_map是类别名到索引的映射字典,必须和 data.yaml 里的 names 顺序一致。保留六位小数是为了减少精度损失,YOLO 训练时对坐标精度不敏感,但太粗糙会影响小目标。

3. data.yaml 配置与 YOLO 全系对接:从 yolov5 到 yolo11 怎么改

3.1 data.yaml 的字段拆解与路径写法

数据集自带的 data.yaml 通常长这样:

path: ./dataset train: images/train val: images/val nc: 1 names: ['white_radish']

path是数据集根目录,train和val是相对于 path 的子路径。nc是类别数,白萝卜检测只有一类,所以是 1。names是类别名列表,顺序必须和标签里的 class 索引对应。如果你的目录结构和默认不一样,改这三个路径就行。

常见坑是路径用了绝对路径但换机器后失效,建议用相对路径,或者在训练脚本里动态拼接。另外 Windows 下路径分隔符是反斜杠,YAML 里最好统一用正斜杠,避免转义问题。

3.2 各版本 YOLO 的训练入口差异

yolov5 用train.py,命令是:

python train.py --data data.yaml --weights yolov5s.pt --img 640 --epochs 100 --batch-size 16

yolov8 及之后版本统一用yolo命令行:

yolo detect train data=data.yaml model=yolov8n.pt imgsz=640 epochs=100 batch=16

yolov9、yolov10、yolo11 的入口和 yolov8 类似,只是模型权重文件名不同,比如yolov9c.pt、yolov10n.pt、yolo11n.pt。参数含义基本一致:imgsz是输入分辨率,epochs是训练轮数,batch是批大小。1000 张图的数据集,建议从 yolov8n 或 yolo11n 这种轻量模型开始跑通流程,再换大模型。

注意:yolov5 的--img参数在 yolov8+ 里变成了imgsz,直接复制命令会报错。版本迁移时先看官方文档的参数表,别硬套。

3.3 训练前用脚本做一次标签体检

在正式训练前,强烈建议跑一个标签检查脚本,确认没有越界框、空标签、类别索引超范围等问题:

import os import cv2 def check_labels(img_dir, label_dir, nc): issues = [] for label_file in os.listdir(label_dir): if not label_file.endswith('.txt'): continue img_name = label_file.replace('.txt', '.jpg') img_path = os.path.join(img_dir, img_name) if not os.path.exists(img_path): issues.append(f"missing image: {img_name}") continue img = cv2.imread(img_path) h, w = img.shape[:2] with open(os.path.join(label_dir, label_file)) as f: for i, line in enumerate(f): parts = line.strip().split() if len(parts) != 5: issues.append(f"{label_file} line {i}: field count {len(parts)}") continue cls_id = int(parts[0]) if cls_id < 0 or cls_id >= nc: issues.append(f"{label_file} line {i}: class {cls_id} out of range") vals = list(map(float, parts[1:])) if any(v < 0 or v > 1 for v in vals): issues.append(f"{label_file} line {i}: coord out of [0,1]") return issues

这个脚本会输出所有异常记录。参数nc传 data.yaml 里的类别数。跑完如果 issues 为空,说明标签质量过关,可以放心开训。如果有越界坐标,大概率是标注时框拖到了图像外面,需要人工修正或直接剔除该样本。

4. 训练参数调优与验证:1000 张图怎么跑出可用模型

4.1 小数据集的增强策略与超参设置

1000 张图在目标检测里算小数据集,容易过拟合。常见做法是开启 Mosaic 增强和 HSV 色彩扰动,yolov5 默认就带 Mosaic,yolov8+ 也有mosaic参数。学习率方面,用预训练权重微调时,初始 lr 设 0.001 到 0.01 之间,配合余弦退火。batch size 根据显存来,8G 显存跑 640 分辨率,yolov8n 可以开到 16,yolov8m 可能只能开到 8。

如果验证集 mAP 波动大,先把close_mosaic设成最后 10 个 epoch 关闭 Mosaic,让模型在真实分布上收敛。这个技巧在农业数据集上尤其管用,因为 Mosaic 拼接会引入不自然的边界,而白萝卜在田间的背景相对固定。

4.2 训练过程监控与指标解读

训练启动后,重点看三个指标:box_loss、cls_loss 和 mAP@0.5。box_loss 下降说明框回归在收敛,cls_loss 下降说明分类在改善,mAP@0.5 是综合指标。如果 box_loss 震荡不降,检查学习率是不是太大;如果 cls_loss 很快降到接近零但 mAP 不涨,可能是类别不平衡或标注有噪声。

验证阶段用yolo detect val命令:

yolo detect val data=data.yaml model=runs/detect/train/weights/best.pt imgsz=640

输出会给出每类的 precision、recall 和 mAP。白萝卜检测只有一类,重点看 recall,漏检比误检更致命。如果 recall 低于 0.8,优先补充难样本,比如遮挡、小目标、逆光场景的图。

4.3 推理测试与结果可视化

训练完成后用 best.pt 做推理:

yolo detect predict model=best.pt source=test_images/ save=True conf=0.25

conf是置信度阈值,默认 0.25,白萝卜检测可以调到 0.3 减少误报。save=True会把画框结果存到 runs/detect/predict 目录。如果想批量统计检测数量,可以写脚本遍历输出目录,解析每张图的框数量。

提示:推理时如果发现框普遍偏大或偏小,检查训练时的 imgsz 和推理时的 imgsz 是否一致。不一致会导致框尺度错位,这是血泪经验。

5. 避坑与排查:标签、路径、显存三个高频翻车点

5.1 标签文件与图像文件不匹配

现象:训练启动后报No labels found或 loss 一直为 nan。原因:标签目录和图像目录的文件名主干不一致,或者标签文件为空。解决:用 3.3 节的检查脚本先跑一遍,确认每个图像都有对应标签且标签内容非空。如果文件名有大小写差异,统一转成小写再匹配。

5.2 data.yaml 路径错误导致数据集加载失败

现象:报Dataset not found或0 images found。原因:path字段写的是相对路径,但训练脚本的工作目录和数据集根目录不在同一层级。解决:在 data.yaml 里用绝对路径,或者在训练命令前先cd到数据集根目录。另一个常见原因是train和val字段忘了带images/前缀,直接写了train,YOLO 会去根目录找。

5.3 显存不足导致训练中断

现象:报CUDA out of memory。原因:batch size 太大或 imgsz 太高。解决:先把 batch 降到 4 或 2,确认能跑通后再逐步往上加。如果显存实在紧张,把 imgsz 从 640 降到 416 或 320,但注意小目标检测精度会下降。另一个技巧是开启混合精度训练,yolov8+ 默认开启 AMP,yolov5 加--amp参数。

5.4 验证集 mAP 异常低但训练 loss 正常

现象:训练 loss 稳步下降,但验证 mAP 始终在 0.1 以下。原因:验证集和训练集的类别分布差异大,或者验证集标签格式有问题。解决:分别统计训练集和验证集的类别数量和框尺寸分布,如果验证集里全是小目标而训练集全是大目标,模型泛化会差。另外检查验证集的 txt 文件是不是误用了 VOC 格式的坐标。

5.5 推理结果框重叠严重

现象:同一根白萝卜被检测出多个框。原因:NMS 阈值设得太高,或者模型对重叠目标区分能力不足。解决:推理时调低iou参数,默认 0.45,可以试 0.3。如果还是重叠,说明训练数据里密集目标标注不一致,需要回头检查标注质量。

6. 进阶技巧:用 TTA 和模型集成把白萝卜检测 recall 再拉一截

训练跑通之后,如果 recall 还差那么几个点,可以试试测试时增强(TTA)。YOLO 官方支持augment=True推理,会对每张图做翻转、缩放等多尺度预测再融合:

yolo detect predict model=best.pt source=test_images/ augment=True conf=0.25 iou=0.4

TTA 的代价是推理速度变慢,大概慢 2 到 3 倍,但 recall 通常能涨 1 到 3 个百分点。对于白萝卜这种形状相对规则的目标,水平翻转和轻微缩放增强效果最明显。

另一个技巧是模型集成。用 yolov8n 和 yolo11n 分别训练,推理时把两个模型的框合并再做一次 NMS。集成脚本核心逻辑:

from ultralytics import YOLO import numpy as np model_a = YOLO('runs/yolov8n/weights/best.pt') model_b = YOLO('runs/yolo11n/weights/best.pt') def ensemble_predict(img_path, conf=0.25, iou=0.5): boxes_a = model_a(img_path, conf=conf)[0].boxes boxes_b = model_b(img_path, conf=conf)[0].boxes all_boxes = np.concatenate([boxes_a.xyxy.cpu().numpy(), boxes_b.xyxy.cpu().numpy()], axis=0) all_scores = np.concatenate([boxes_a.conf.cpu().numpy(), boxes_b.conf.cpu().numpy()], axis=0) # 这里接一个 NMS 实现,按 iou 阈值过滤 keep = nms(all_boxes, all_scores, iou) return all_boxes[keep], all_scores[keep]

nms函数可以用 torchvision 的torchvision.ops.nms,传入框的 tensor 和分数即可。集成的收益取决于两个模型的差异度,如果都是 yolov8n 只是随机种子不同,提升有限;用不同架构的模型集成效果更好。

验证集成效果时,别只看 mAP,把 recall 单独拎出来对比。白萝卜检测场景下,漏检一根萝卜的代价比多检一个框高得多。我一般会在验证集上跑三组对比:单模型、单模型+TTA、双模型集成,选 recall 最高且推理耗时能接受的那个方案。

从那以后我每次拿到新数据集,都强制先跑一遍标签体检脚本,再开训练。这个习惯帮我省了至少三次通宵排查的功夫。希望帮到你。

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

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

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

立即咨询