简介:这份资源面向从事农业智能识别、计算机视觉方向的学生与算法工程师,提供一套可直接用于YOLO系列目标检测训练的杂草检测数据集,帮助解决田间杂草识别任务中样本不足、标注格式不统一的问题。压缩包共约2000个文件,以xml格式的VOC标注文件为主,同时配套txt格式标签,兼顾不同检测框架的读取习惯;整体包体约128.06MB,规模适中便于本地快速加载与调试。数据集目录已按train、val、test完成划分,并附有data.yaml配置文件,yolov5、yolov7、yolov8、yolov9等主流算法可直接接入训练,无需额外整理路径。目前已有449人学习下载,读者可借此快速搭建杂草检测基线模型,验证数据增强、类别平衡与迁移学习等策略,并对照检测结果参考进一步优化精度与召回表现。
1. 杂草识别项目里,4000 张图的数据集到底能不能直接开练
田里长草这件事,做农业视觉的同行都懂:不是识别不出来,是数据不够“野”。我最早做除草机器人感知模块时,拿公开的植物分类数据集凑数,实验室里 mAP 挺好看,一放到真实垄沟就翻车——逆光、遮挡、幼苗和杂草长得几乎一样。这次拆的这份yolo算法杂草检测数据集,核心价值就在“量”和“场景贴合度”:4000 多张标注好的杂草图像,直接对应 YOLO 系列的目标检测训练格式,省掉了最耗时的采集和标框环节。
它适合三类人:一是做智慧农业、除草机器人、无人机巡田的算法同学,想快速验证检测头和后处理;二是学生或转行者,需要一个真实场景数据集跑通 YOLO 训练全流程;三是已有模型想加一类“杂草”目标的工程师,拿它做增量数据。不适合谁?想直接拿去做植保决策、要求物种级细分类的,这份数据是“杂草 vs 作物”的检测级标注,不是分类级。下面我按“先看懂数据 → 再跑通训练 → 再避开坑”的顺序,把这份资源怎么落地讲透。
2. 先看清数据长什么样:目录结构、标注格式与类别定义
拿到一个检测数据集,我第一件事不是写训练脚本,而是把目录和标注翻一遍。翻车最多的不是模型,是数据本身对不上 YOLO 的预期格式。这一章先把这份杂草检测数据集的结构、标注和类别讲清楚,你才知道后面data.yaml该怎么写。
2.1 典型目录结构与文件对应关系
这类 YOLO 格式数据集,常见做法是 images 和 labels 分离,train/val 各自成对。你解压后大概率看到类似结构(不同打包方式略有差异,以实际为准):
weed_dataset/ ├── images/ │ ├── train/ # 训练图像,jpg/png │ │ ├── weed_0001.jpg │ │ └── ... │ └── val/ # 验证图像 │ └── ... ├── labels/ │ ├── train/ # 与图像同名的 txt 标注 │ │ ├── weed_0001.txt │ │ └── ... │ └── val/ │ └── ... └── data.yaml # 数据集配置文件(可能需自己补)关键点:labels 下的 txt 必须和 images 下的图一一同名,只差扩展名。我见过有人把标注全塞一个文件夹,结果训练时 loss 一直是 nan,查半天才发现路径没对上。先跑一遍配对检查,比什么都强。
import os img_dir = "weed_dataset/images/train" lbl_dir = "weed_dataset/labels/train" imgs = {os.path.splitext(f)[0] for f in os.listdir(img_dir)} lbls = {os.path.splitext(f)[0] for f in os.listdir(lbl_dir)} print("图片数:", len(imgs), "标注数:", len(lbls)) print("有图无标注:", list(imgs - lbls)[:10]) print("有标注无图:", list(lbls - imgs)[:10])这段脚本做的是集合差运算:imgs - lbls找出没有标注的图,lbls - imgs找出没有图的标注。参数上只需改两个目录路径。正常情况两者数量应完全一致,差集为空;如果差集里出现大量文件名,说明打包时漏了文件,得先补齐再训练,否则 YOLO 会静默跳过或报错。
2.2 YOLO 标注格式与类别编号
YOLO 检测的标注是归一化的class x_center y_center width height,每行一个目标,取值 0~1。打开一个 txt 看:
0 0.512 0.634 0.221 0.318 0 0.301 0.402 0.180 0.265第一列是类别索引,后四列是框中心点和宽高,都除以了图像宽高。这里要确认两件事:类别数和索引从 0 还是 1 开始。有些数据集标注从 1 开始,直接喂给 YOLO 会越界或错类。快速统计一下所有出现过的类别值:
import glob classes = set() for txt in glob.glob("weed_dataset/labels/train/*.txt"): with open(txt) as f: for line in f: if line.strip(): classes.add(int(line.split()[0])) print("出现的类别索引:", sorted(classes))如果输出是[0],说明是单类(只有“杂草”);如果是[0, 1],可能是“杂草 + 作物”两类。索引必须从 0 连续,出现[1, 2]或跳号就要在转换脚本里减 1 重映射。这一步不做,训练时类别名和索引会对不上,验证阶段画出来的框全是错的。
2.3 data.yaml 怎么写才不出错
YOLOv5/v8 都靠一个 yaml 描述数据路径和类别。基于上面的结构,我一般这样写:
path: ./weed_dataset # 数据集根目录 train: images/train # 相对 path 的训练图目录 val: images/val # 相对 path 的验证图目录 nc: 1 # 类别数,按 2.2 统计结果填 names: 0: weed # 类别名,顺序必须和索引一致参数说明:path是根,train/val是相对它的子路径,YOLO 会自动把images替换成labels去找标注,所以目录名最好保持 images/labels 对称。nc和names必须和实际标注一致——这是最常见的翻车点,nc写错会导致训练直接报维度不匹配。写完 yaml,先别急着开训,用官方脚本或自己写个可视化把框画到图上,肉眼确认框位置和类别没错,再进入下一章。
3. 用 YOLOv8 跑通训练:环境、命令与参数怎么调
数据确认无误后,就进入训练环节。这一章以 YOLOv8 为主线(YOLOv5 命令大同小异),把环境、训练命令、关键参数和验证方法讲清楚。yolov8训练自己的数据集这套流程在农业场景里同样适用,区别只在数据分布和增强策略。
3.1 环境搭建与依赖安装
我一般用 conda 隔离环境,避免和系统里的 torch 打架。常见做法是:
conda create -n weed_yolo python=3.10 -y conda activate weed_yolo # 安装 PyTorch,按你的 CUDA 版本选对应命令 pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118 # 安装 ultralytics pip install ultralytics参数说明:Python 选 3.10 兼容性最好;torch 的 index-url 要和你显卡驱动匹配,CUDA 11.8 对应 cu118,12.x 对应 cu121。装完跑一句yolo checks或python -c "import torch; print(torch.cuda.is_available())",输出 True 才算 GPU 可用。如果只有 CPU,训练会慢到怀疑人生,4000 张图建议至少一张 8G 显存的卡。
3.2 训练命令与关键参数
YOLOv8 用命令行就能起训,我常用的配置:
yolo detect train \ data=weed_dataset/data.yaml \ model=yolov8n.pt \ epochs=100 \ imgsz=640 \ batch=16 \ lr0=0.01 \ patience=20 \ project=runs/weed \ name=exp1逐项说明:model=yolov8n.pt是 nano 版预训练权重,杂草单类任务够用,想提精度换yolov8s.pt;epochs=100配合patience=20,20 轮没提升就早停,省时间;imgsz=640是检测常用分辨率,田间小目标多可以试 960,但显存翻倍;batch=16按显存调,爆显存就降到 8;lr0=0.01是初始学习率,微调预训练模型时偏大,可降到 0.001。project/name决定权重和日志存哪,方便多组实验对比。
训练启动后重点盯三个指标:box_loss应稳步下降,mAP50逐步上升,mAP50-95更严格。如果 loss 震荡不降,先查学习率和 batch;如果 mAP 卡住不动,多半是数据标注或类别配置有问题,回到第 2 章复查。
3.3 验证与推理:确认模型真的能用
训练完先别高兴,用验证集跑一遍,再用真实图推理看效果:
# 验证 yolo detect val model=runs/weed/exp1/weights/best.pt data=weed_dataset/data.yaml # 单图推理 yolo detect predict model=runs/weed/exp1/weights/best.pt source=test_field.jpg conf=0.25 save=Trueconf=0.25是置信度阈值,田间误检多就调高到 0.4,漏检多就降到 0.15。推理结果默认存到runs/detect/predict。我习惯拿几张逆光、密集杂草的图单独测,因为验证集 mAP 高不代表真实场景稳。如果发现小目标漏检严重,把imgsz提到 960 重训,或换yolov8s/m更大模型。这一步是判断这份数据集训练出来的模型能不能上线的关键,别只看一个 mAP 数字就收工。
4. 避坑与排查:杂草检测训练里最容易翻车的五件事
这一章是我踩过的血泪经验合集。杂草检测和常规目标检测不同,背景杂、目标小、类间相似度高,很多坑是通用的但在这里被放大。每条按“现象 → 原因 → 解决”写,照着排查能省你几天时间。
4.1 现象:训练 loss 正常但 mAP 极低
原因:最常见是标注类别索引和data.yaml的names对不上,或者标注坐标没归一化(还是像素值)。YOLO 对越界坐标不报错,只是默默学歪。解决:回到 2.2 的统计脚本确认索引从 0 连续,再抽查几个 txt,确认后四列都在 0~1 之间。若发现大于 1 的值,说明标注是像素坐标,需要写脚本除以图像宽高重新归一化。
4.2 现象:验证时框位置对但类别全错
原因:names顺序和标注索引不一致。比如标注 0 是作物、1 是杂草,你 yaml 里写反了。解决:打开几张图的可视化标注,对照names逐个核对。单类任务一般不会遇到,多类任务必查。改完 yaml 重新训练,权重不能复用。
4.3 现象:显存爆掉,batch 降到 1 还 OOM
原因:imgsz太大或模型太大,也可能是 dataloader 的 workers 开太多。解决:先把imgsz从 960 降回 640,模型换 nano;再把workers设为 2~4(Windows 下建议 0)。如果还爆,用batch=4配合梯度累积(YOLOv8 里用nbs间接控制)。别硬扛大分辨率,先跑通再优化。
4.4 现象:小杂草目标几乎检测不到
原因:田间杂草幼苗在 640 分辨率下只有十几个像素,特征太弱。解决:提高imgsz到 960 或 1280;开启 Mosaic、MixUp 增强(YOLOv8 默认开 Mosaic);或在数据层面裁剪放大目标区域做补充。如果数据集本身小目标占比高,考虑换带 P2 检测头的模型结构,专门加一层高分辨率特征图。
4.5 现象:模型在验证集好,实拍图一塌糊涂
原因:数据集场景单一,缺少逆光、阴影、不同土壤背景的样本,域偏移严重。解决:先做数据增强扩展(亮度、对比度、HSV 抖动),再补采真实场景图。如果短期没法补数据,推理时用 TTA(测试时增强)或多尺度推理缓解。这也是我为什么强调第 3.3 步一定要拿真实图测——验证集是“自己人”,实拍才是考场。
5. 进阶技巧:把 4000 张图榨干,以及怎么验证模型真能用
数据量固定时,提升空间在“怎么用”和“怎么验”。这一章讲两个具体技巧:一是用数据增强和迁移学习把 4000 张图的泛化拉满,二是用一套可复现的验证流程判断模型能不能上田间设备。
5.1 数据增强与迁移学习的组合拳
YOLOv8 默认带了 Mosaic、随机缩放、HSV 抖动,但对农业场景,我一般再补几项。在训练命令里加超参:
yolo detect train \ data=weed_dataset/data.yaml \ model=yolov8s.pt \ epochs=150 \ imgsz=640 \ batch=16 \ hsv_h=0.015 hsv_s=0.7 hsv_v=0.4 \ degrees=10 translate=0.1 scale=0.5 \ fliplr=0.5 flipud=0.0 \ mosaic=1.0 mixup=0.1参数说明:hsv_s=0.7、hsv_v=0.4加大饱和度亮度扰动,模拟不同光照;degrees=10小幅旋转,适应相机安装角度偏差;scale=0.5缩放增强小目标鲁棒性;fliplr=0.5水平翻转,flipud=0因为田间图像上下翻转不真实;mixup=0.1轻度混合,别开太大否则杂草和作物混一起反而学乱。迁移学习上,从 COCO 预训练权重起步,前几轮冻结 backbone 只训 head,再解冻全量微调,收敛更快也更稳。
5.2 一套可复现的验证流程
我判断模型能不能用,不看单一 mAP,而是走三步。第一步,验证集看mAP50和mAP50-95,前者宽松后者严格,两者差距大说明框定位不准。第二步,按目标尺寸分桶统计召回率,小目标召回低于 0.5 就得回炉。第三步,拿 20 张完全没参与训练的真实田间图,人工数漏检和误检,算一个“实战准确率”。这三步走完,心里才有底。
from ultralytics import YOLO model = YOLO("runs/weed/exp1/weights/best.pt") results = model.val(data="weed_dataset/data.yaml", imgsz=640) # 按尺寸看召回,需结合自定义脚本统计 print("mAP50:", results.box.map50) print("mAP50-95:", results.box.map)这段代码跑官方验证并打印两个核心指标。results.box.map50是 IoU=0.5 时的平均精度,results.box.map是 0.5~0.95 的平均。实际项目里我会把结果导出成表格,和上一版模型对比,只有两项都提升才替换线上权重。
5.3 部署前的最后一道关
模型训练完,导出成部署格式再测一遍速度。田间设备算力有限,常见做法是导出 ONNX 或 TensorRT:
yolo export model=runs/weed/exp1/weights/best.pt format=onnx imgsz=640 yolo export model=runs/weed/exp1/weights/best.pt format=engine imgsz=640 half=Trueformat=onnx通用性好,format=engine是 TensorRT,NVIDIA 设备上提速明显,half=True用 FP16 进一步压延迟。导出后务必用同一批测试图对比原模型和导出模型的输出,确认精度没掉。我吃过一次亏:导出时忘了对齐预处理,结果框整体偏移,田里跑起来才发现。从那以后我每次导出都强制走一遍“原模型 vs 导出模型”的逐图对比,确认一致才敢上车。希望这份拆解帮到你,少走我走过的弯路。
本文还有配套的精品资源,点击获取