news 2026/9/11 20:03:20

16类农作物目标检测数据集与YOLOv8迁移学习实践

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
16类农作物目标检测数据集与YOLOv8迁移学习实践

简介:面向农业智能化监测与精准农业管理的YOLO格式农作物检测数据集,覆盖香蕉、豆类、茄子、辣椒、黄瓜、玉米、水稻、小麦等16类主要经济作物,适合农田巡检机器人、智能除草设备及作物分布分析等视觉模块开发。压缩包共2000个文件,以1041个txt标注文件与957张jpg图像为主体,另含1个yaml配置文件与1个docx说明文档,整体大小约73.86MB,解压后即可按YOLO标准流程使用。txt文件提供标准化边界框与类别标签,jpg图像覆盖复杂农田场景中的重叠与遮挡情况,yaml便于快速接入YOLOv5/v7/v8等框架训练,docx则对数据构成与类别分布进行说明。数据特别包含豆类与豌豆、不同茄科作物等易混淆样本,有助于提升模型在真实农业场景中的区分精度。目前已有106人学习下载,适合农业院校科研、农机装备研发以及AI+农业交叉学科实践。

1. 这份农作物目标检测数据集,能解决什么实际问题

农业视觉模型落地时,最缺的不是算法,而是带标准标注的现场数据。很多团队拿到农田巡检需求后,第一件事就是自己采集几万张图片、连夜标注,结果边界框画得参差不齐,类别定义各说各话,训练出来的模型换块地就失效。这份农作物多类别目标检测数据集提供了 726 张训练图、212 张验证图、103 张测试图,覆盖香蕉、豆类、茄子、辣椒、黄瓜、大蒜、生姜、玉米、洋葱、豌豆、菠萝、马铃薯、水稻、高粱、番茄、小麦共 16 类主要农作物,并且全部使用 YOLO 格式标注,即每个图片同名 txt 文件里存归一化后的中心点坐标和宽高。它解决的核心问题是:让你跳过最耗时的“从零采集标注”阶段,直接进入模型验证和迁移学习,特别适合做农田巡检机器人视觉模块、智能除草设备感知单元,以及农业院校的 AI+ 交叉学科实验。

2. YOLO 标注格式与目录结构:先看懂数据再动手改

拿到农作物多类别目标检测数据集.zip后,解压出的是一堆以chilli_8_jpg.rf.71b9cb5407d240f706c0e72e817a39fb.jpg和同名.txt配对的图片标注文件,文件名里的.rf.是 Roboflow 导出的命名痕迹,不影响使用。这类数据集通常保留了 Roboflow 的拆分结构,也可能已经按train/val/test分好目录。无论哪种,第一步永远是确认文件组织方式和标注内容是否正确。

2.1 目录结构确认与标准转换

常见做法是先把目录整理成 YOLO 训练的标准形态,便于直接喂给框架。我一般会先用find命令扫一眼实际层级:

# 查看解压后的目录树前两层 find . -maxdepth 2 -type d | sort # 统计每个图片是否有同名标注文件 for img in $(find . -name "*.jpg"); do txt="${img%.jpg}.txt" if [ ! -f "$txt" ]; then echo "missing: $img"; fi done

第一行命令确认train/valid/testtrain/val/test的目录名到底是什么,以及类别配置文件是否存在。第二行检查图片和标注是否一一对应,缺失标注的图片会导致训练时报错或该样本被静默跳过。如果发现只有valid没有val,可以用mv valid val统一命名,避免在 YAML 配置里写错路径。

2.2 标签文件数值含义与可视化验证

YOLO 标注文件的每一行代表一个目标,格式为class x_center y_center width height,五个数值全部归一化到 0~1 之间。比如potato_50_jpg.rf.f8be569fdccf89a48956827ed931a8a1.txt中某一行是11 0.512 0.348 0.126 0.095,含义是类别 id 为 11(对应classes.txt里的名称),目标的中心点位于图片宽度的 51.2%、高度的 34.8% 处,宽高分别占整张图的 12.6% 和 9.5%。这个数值必须与图片尺寸解耦,换分辨率时不需要重新标注。

拿到数据后不要直接训练,先用 OpenCV 把标注框画回去,目测标注质量。这里给出一段快速可视化脚本:

import cv2 img_path = "potato_50_jpg.rf.f8be569fdccf89a48956827ed931a8a1.jpg" txt_path = img_path.replace(".jpg", ".txt") img = cv2.imread(img_path) h, w = img.shape[:2] with open(txt_path) as f: for line in f: cls, xc, yc, bw, bh = map(float, line.split()) x1 = int((xc - bw / 2) * w) y1 = int((yc - bh / 2) * h) x2 = int((xc + bw / 2) * w) y2 = int((yc + bh / 2) * h) cv2.rectangle(img, (x1, y1), (x2, y2), (0, 255, 0), 2) cv2.putText(img, str(int(cls)), (x1, y1 - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 0, 255), 2) cv2.imwrite("check.jpg", img)

