资讯动态

YOLO作物杂草数据集:200张带标签图像的目标检测训练全流程解析

发布时间:2026/10/9 2:46:28 来源:尧图企业网站定制
简介面向YOLO系列算法学习与作物杂草检测场景这套数据集包含200张已标注图像及完整标签已划分好训练集与验证集并附带data.yaml配置文件可直接用于YOLOv5、YOLOv8、YOLOv9、YOLOv7、YOLOv10、YOLO11等主流版本的模型训练与测试。标签同时提供YOLO格式txt与VOC格式xml两种版本分别存放于独立文件夹其中YOLO格式按类别索引、归一化中心坐标和宽高记录目标框方便不同框架间自由切换。压缩包共601个文件涵盖200个jpg图像、200个txt标签、200个xml标签及1个yaml配置整体大小185.56MB目录结构清晰。目前已有106人学习下载。对于需要快速获取高质量作物杂草标注数据、节省手动标注时间的研究者或初学者该数据集可直接用于算法验证、精度对比和模型调优是开展目标检测实验的实用基础资源。1. YOLO作物杂草数据集200张带标签图像为什么值得你下载做目标检测最熬人的环节不是调模型而是攒数据。一张张找图、标注、转格式、切分训练验证集一套流程下来半天就没了。这份作物杂草数据集把yolo算法目标检测数据集最麻烦的几件事提前做完200张图像全部带标签同时给了YOLO的txt和VOC的xml两种标注格式目录已经划分好train/val/test连data.yaml都写好了。解压之后从YOLOv5一路训到v8、v9、v10、YOLO11都能直接跑不用再写一行转换脚本。我拆过不少类似的数据包负责任地说这类小数据集真正的价值不是拿来刷精度而是让你把训练链条完整走通搞清楚标注格式怎么解析、data.yaml怎么配、模型训练参数怎么调、验证结果怎么判读。适合两类人——第一次跑YOLO想验证全流程的新手以及需要小样本快速出baseline做迁移学习的开发者。2. 两种标注格式并存YOLO txt与VOC xml的换算与切换2.1 数据集目录结构一个zip解开后应该长什么样先把压缩包解开看目录结构。这套数据集最省事的地方在于标注文件不是混在一起而是按格式分目录存放。常见的目录组织方式如下crop_weed/ ├── data.yaml ├── images/ │ ├── train/ │ │ ├── img_0323_0.jpg │ │ ├── img_0323_7.jpg │ │ └── ... │ ├── val/ │ └── test/ └── labels/ ├── yolo/ │ ├── train/ │ ├── val/ │ └── test/ └── voc/ ├── train/ ├── val/ └── test/图片在images目录下按train、val、test三个子目录划分好YOLO格式的txt标签放在labels/yolo目录VOC格式的xml放在labels/voc目录。两套标注目录内部也按同样的train/val/test结构组织文件名与图像名一一对应img_0323_177.jpg对应的标签就是img_0323_177.txt和img_0323_177.xml。动手训练前我一般会强制自己先做一遍结构检查用脚本统计images和labels下的文件数量再逐一比对文件名。这一步能挡掉大部分后续训练时的报错。2.2 YOLO格式标注归一化坐标的四要素解析打开labels/yolo/train目录下任意一个txt文件看到的应该是每一行五个数字的结构0 0.4234 0.5512 0.3861 0.4928 1 0.1121 0.7380 0.2245 0.2153这五个数字依次是类别索引、目标框中心点x坐标、目标框中心点y坐标、目标框宽度、目标框高度。注意后四个值全部相对于图像宽度和高度做了归一化取值范围在0到1之间。也就是说0.4234不是像素坐标而是中心点位于图像宽度的42.34%处。这里的核心认知是txt标注文件里不存图像尺寸信息所以它依赖图像本身的宽高来还原像素框。这也解释了为什么YOLO格式的文件小而统一换分辨率训练也完全不受影响。如果你需要把归一化坐标还原成像素坐标做可视化常见做法是用下面这段脚本我已经在多个数据集上验证过def yolo_to_pixels(x_center, y_center, w, h, img_w, img_h): x1 int((x_center - w / 2) * img_w) y1 int((y_center - h / 2) * img_h) x2 int((x_center w / 2) * img_w) y2 int((y_center h / 2) * img_h) return x1, y1, x2, y2逻辑很简单x_center乘以图像宽度得到中心点的像素坐标再减去宽度的一半得到左上角x1加上宽度的一半得到右下角x2。y轴方向同理。这段代码在检查标签是否错位时非常有用把还原出来的框画到原图上一眼就能看出标注质量。2.3 VOC格式标注从xml里能找回哪些信息VOC格式的xml是另一种常见的标注载体它和YOLO txt最大的区别是坐标是绝对值且带有图像尺寸、类别名等元信息。看一个典型的标注文件annotation folderimages/folder filenameimg_0323_177.jpg/filename size width640/width height480/height depth3/depth /size object nameweed/name bndbox xmin64/xmin ymin128/ymin xmax311/xmax ymax365/ymax /bndbox /object /annotationxml里最关键的三块filename对应图像名size给出图像真实宽高object下的name是类别名、bndbox是目标框左上角和右下角的像素坐标。从xml转YOLO txt时需要把这些绝对值换算成归一化相对值还要把类别名映射成类别索引。我自己在迁移其他项目时最常用的是这个xml转txt脚本import xml.etree.ElementTree as ET def voc_to_yolo(xml_path, classes): tree ET.parse(xml_path) root tree.getroot() img_w int(root.find(size/width).text) img_h int(root.find(size/height).text) lines [] for obj in root.iter(object): cls obj.find(name).text if cls not in classes: continue idx classes.index(cls) box obj.find(bndbox) xmin float(box.find(xmin).text) ymin float(box.find(ymin).text) xmax float(box.find(xmax).text) ymax float(box.find(ymax).text) w xmax - xmin h ymax - ymin x_center xmin w / 2.0 y_center ymin h / 2.0 dw 1.0 / img_w dh 1.0 / img_h lines.append(f{idx} {x_center * dw:.6f} {y_center * dh:.6f} {w * dw:.6f} {h * dh:.6f}) return lines参数说明classes是一个按索引顺序排列的类别名列表比如[crop, weed]索引0对应crop、1对应weed。脚本先读图像尺寸再遍历所有object节点把bndbox的绝对值转换成yolo所需的归一化相对值。dw和dh是归一化分母用它们做除法而非乘法能减少浮点误差。提示txt里类别索引从0开始计数xml里类别名要跟data.yaml的names列表严格对应否则训练出来的模型类别全乱。这套数据集的聪明之处在于同时保留两套标注所以无论你习惯用VOC工具比如LabelImg还是YOLO生态的标签工具都能直接上手改数据不用重新标注。3. 用YOLOv8快速跑通data.yaml解读与训练命令3.1 data.yaml里到底配了什么YOLO系列训练的第一步不是写模型代码而是先把数据配置文件搞清楚。解压后根目录的data.yaml是这套数据集能直接开工的关键其结构大致如下path: /path/to/crop_weed train: images/train val: images/val test: images/test nc: 2 names: 0: crop 1: weed逐项看path是数据集根目录的路径train、val、test分别指向相对于根目录的图像子目录。nc是类别总数names是类别名列表索引顺序必须与txt标签里的第一个数字一致。提示path写的是绝对路径换机器后记得改成自己的实际路径。我一般建议改成相对路径写法把数据集放到项目目录下直接用path: ./crop_weed省得每次迁移都要改。这套数据集的面板数据是200张图像量不大但胜在划分齐全。三个子目录的存在意味着你不需要再手动执行train_test_split直接进入训练阶段。如果发现test目录没用到也不用慌YOLOv8默认训练时只读train和valtest留给最终评估。3.2 训练参数怎么设不翻车数据量小训练策略就要跟着调整。我的习惯是先拿YOLOv8n这个小模型跑通全流程确认数据和标签没问题再考虑换大模型或者调参。训练命令如下yolo detect train datadata.yaml modelyolov8n.pt epochs100 imgsz640 batch16 patience20各参数含义modelyolov8n.pt加载的是COCO预训练权重n代表nano是系列里体积最小、速度最快的版本在小数据集上不容易因为模型太大而过拟合epochs100是训练轮数200张图通常用不到100轮就能收敛batch16受显存限制如果显卡只有8GB显存建议降到8patience20是早停参数20轮验证指标没提升就自动停止防止白烧电费。我碰上过不少新手一上来就用yolov8x结果训200张图直接过拟合验证集的mAP一路下滑。小数据集的正确打开方式是先小后大用n或s版本验证链路再尝试m版本微调。batch size也不是越大越好小数据集用大batch会让每个epoch的梯度更新次数过少收敛反而变慢。3.3 结果怎么看mAP与混淆矩阵训练结束后YOLOv8会在runs/detect/train目录下生成weights和一系列图表。我最关心三个指标mAP50IoU阈值0.5下的平均精度、mAP50-95多个IoU阈值的平均和混淆矩阵。mAP50对杂草检测这种任务足够衡量好坏mAP50-95要求框的位置更精准。200张图训练出来的结果不能要求太高mAP50在0.6以上说明数据质量基本在线如果低于0.3大概率是标签出了问题而非模型问题。单独验证模型时我会用best.pt重新跑一次valyolo detect val modelruns/detect/train/weights/best.pt datadata.yaml这步的意义在于训练过程里的val指标是在验证集上边训练边评估的有早停的干扰单独跑一次才是干净的成绩。如果单独验证的成绩与训练时相差很大说明训练过程中出现了数据泄漏。4. 跨版本适配yolov5/v7/v9/v10/yolo11怎么通用迁移4.1 为什么一套数据集能通吃这么多版本很多人拿到数据集后的第一个疑问是data.yaml是Ultralytics的格式YOLOv5和YOLOv7能认吗答案是能因为这些版本本质上共享同一套数据组织规范YOLO txt的统一归一化坐标格式加上描述类别和路径的yaml配置文件。txt文件的五行结构在前面的章节已经讲过它是不绑死任何特定框架的中间格式。而data.yaml虽然由Ultralytics推广但v5、v7的读取逻辑基本兼容只是字段名略有差异。跨版本迁移前的检查清单我一般固定走三遍第一确认txt文件里类别索引与目标版本的类别列表顺序一致第二确认data.yaml的path写法是目标工具能识别的绝对路径或相对路径第三确认标签目录的结构符合目标版本对labels目录的默认查找规则。这三项只要有一项不对训练就会报错或静默出错。4.2 yolov5与yolov7的启动差异YOLOv5用的是独立的Git仓库和train.py入口训练命令长这样python train.py --data data.yaml --weights yolov5s.pt --img 640 --epochs 80 --batch 16注意v5训练时默认把标签放在与images平级的labels目录下具体约定是labels目录内按train/val子目录存放txt且文件名与图像名一致。而这份数据集把txt放在labels/yolo/train下所以直接传--data data.yaml可能找不到标签。常见做法是建一个软链接或调整目录结构ln -s labels/yolo/train labels/train ln -s labels/yolo/val labels/valyolov7的命令行参数与v5接近但略有区别python train.py --data data.yaml --weights yolov7.pt --img 640 --epochs 80 --batch 16v7对--data的yaml要求里没有test字段也不会报错它会自动忽略。这里提示v5和v7都要求类别索引从0开始连续编号如果数据里出现索引2而names只有两项训练会直接崩溃。4.3 v9/v10/yolo11统一命令行生态从YOLOv8之后v9、v10、yolo11都采用相同的Ultralytics命令行风格训练命令几乎一模一样只需要换模型名称yolo detect train datadata.yaml modelyolo11n.pt epochs100 imgsz640 batch16v9和v10也有各自的微调版本但用Ultralytics主线跑是最稳妥的方式。如果你想把这份数据集切回VOC格式跑老版本YOLO比如YOLOv3处理路径也不复杂先写脚本把xml转回txt再按目标版本的标签目录规则摆放即可。xml转txt的脚本在2.3节已经给出注意classes列表的顺序要手工指定不要依赖xml里的出现顺序。提示工具链再统一也不要跳过标签抽检。每次换版本我都至少随机抽5张图把标签画上去肉眼过一遍确认txt内容没有因编码或格式问题被篡改。5. 避坑指南200张图像数据集最常见的五个坑5.1 坑一类别索引对不上训练不报错但mAP全是0现象训练过程看起来正常loss在降但验证集mAP一直为0预测结果全部错位。原因txt文件里的类别索引与data.yaml的names顺序不一致。比如txt里0代表weeddata.yaml里索引0却写成了crop模型学到的东西和标签语义完全错乱。解决先把所有txt文件里的类别索引统计出来再对照xml里的name文本写个映射脚本核对。我一般会这么做解析几个xml记录每个name明文再解析对应txt确认索引和类别名一一对应无误后才进入训练。5.2 坑二train和val图像重叠验证指标虚高现象训练时val的mAP逼近0.9但换一批真实图片测试效果一下子掉到0.3典型的见光死。原因数据集划分时没有做去重某些图像同时出现在train和val里。模型相当于已经把验证集背下来了指标自然漂亮。解决用MD5哈希对图像内容去重确保train、val、test三个子目录没有任何一张图的哈希值相同。具体做法md5sum images/train/*.jpg images/val/*.jpg | sort | awk {print $1} | uniq -d如果这个命令有输出说明存在重复图像需要手动剔除并同步删除对应标签。5.3 坑三data.yaml的path写成不可移植的绝对路径现象在自己的电脑上训练正常把项目拷给别人或换服务器后报FileNotFoundError指向的还是原来的路径。原因yaml里写死了/home/xxx/crop_weed这类绝对路径换机器后路径不存在。解决把数据集目录和训练代码放在同级目录yaml里用相对路径path: ./crop_weed这样只要整个文件夹一起迁移路径就不会失效。5.4 坑四标签文件存在但内容异常现象训练日志里出现警告提示某些标签文件为空或边界框宽高为0Loss曲线剧烈震荡。原因标注工具导出时漏写了某行或者某个目标被标注成了一个点导致width或height计算出来是0。解决写一个快速巡检脚本扫描所有txt过滤掉非五列的行和宽高小于等于0的行awk -F NF ! 5 || $4 0 || $5 0 {print FILENAME: $0} labels/yolo/train/*.txt有输出就定位到具体文件手工修正或删除异常行。5.5 坑五小样本训练过拟合验证集mAP震荡现象train loss持续下降val loss先降后升mAP曲线像锯齿一样上下跳动。原因200张图像的数据容量本身就有限模型参数远超数据量时就容易把噪声也学进去。解决三件事并行——换小模型nano或small、适当增加数据增强YOLOv8默认开了mosaic和flip可以调高hsv_h和degrees、加上早停参数patience。迁移学习的批次里冻结backbone前几层也有帮助v8里可以用freeze10参数让前10层不参与训练。提示小数据集是常态不是错误。判断一份数据能不能用先跑通再谈精度先把目录、标签、类别三关过了训练就是水到渠成的事。6. 进阶验证贴标签质量检查与小样本迁移学习技巧数据集的价值取决于标签可信度所以我拿到任何带标签资源的第一件事不是训练而是抽检。把txt里的归一化坐标还原成像素框直接画到原图上这一步能暴露绝大多数标签问题。下面的脚本我每次都会跑一遍# draw_boxes.py import cv2 from pathlib import Path img_dir Path(images/train) label_dir Path(labels/yolo/train) for img_path in sorted(img_dir.glob(*.jpg))[:20]: img cv2.imread(str(img_path)) h, w img.shape[:2] txt_path label_dir / (img_path.stem .txt) if not txt_path.exists(): print(fmissing label: {img_path.name}) continue with open(txt_path) as f: for line in f: parts line.split() if len(parts) ! 5: continue _, x_c, y_c, bw, bh parts x_c, y_c, bw, bh map(float, (x_c, y_c, bw, bh)) x1 int((x_c - bw / 2) * w) y1 int((y_c - bh / 2) * h) x2 int((x_c bw / 2) * w) y2 int((y_c bh / 2) * h) cv2.rectangle(img, (x1, y1), (x2, y2), (0, 255, 0), 2) cv2.putText(img, str(parts[0]), (x1, y1 - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 1) out_path str(img_path).replace(.jpg, _check.jpg) cv2.imwrite(out_path, img) print(fdone: {out_path})这个脚本的逻辑是读取每张图把同名txt里的归一化框转为像素框用OpenCV画矩形的同时把类别索引标在框左上角。跑完后逐个翻看生成的_check.jpg重点看两处——框是否完整包住目标类别索引是否和目标的实际种类相符。框偏了或者类别标错几乎都能在这一步被逮住。小样本迁移学习的进阶技巧更偏向训练策略。我的习惯是先用预训练权重跑一轮短训练50轮以内摸清数据底细然后做一个冷启动对照freeze10冻结backbone重新训练与小数据集常见的全量微调对比。冻结backbone能显著降低过拟合概率特别适合200张这种量级代价是收敛速度稍慢需要适当增大学习率。配合早停和cosine学习率调度一般能在不换模型的前提下把mAP往上拉几个点。检查完标签、跑完对照实验后这套数据集才算真正吃透。从那以后我每次拿到新的标注数据都强制先跑一遍画框脚本再做训练不再跳过抽检这个环节。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