ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

航拍农业安防数据集实战:6类目标检测与YOLOv12训练调优

航拍农业安防数据集实战:6类目标检测与YOLOv12训练调优 简介这份航拍农业区域野生动物及安防多目标检测数据集面向智慧农业、生态监测与园区安防方向的计算机视觉开发者与算法工程师提供可直接用于YOLO系列目标检测训练的标注样本。数据覆盖野猪、鸟类、猴子、蛇类四类野生动物及入侵者、业主两类人员共6个类别训练集1812张、验证集137张、测试集69张均为俯视或斜视航拍视角涵盖不同光照下的农田与林区交界场景可支撑野生动物入侵预警、人员异常活动识别与业主身份验证等多任务学习。资源包共2000个文件以1998个YOLO格式txt标注文件为主另含1个yaml数据配置与1份docx说明文档压缩包约127.32MB标注框精准覆盖目标主体便于快速接入YOLOv5、YOLOv8等主流框架。目前已有73人学习下载适合用于轻量化模型训练与无人机端侧AI部署也可转换为分类数据集开展物种识别等衍生任务。1. 航拍农业安防数据集6 类目标、2018 张图能不能直接喂给 YOLOv12去年帮一个做果园巡检的团队调模型他们卡在一个很实际的问题上无人机拍回来的画面里野猪、猴子、蛇、鸟、陌生人、农场主全混在一起用公开的 COCO 或 VisDrone 训出来的检测器要么把猴子认成狗要么把蹲着干活的业主当成入侵者报警。这类农业场景 航拍视角 人兽混检的需求通用数据集基本接不住因为类别定义和拍摄角度都对不上。这份航拍农业区域野生动物及安防多目标检测数据集就是冲着这个缺口来的2018 张航拍图训练 1812 / 验证 137 / 测试 696 个类别YOLO 格式边界框标注覆盖野猪、鸟类、猴子、蛇、入侵者、业主。它适合做智慧农业监控、生态多样性监测、园区安防预警以及无人机端侧轻量化部署的从业者。下面我按这份数据长什么样 → 怎么接进 YOLOv12 训练 → 哪里会翻车的顺序拆一遍能抄的步骤我都落成代码。2. 数据集结构与 YOLO 标注格式先看清 6 类目标怎么落盘拿到一个目标检测数据集我第一件事不是急着训练而是把目录结构和标注文件翻一遍。因为标注格式的细节——类别索引从 0 还是 1 开始、坐标是归一化还是像素、有没有空标注文件——决定了你后面要不要写转换脚本。这份数据是标准 YOLO 格式理解它的组织方式是后面所有操作的前提。2.1 目录组织与类别映射从项目正文的文件清单能看出标注文件是.txt结尾命名规则是类别名-序号-原始文件名哈希比如kera-97-_jpeg.rf.ef5c00ec...txt、ular_sawah-17-_jpeg.rf.17c55f1c...txt。这种命名说明数据在导出时保留了类别前缀方便人工核对但训练时真正起作用的是 txt 文件里的类别索引不是文件名。常见的 YOLO 目录长这样dataset/ ├── images/ │ ├── train/ # 1812 张 │ ├── val/ # 137 张 │ └── test/ # 69 张 ├── labels/ │ ├── train/ │ ├── val/ │ └── test/ └── data.yamlimages和labels必须一一对应同名不同后缀。如果解压后发现图片和标签混在一个目录里先按上面结构拆开否则 YOLO 训练时找不到标签会直接报No labels found。类别映射要自己定按摘要给的 6 类我一般写成# data.yaml path: ./dataset train: images/train val: images/val test: images/test nc: 6 names: 0: babi_hutan # 野猪 1: burung # 鸟类 2: kera # 猴子 3: ular_sawah # 蛇类 4: maling # 入侵者 5: owner # 业主这里有个关键点names的顺序必须和标注 txt 里的类别索引严格对应。如果原始标注里kera是索引 2你这里写成 1训练出来的模型会把猴子的预测框标成鸟而且 loss 还能正常下降——这种错误不会报错只会让你在推理时一脸懵。所以拿到数据后务必抽几个 txt 文件确认索引。2.2 标注文件内容解析与校验YOLO 标注每行是class_id x_center y_center width height后四个都是相对图片宽高的归一化值0~1。抽一个文件看看# 查看某个标注文件内容 cat labels/train/kera-97-_jpeg.rf.ef5c00ec5faa18cad3164c29dc43bde6.txt # 输出示例 # 2 0.512 0.437 0.086 0.121 # 2 0.623 0.501 0.074 0.098第一列2就是类别索引后面是归一化坐标。写个脚本批量校验能提前发现脏数据import os from pathlib import Path def check_labels(label_dir, img_dir, nc6): issues [] for txt in Path(label_dir).glob(*.txt): img_name txt.stem .jpg img_path Path(img_dir) / img_name # 1. 图片是否存在 if not img_path.exists(): issues.append(f缺图: {txt.name}) continue # 2. 逐行检查坐标范围 with open(txt) as f: for i, line in enumerate(f): parts line.strip().split() if len(parts) ! 5: issues.append(f{txt.name} 第{i}行字段数不对: {line}) continue cid int(parts[0]) coords list(map(float, parts[1:])) if cid 0 or cid nc: issues.append(f{txt.name} 类别越界: {cid}) if any(c 0 or c 1 for c in coords): issues.append(f{txt.name} 坐标越界: {coords}) return issues issues check_labels(dataset/labels/train, dataset/images/train) print(f发现 {len(issues)} 个问题) for x in issues[:10]: print(x)这段脚本做三件事核对图片与标签是否配对、检查每行是否 5 个字段、验证类别索引和归一化坐标是否在合法范围。参数nc6要和data.yaml里的nc保持一致。跑完如果问题数为 0说明数据基本干净如果有大量缺图多半是图片扩展名不统一.jpg和.jpeg混用改一下img_name的拼接逻辑即可。提示航拍数据里小目标多蛇和鸟的框可能只有十几个像素。校验时顺便统计一下框的宽高分布如果大量框小于 0.01即图片宽高的 1%训练时要调小 anchor 或提高输入分辨率否则这些小目标会被直接忽略。3. 用 YOLOv12 训练这份数据从环境到收敛的完整链路数据看清楚了接下来是把它喂进模型。这份数据标注是 YOLO 格式理论上 YOLOv5/v8/v12 都能直接吃但不同版本对数据加载、增强策略、显存占用差别不小。我选 YOLOv12 来演示因为它在小目标和密集场景上的注意力机制对航拍图更友好而且这份数据里动物群体聚集的场景正好吃这一套。下面从环境装起到训练、验证、导出一步步来。3.1 环境准备与依赖安装先确认显卡和 CUDA 版本再装框架。我一般用 conda 隔离环境避免和系统里的 torch 打架# 创建环境 conda create -n agri_yolo python3.10 -y conda activate agri_yolo # 安装 PyTorch按你的 CUDA 版本选这里以 cu121 为例 pip install torch torchvision --index-url https://download.pytorch.org/whl/cu121 # 安装 ultralyticsYOLOv12 已并入该框架 pip install ultralytics # 验证 python -c import torch; print(torch.cuda.is_available())最后一行输出True才算 GPU 可用。如果输出False先别急着训练检查驱动和 CUDA 版本是否匹配——用 CPU 训这份 2000 张的数据一个 epoch 可能要十几分钟纯属浪费时间。装完把数据集按第 2 章的目录结构放好data.yaml里的path改成你的实际路径。3.2 训练命令与关键参数YOLOv12 的训练入口很简洁但参数怎么设直接决定收敛质量。我常用的起手命令yolo detect train \ modelyolov12n.pt \ datadataset/data.yaml \ epochs150 \ imgsz640 \ batch16 \ patience30 \ lr00.01 \ lrf0.01 \ mosaic1.0 \ close_mosaic15 \ device0 \ projectruns/agri \ nameexp1逐个说清楚这些参数为什么这么设modelyolov12n.ptn 是 nano 版参数量小适合无人机端侧部署。如果你追求精度且显存够可以换yolov12s.pt或m。imgsz640航拍图里蛇、鸟偏小640 是精度和速度的平衡点。显存允许的话上 960小目标召回会明显提升。batch168G 显存大概能跑 1612G 以上可以上 32。显存爆了就往下调别硬撑。patience3030 个 epoch 验证指标不涨就早停省时间。lr00.01/lrf0.01初始学习率和最终学习率比例这是官方默认值小数据集别乱调大容易震荡。mosaic1.0马赛克增强对多目标密集场景很有效但会破坏小目标的完整性。close_mosaic15最后 15 个 epoch 关掉 mosaic让模型在真实分布上收尾这一步对最终精度影响很大别省。训练启动后终端会打印每个 epoch 的 box_loss、cls_loss、mAP50、mAP50-95。重点盯mAP50-95它比 mAP50 更严格。如果前 20 个 epoch loss 不降反升八成是学习率太大或标注有问题回去查第 2 章的校验脚本。3.3 训练过程监控与结果解读训练不是启动了就完事得会看曲线。ultralytics 会在runs/agri/exp1/下生成results.csv和一堆可视化图。我习惯用脚本把关键指标拉出来看趋势import pandas as pd df pd.read_csv(runs/agri/exp1/results.csv) df.columns df.columns.str.strip() # 列名可能带空格 # 看最后 10 个 epoch 的指标 cols [epoch, train/box_loss, train/cls_loss, metrics/mAP50(B), metrics/mAP50-95(B)] print(df[cols].tail(10).to_string(indexFalse)) # 找最佳 epoch best df.loc[df[metrics/mAP50-95(B)].idxmax()] print(f\n最佳 epoch: {int(best[epoch])}, mAP50-95: {best[metrics/mAP50-95(B)]:.4f})这段代码读训练日志打印最后 10 轮的 loss 和 mAP并定位最佳 epoch。判断标准box_loss和cls_loss应该整体下降并趋于平稳mAP50-95稳步上升。如果cls_loss一直很高说明类别区分度不够——这份数据里入侵者和业主都是人形模型容易混可以考虑加类别权重或补充难例。训练完在验证集上跑一次评估yolo detect val \ modelruns/agri/exp1/weights/best.pt \ datadataset/data.yaml \ imgsz640 \ batch16输出会给出每个类别的 precision、recall、mAP。重点看maling入侵者和owner业主这两类的混淆情况如果 recall 明显低于其他类说明这两类样本可能不均衡或特征太像需要针对性补数据。3.4 推理与导出部署训练完的模型要落到实际场景先做单图推理验证效果yolo detect predict \ modelruns/agri/exp1/weights/best.pt \ sourcedataset/images/test \ imgsz640 \ conf0.25 \ saveTrue \ projectruns/agri/predictconf0.25是置信度阈值航拍安防场景我一般调到 0.3~0.4宁可漏检也别误报——把业主认成入侵者触发警报比漏掉一只鸟的代价大得多。推理结果图会存到runs/agri/predict/肉眼过一遍重点看小目标和密集聚集场景有没有漏框。如果要部署到无人机端侧导出成 ONNX 或 TensorRT# 导出 ONNX yolo export modelruns/agri/exp1/weights/best.pt formatonnx imgsz640 # 导出 TensorRT需要 GPU 和 tensorrt 环境 yolo export modelruns/agri/exp1/weights/best.pt formatengine imgsz640 halfTruehalfTrue是 FP16 量化能显著提速但精度会掉一点点。端侧设备算力紧张时值得服务器部署就保持 FP32。4. 避坑与排查这份数据训练时最容易翻车的 5 个点上面流程走通不代表一帆风顺。我在类似航拍农业数据上踩过的坑集中列出来每条按现象 → 原因 → 解决写你对照排查能省不少时间。现象一训练启动就报No labels found in ...。原因图片和标签目录没对应上或者标签文件扩展名不是.txt又或者data.yaml里的train路径写成了绝对路径但实际是相对路径。 解决确认images/train和labels/train下文件名除扩展名外完全一致data.yaml里用相对路径且path指向数据集根目录。跑第 2 章的校验脚本缺图问题会直接暴露。现象二mAP 一直卡在 0.1 以下loss 不降。原因类别索引错位。原始标注里babi_hutan可能是 0但你data.yaml里写成了别的顺序模型学的是错的映射。 解决抽 5~10 个不同类别前缀的 txt 文件看第一列的数字和data.yaml的names逐一核对。这个错误最隐蔽因为训练不报错只是学不会。现象三小目标蛇、鸟几乎检不出来。原因imgsz640下原本就十几像素的目标被缩得更小特征在深层网络里丢失。 解决把imgsz提到 960 或 1280或者在data.yaml同级加anchors自定义针对小目标调小 anchor 尺寸再不行就切图训练把大图裁成小块但要注意边界框的裁剪转换。现象四验证集 mAP 很高实际推理一堆误报。原因验证集和测试集分布太接近模型过拟合了验证集或者conf阈值设太低。 解决用测试集69 张单独评估别只看验证集推理时把conf提到 0.35 以上检查训练时close_mosaic是否生效没关 mosaic 的模型在真实图上容易出鬼影框。现象五显存溢出CUDA out of memory。原因batch或imgsz太大或者没开混合精度。 解决先把batch减半还不行就降imgsz加ampTrue默认开用混合精度训练前torch.cuda.empty_cache()清一下缓存。别用batch1硬跑BN 层会不稳定。注意这份数据训练集 1812 张、验证集只有 137 张验证集偏小单次评估的 mAP 波动会比较大。建议用 K 折或者多次不同随机种子训练看指标稳定性别被一次的高分骗了。5. 从检测到业务类别阈值调优与端侧部署的一个实用技巧模型训出来只是半成品真正落地时入侵者和业主的误判率才是决定这套系统能不能用的关键。我分享一个在农业安防项目里验证过的做法按类别分别设置信度阈值而不是全局一个conf。YOLO 默认推理时所有类别共用一个conf但这份数据的 6 类目标业务代价完全不同。漏检一只鸟生态监测少一条记录误报一个业主为入侵者可能触发不必要的警报甚至纠纷。所以我在部署时会写一层后处理对maling和owner用更高的阈值对动物类用较低阈值from ultralytics import YOLO import numpy as np model YOLO(runs/agri/exp1/weights/best.pt) # 按类别设阈值索引对应 data.yaml 的 names class_conf { 0: 0.25, # babi_hutan 野猪中等 1: 0.20, # burung 鸟类小目标放宽 2: 0.25, # kera 猴子 3: 0.20, # ular_sawah 蛇小目标放宽 4: 0.45, # maling 入侵者从严避免误报 5: 0.45, # owner 业主从严 } results model.predict(test.jpg, conf0.15, imgsz640)[0] kept [] for box in results.boxes: cid int(box.cls) conf float(box.conf) if conf class_conf.get(cid, 0.25): kept.append((cid, conf, box.xyxy.tolist())) for cid, conf, xyxy in kept: print(f类别 {model.names[cid]} 置信度 {conf:.3f} 框 {xyxy})这段代码先用一个较低的全局conf0.15让模型尽量多输出候选框再按类别阈值二次过滤。class_conf字典里的值要根据你的实际业务调安防场景把maling和owner调高生态监测把动物类调低。参数调整的依据是拿一批真实航拍图跑一遍统计每类的误报和漏报画个 PR 曲线找平衡点。端侧部署还有个细节无人机图传分辨率往往高于 640直接缩放会丢小目标。我的习惯是推理前把原图切成带重叠的瓦片每片单独推理再合并框重叠区域用 NMS 去重。这样蛇和鸟的召回能提升一截代价是推理耗时增加需要根据端侧算力权衡瓦片大小和重叠比例。从那以后我每次拿到新的行业数据集都强制先跑一遍标注校验脚本、再抽 20 张图肉眼核对类别索引最后才启动训练——这三步花不了半小时但能挡掉后面几天的返工。希望这份拆解帮到你少走点我当年走过的弯路。本文还有配套的精品资源点击获取
返回列表