这段脚本的关键是还原坐标:归一化中心点减半宽度,乘以图片宽高得到左上角,再加上宽度得到右下角。类别 id 默认按classes.txt里的行序排列。如果画出来的框偏离目标、框住了背景,说明该图片标注有误,需要删除或修正,否则会直接污染模型。

2.3 类别映射与类别不平衡初判

解压目录里通常带有classes.txtdata.yaml。如果只有图片和 txt,需要自己从所有标注文件中提取类别 id 生成名称映射。16 类的顺序固定后,训练时的类别数量必须是 16,否则 Loss 中cls部分会维度不匹配。这里贴一个快速统计各类别样本数量的命令:

cat */*/*.txt | awk '{print $1}' | sort | uniq -c | sort -k2 -n

awk取每行第一个字段即类别 id,uniq -c统计每个 id 出现的频次。注意这里是目标框数量,不是图片数量。如果某个类只有几十个框,训练时容易欠拟合,需要后续做针对性增强或使用类别权重。

3. 训练集/验证集/测试集划分与类别分布分析:用脚本代替肉眼

数据拆分直接决定评估指标的可信度。该数据集给出的 726/212/103 大约符合 7:2:1,验证集占 20.4%,测试集占 9.9%,属于合理范围。但每个类别在三个集合中的分布是否一致,才是模型是否过拟合到特定场景的关键。直接看一组统计表更直观。

3.1 统计每个类别在 train/val/test 中的目标数量

写一个 Python 脚本,遍历三个目录下的所有 txt 文件,统计每个类别在每个集合中的框数,并输出表格:

import os from collections import defaultdict splits = ['train', 'val', 'test'] class_names = ["banana", "beans", "eggplant", "chilli", "cucumber", "garlic", "ginger", "corn", "onion", "pea", "pineapple", "potato", "rice", "sorghum", "tomato", "wheat"] data = {sp: defaultdict(int) for sp in splits} for sp in splits: for root, _, files in os.walk(sp): for fn in files: if fn.endswith('.txt'): with open(os.path.join(root, fn)) as f: for line in f: cls = int(line.split()[0]) data[sp][cls] += 1 for cls in range(len(class_names)): c = class_names[cls] cnts = [data[sp].get(cls, 0) for sp in splits] total = sum(cnts) print(f"{c:10s} total={total:5d} fat={total==0 or total < all(cnts):>}")

最后一行不是必须的,实际输出时可以把 train/val/test 的框数和总数列齐,再计算每个类在验证集中的占比与训练集占比是否接近。如果某一类在 val 中数量为 0,说明该类样本全在训练集里,评估时这一类永远测不到,必须手动调整。

3.2 用饼图检查类别不均衡

16 类中,辣椒(chilli)和马铃薯(potato)的样本数量明显多,而小麦(wheat)或豌豆(pea)可能很少。绘制各集合的类别分布柱状图,能快速看出长尾情况:

import matplotlib.pyplot as plt import numpy as np counts = [data['train'].get(i, 0) for i in range(16)] plt.figure(figsize=(10, 4)) plt.bar(class_names, counts) plt.xticks(rotation=45) plt.ylabel("bbox count") plt.title("Train set category distribution") plt.tight_layout() plt.savefig("dist.png")

如果柱形图出现明显的“断崖”,说明某个类参与训练的概率很低。这种情况下,不能只依赖随机抽样,应该在训练参数中给少样本类别更高的损失权重。YOLOv8 的model.train()支持传入class_weights,不过实际更通用的做法是在数据增强时对少样本类所在的图片做离线复制或马赛克增强。该数据集里番茄和辣椒同属茄科,外观相似,统计时尤其要注意两者在同一个框内的重叠情况,后续模型的混淆矩阵大概率出错在这两类上。

3.3 拆分比例合理性验证

用余弦相似度或简单的 KL 散度验证三个集合的类别分布一致性,我是这么做的:将每个集合的各类别框数归一化为概率分布,然后计算 train 与 val 的散度值:

def normalize(cnts): arr = np.array([cnts.get(i, 0) for i in range(16)], dtype=float) return arr / arr.sum() p_train = normalize(data['train']) p_val = normalize(data['val']) eps = 1e-10 kl = np.sum(p_train * np.log((p_train + eps) / (p_val + eps))) print(f"KL(train||val) = {kl:.3f}")

KL 值小于 0.1 可以认为分布基本一致。如果超过 0.3,说明某个类在拆分时被人为集中放到了训练集或验证集,模型评估会失真。该数据集的来源是 Roboflow 自动拆分,通常分布均匀,但仍建议在训练前跑一遍,避免自己重新划分时出错。

4. 基于 YOLOv8 的迁移学习训练与参数调优:让 726 张图发挥出最大价值

只有 726 张训练图,如果从头训练一个深层网络,几乎必然过拟合。正确做法是使用 COCO 预训练权重做迁移学习,冻结主干的前几层,只训练检测头和最后几层。YOLOv5、v7、v8 都支持这种方式,这里以 YOLOv8 为例,因为它的train命令参数更直观,且对自定义数据集支持最省事。

4.1 准备 data.yaml 与目录映射

先建一个cropland.yaml,注意路径写绝对路径或相对路径均可,关键是train/val/test指向的目录下必须直接是图片和 txt:

path: /home/user/crop_dataset train: train val: val test: test nc: 16 names: 0: banana 1: beans 2: eggplant 3: chilli 4: cucumber 5: garlic 6: ginger 7: corn 8: onion 9: pea 10: pineapple 11: potato 12: rice 13: sorghum 14: tomato 15: wheat

nc必须与names的键值数量一致,否则训练会直接报错。names的顺序是类别 id 的唯一依据,训练时如果某个 txt 中的类别 id 超出 15,说明标注文件有问题,需要返回第 2 章的可视化脚本排查。

4.2 训练命令与超参数拆解

执行迁移学习训练:

yolo detect train \ data=cropland.yaml \ model=yolov8n.pt \ epochs=100 \ imgsz=640 \ batch=16 \ lr0=0.01 \ freeze=10 \ workers=4 \ seed=42

参数不是写完就完事,需要知道每个值的理由。model=yolov8n.pt是轻量版 n 模型,参数量约 3.2M,对于 16 类小规模数据足够,且不易过拟合;如果换成yolov8s.pt,精度会略高但训练时间更长,数据量不足时反而可能掉点。freeze=10表示冻结主干前 10 层的参数,让梯度只更新颈部网络和检测头,这是小数据集上防止破坏预训练特征最直接的手段。imgsz=640是 YOLOv8 默认分辨率,原始图片如果是 416x416,建议先统一到 640,像素不足时框架会自动补齐,但补出来的边缘可能是纯色,影响小目标识别。

4.3 训练过程中的关键监控指标

训练时不要只看总的loss,要分开看box_losscls_lossdfl_loss。因为类别不均衡时,cls_loss会被多数类主导,某个少数类即使完全没学会,总 loss 也可能在下降。YOLOv8 训练日志会每秒输出box_losscls_lossdfl_loss,同时每轮评估后打印mAP50mAP50-95。当mAP50在验证集上达到 0.9 以上时,说明边界框定位已相当准;如果mAP50高但mAP50-95特别低,说明框的定位精度不够细,需要调高imgsz或增加iou阈值下的优化。

我习惯在训练到 30 轮时暂停一次,用验证集做一次早停观察:如果训练 loss 还在降而验证 mAP 开始波动,就是过拟合信号,需要加大weight_decay到 0.0005,或者把cos_lr=True打开让学习率余弦衰减。对于小数据集,epochs=100通常在第 60~80 轮就已经收敛,太多反而浪费时间。

4.4 与 YOLOv5 的差异点

如果使用 YOLOv5,训练命令类似,但需要注意标注目录中不能出现中文路径,YOLOv5 的utils/datasets.py对路径编码处理不统一,中文会直接报错。另外 YOLOv5 的freeze参数接收的是层索引列表,比如freeze=[0,1,2,3,4,5,6,7,8,9],写起来比 YOLOv8 麻烦。从该数据集的命名来看,它来自 Roboflow 导出,YOLOv5 格式和 YOLOv8 完全兼容,直接换用yolov5s.pt也未尝不可,但 YOLOv8 的 Anchor-Free 头对小目标更友好,推荐优先使用 v8。

5. 难分样本、数据增强与结果验证:把辣椒和番茄分清

最后一章集中处理这类作物数据最容易翻车的地方:类间相似度高和背景干扰。

5.1 难样本分析与类别混淆矩阵

训练完成后,使用最佳权重runs/detect/train/weights/best.pt对测试集推理,生成混淆矩阵查看哪些类别互相污染:

yolo detect val \ model=runs/detect/train/weights/best.pt \ data=cropland.yaml \ split=test \ plots=True

plots=True会输出confusion_matrix.png,重点关注番茄、茄子、辣椒这三类之间的误检。这三个都是茄科植物,叶片和果实形状在早期生长阶段高度相似。如果混淆矩阵显示番茄被大量识别成辣椒,需要回到数据层面做两个操作:一是检查标注框中是否有“一个框包含多棵植物”的情况,YOLO 对小目标密集场景经常框到中间;二是对这两类单独做裁剪增强,把图片中番茄的区域随机放大 1.2~1.5 倍作为额外样本,迫使模型学习叶型差异。我一般会用 Python 写一个离线增强脚本,对某些特定类别图片执行随机 HSV 变换,增加亮度、饱和度扰动,让模型不过度依赖颜色。

5.2 测试集结果的人工验证方法

mAP 指标只看整体,无法感知“模型在新地里的鲁棒性”。建议手动抽取测试集中每类 5 张图片,共 80 张,用predict跑出结果缩略图:

yolo predict \ model=runs/detect/train/weights/best.pt \ source=test_images_sample \ save_txt=True \ save_conf=True \ conf=0.25

conf=0.25是经验值,如果检测框很少,说明阈值过高;如果框很多但重叠严重,说明 NMS 阈值需要调整。save_conf=True会在 txt 中记录每个框的置信度,便于后续用脚本统计低置信度的误报集中在哪一类。对于这个数据集,背景中常见的泥土、杂草容易造成误检,可以额外增加agnostic_nms=True减少不同类别间的框抑制冲突,类别数多时非常有用。

5.3 快速验证训练是否真正学到了作物特征

一个反直觉但有效的测试:把一张完全不包含农作物的图片(比如空草地)丢给模型推理,如果模型输出大量低置信度预测框,说明模型学到了背景纹理而不是作物本身。这时候要检查训练集中的负样本是否存在——YOLO 格式本身不支持纯背景标签,但可以在训练集中加入若干“无目标”图片,对应的 txt 为空文件。本数据集没有包含背景图,因此推理时调高conf到 0.35~0.4 能有效过滤误检。另外,摄像头实拍时现场光照与训练图差异大,建议在部署前用测试集之外的自采图片做一次 domain shift 测试,若 mAP 掉幅超过 20%,需要对现场图片做预处理,比如白平衡归一化后再送进模型,这一步比调超参更贴近真实农业场景。

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/11 19:58:16

深度学习模型复现:随机种子与确定性计算实践

1. 随机种子与模型复现的世纪难题 第一次跑模型准确率90%&#xff0c;第二次跑变成85%&#xff0c;第三次又变成92%——这种让人抓狂的经历&#xff0c;相信每个深度学习从业者都遇到过。上周隔壁组的小王就因为论文实验结果无法复现&#xff0c;被导师要求重做了整整三周实验。…

作者头像 李华
网站建设 2026/9/11 19:55:32

基于Python与OpenCV的人脸识别景区票务系统设计

简介&#xff1a;基于人脸识别的景区票务系统毕业设计源码&#xff0c;面向需要完成Python课程设计或毕业设计的在校学生&#xff0c;也适合希望学习DjangoMySQL开发流程的初级开发者。系统采用前台后台双模式设计&#xff0c;前台支持用户注册、公告须知、票务查看与在线购票&…

作者头像 李华
网站建设 2026/9/11 19:53:55

深入理解人工智能 chatGPT的软件架构

ChatGPT是一个复杂的系统&#xff0c;其软件架构可以清晰地划分为几个核心的功能模块&#xff0c;它们协同工作以提供流畅、智能的对话体验。这些模块的交互流程&#xff0c;可以理解为用户请求从进入到响应返回所经过的一条“流水线”。&#x1f9e9; 核心软件模块与功能1. 客…

作者头像 李华
网站建设 2026/9/11 19:50:32

LangChain+ChatGLM-6B本地知识库问答实战:从RAG构建到调优

简介&#xff1a;面向计算机、通信、人工智能、自动化等相关专业学生及从业者的一套完整毕业设计项目&#xff0c;基于LangChain和ChatGLM-6B等主流LLM&#xff0c;解决针对本地知识库的自动问答问题。该项目为个人毕业设计&#xff0c;代码经调试测试确保可运行&#xff0c;作…

作者头像 李华
网站建设 2026/9/11 19:47:33

车载逆变储能电源控制板设计:从拓扑选型到调试实战

车载逆变储能电源这两年热度一直不低&#xff0c;房车、露营、户外作业、应急救援都在用。但说句实话&#xff0c;我在帮朋友和客户调试这类项目时见得最多的&#xff0c;不是方案选型多困难&#xff0c;而是控制板设计阶段埋下的雷。很多人照着网上现成原理图打样&#xff0c;…

作者头像 李华
网站建设 2026/9/11 19:47:13

GitLab迁移实战:从CentOS到Docker Compose的数据零丢失指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华