资讯详情

资讯详情

森林害虫目标检测数据集实战:YOLOv8训练与避坑指南

简介这份森林害虫目标检测数据集面向林业智能监测、农业AI应用开发及生态科研人员聚焦松毛虫、松墨天牛、卷叶蛾三类常见且危害严重的森林害虫识别难题。数据集共1715张实际场景采集的JPEG图片按训练集1199张、验证集257张、测试集259张划分全部采用YOLO格式标注边界框与类别标签可直接接入YOLO、Faster R-CNN等主流检测框架用于虫害预警、无人机巡护与精准施药等任务。资源包共2000个文件以1715个txt标注文件、283张jpg图像为主另含1个yaml配置文件与1份docx说明文档压缩包约189.26MB目录结构清晰便于按类别与划分快速检索。目前已有303人学习下载。三类害虫形态差异明显标注定位准确能有效提升模型在复杂林区环境中的泛化能力适合林业院校教学实训、昆虫行为研究及高水平论文实验使用。1. 森林害虫目标检测数据集1715 张实拍图能撑起一个林业 AI 项目吗林业场景的目标检测和城市道路那套完全不是一回事。树冠遮挡、虫体尺度小、背景纹理高度重复随便拿 COCO 预训练权重直接推理松毛虫和松墨天牛大概率被当成同一团褐色噪点。这份森林害虫目标检测数据集的价值就在这儿1715 张实际场景采集的 JPEG 图片训练集 1199 张、验证集 257 张、测试集 259 张YOLO 格式标注覆盖松毛虫、松墨天牛、卷叶蛾三个类别。它不是玩具数据集三个类别都是林业上真正会造成大面积松林死亡的害虫其中松墨天牛还是松材线虫的主要传播媒介。适合谁用做农业林业智能监测的算法工程师、想发昆虫学或生态方向论文的研究生、以及要给无人机或地面监控设备加虫害识别模块的开发者。下面按「拿到手怎么跑通 → 参数怎么调 → 哪里会翻车」的顺序拆一遍。2. 从压缩包到可训练目录YOLO 格式解析与数据校验2.1 文件名里的哈希和标签编码说明了什么先看项目正文里列出的文件名比如9_0_jpg.rf.02488166257d9f7cc9a279d5e73a6393.jpg、147_1_jpg.rf.42944e13c01c4b8177519c59ffcfa629.jpg。这种命名是 Roboflow 导出时的典型格式{原始编号}_{类别索引}_jpg.rf.{哈希}.jpg。下划线后那个数字就是类别索引_0_对应第 0 类_1_对应第 1 类。这意味着你光看文件名就能大致判断类别分布不用先解析标注文件。但要注意文件名里的类别索引和data.yaml里names列表的顺序必须一致否则训练出来的模型会把松毛虫认成卷叶蛾而且 loss 曲线看起来还挺正常这种坑最恶心。YOLO 格式的标注是每张图对应一个同名.txt文件每行格式为class_id x_center y_center width height后四个值都是归一化到 0~1 的相对坐标不是像素值。这一点新手经常搞混直接把像素坐标写进去训练时框全跑到图像外面。校验的时候重点看两件事坐标是否都在 0~1 之间以及class_id是否超出类别总数。2.2 目录结构整理与 data.yaml 配置拿到压缩包后我一般先统一成 Ultralytics YOLO 的标准目录结构避免后面训练脚本到处改路径# 整理成标准 YOLO 目录结构 mkdir -p forest_pest/images/train forest_pest/images/val forest_pest/images/test mkdir -p forest_pest/labels/train forest_pest/labels/val forest_pest/labels/test # 假设解压后图片和标注混在一起按前缀或清单拆分 # 训练集 1199 张、验证集 257 张、测试集 259 张 # 实际拆分以数据集自带的 split 清单为准不要自己随机切这里强调一点数据集已经给好了 train/val/test 的划分不要图省事自己用random_split重新切。林业图像里同一棵树的多个角度可能被分到不同集合自己随机切会导致验证集里出现训练时见过的树指标虚高上线就露馅。data.yaml是训练的入口配置三个类别的顺序必须和标注文件里的class_id对齐# data.yaml path: ./forest_pest # 数据集根目录 train: images/train # 训练集图片相对路径 val: images/val # 验证集图片相对路径 test: images/test # 测试集图片相对路径 nc: 3 # 类别数 names: 0: pine_caterpillar # 松毛虫 Dendrolimus spectabilis Butler 1: pine_sawyer_beetle # 松墨天牛 Monochamus alternatus Hope 2: leaf_roller # 卷叶蛾 Rhyacionia duplana Hubnernc和names的对应关系是整个训练的地基。我见过有人把names写成中文训练能跑但导出 ONNX 后类别名乱码也有人nc写 3 但标注里出现了class_id3Ultralytics 会直接报索引越界。写完 yaml 后跑一遍校验脚本把异常样本挑出来import os from pathlib import Path def check_labels(label_dir, nc3): 检查 YOLO 标注文件的合法性 bad_files [] for txt in Path(label_dir).glob(*.txt): with open(txt) as f: for line_no, line in enumerate(f, 1): parts line.strip().split() if len(parts) ! 5: bad_files.append((txt.name, line_no, 字段数不为5)) continue cls_id int(parts[0]) coords [float(x) for x in parts[1:]] # 类别索引越界 if cls_id 0 or cls_id nc: bad_files.append((txt.name, line_no, f类别越界:{cls_id})) # 坐标必须在 0~1 if any(c 0 or c 1 for c in coords): bad_files.append((txt.name, line_no, 坐标越界)) # 宽高不能为 0 if coords[2] 0 or coords[3] 0: bad_files.append((txt.name, line_no, 宽高为0)) return bad_files if __name__ __main__: issues check_labels(forest_pest/labels/train) print(f发现 {len(issues)} 处问题) for name, line, reason in issues[:20]: print(f{name} 第{line}行: {reason})这个脚本的逻辑很直白逐行读标注检查字段数、类别索引范围、坐标归一化范围、宽高是否为正。参数nc要和data.yaml保持一致。跑完如果输出一堆「坐标越界」大概率是标注工具导出时用了像素坐标需要整体除以图像宽高重新归一化。这一步不做后面训练 loss 会卡在一个很高的值下不去你还以为是学习率的问题。3. 用 YOLOv8 跑通第一版基线训练参数与显存权衡3.1 模型选型n/s/m 三个尺度的取舍1715 张图在目标检测里属于小数据集直接上 YOLOv8l 或 x 基本等于自杀过拟合到验证集 mAP 看着还行、测试集一塌糊涂。我的建议是从 YOLOv8n 或 YOLOv8s 起步。n 版本参数量约 3.2Ms 版本约 11.2M在单张 8G 显存的卡上都能跑。林业害虫目标普遍偏小松毛虫幼虫体长也就几厘米在整幅图里可能只占几十个像素所以输入分辨率不能太低imgsz640是底线显存够就上 800 或 1024。选型上有个反直觉的点小数据集不一定非要用最小模型。如果害虫目标尺度差异大松墨天牛比卷叶蛾大不少YOLOv8s 的多尺度特征融合反而比 n 更稳。我一般会同时跑 n 和 s 两个基线看验证集上每个类别的 mAP哪个类别掉得厉害再针对性调。3.2 训练命令与关键参数说明Ultralytics 的训练接口封装得很好但参数不能无脑默认。下面是我在这个数据集上常用的训练命令yolo detect train \ dataforest_pest/data.yaml \ modelyolov8s.pt \ epochs150 \ imgsz640 \ batch16 \ lr00.01 \ lrf0.01 \ patience30 \ mosaic1.0 \ mixup0.1 \ degrees10.0 \ translate0.1 \ scale0.5 \ fliplr0.5 \ cacheTrue \ device0 \ projectruns/forest_pest \ nameyolov8s_baseline逐个说关键参数。epochs150对小数据集够用配合patience30早停验证集 30 轮不涨就停省时间。batch16是 8G 显存下 640 分辨率的稳妥值显存不够就降到 8 并开ampTrue混合精度。lr00.01是初始学习率lrf0.01是最终学习率系数余弦退火到初始值的 1%。数据增强里mosaic1.0是 YOLO 的招牌四图拼接能显著提升小目标检测但林业图像背景重复度高mosaic 比例太高会让模型学到拼接边缘的伪特征我一般训练后期把它降到 0.5 甚至关掉。mixup0.1轻微混叠增强泛化。degrees10.0旋转增强模拟无人机不同航向角拍摄。fliplr0.5水平翻转注意害虫形态左右翻转后仍然合理但如果你做的是有方向性的任务比如计数特定朝向的昆虫这个要关掉。cacheTrue把图片缓存到内存1715 张 JPEG 大概占几个 G内存够就开能明显加快数据加载。训练过程中重点盯三个指标box_loss是否稳定下降、mAP50和mAP50-95的差距、以及每个类别的instances数量。如果某个类别 instances 特别少比如卷叶蛾只有几十个标注框它的 mAP 会明显低于其他类这时候要考虑类别加权或者针对性补充数据。3.3 验证与推理别只看一个 mAP 数字训练完跑验证yolo detect val \ modelruns/forest_pest/yolov8s_baseline/weights/best.pt \ dataforest_pest/data.yaml \ imgsz640 \ conf0.25 \ iou0.5 \ save_jsonTrueconf0.25是置信度阈值iou0.5是 NMS 的 IoU 阈值。验证输出的混淆矩阵比单一 mAP 有用得多重点看松毛虫和松墨天牛之间有没有互相误判。这两个类别在图像里都是长条状褐色虫体模型分不清很正常。如果混淆矩阵显示这两类互相串说明特征区分度不够要么加数据要么在损失函数上做文章。推理单张图看效果from ultralytics import YOLO model YOLO(runs/forest_pest/yolov8s_baseline/weights/best.pt) results model.predict( sourceforest_pest/images/test, conf0.25, iou0.5, imgsz640, saveTrue, save_txtTrue ) # 统计每个类别的检出数量 for r in results: boxes r.boxes for cls_id in boxes.cls.unique(): count (boxes.cls cls_id).sum().item() print(f类别 {int(cls_id)}: {count} 个)save_txtTrue会把预测结果按 YOLO 格式存下来方便和真值对比算漏检率。实际部署时conf阈值要根据场景调森林虫害预警宁可误报不可漏报conf可以降到 0.15如果是精准施药误报会导致浪费农药conf提到 0.4 以上。4. 避坑与排查林业目标检测里那些血泪经验4.1 验证集 mAP 很高但测试集崩了现象训练时验证集 mAP50 到 0.85测试集一跑只有 0.5 出头。原因通常是数据划分有问题同一棵树的多个角度被分到了训练集和验证集模型记住了树皮纹理而不是虫体特征。解决检查数据集自带的 split 清单确认同一场景的图片没有跨集合。如果原始划分就有问题按拍摄地点或时间重新分组划分而不是随机切。4.2 小目标漏检严重松毛虫几乎检不到现象松墨天牛能检出松毛虫基本全漏。原因是松毛虫目标太小640 分辨率下可能只有 20 来个像素经过多次下采样后特征几乎消失。解决把imgsz提到 1024 或 1280同时在data.yaml里确认标注框没有因为缩放而丢失。另一个办法是改用 YOLOv8 的 P2 检测头增加一个更高分辨率的特征层但会牺牲推理速度需要权衡。4.3 训练 loss 震荡不收敛现象box_loss上下大幅震荡几个 epoch 都不降。原因可能是学习率太大或者 batch 太小导致梯度噪声大。解决把lr0从 0.01 降到 0.001batch尽量提到 16 以上。如果显存不够用梯度累积模拟大 batch。另外检查标注里有没有宽高为 0 的脏数据这种样本会让 loss 直接炸掉。4.4 类别不平衡导致卷叶蛾被忽略现象卷叶蛾的 mAP 远低于其他两类甚至为 0。原因是卷叶蛾标注数量少模型倾向于把它预测成背景。解决在训练时给类别加权或者用copy_paste增强少数类。Ultralytics 本身不直接支持类别权重可以通过过采样少数类图片实现。另一个思路是分两阶段先做二分类有虫/无虫再在正样本里做三分类。4.5 导出 ONNX 后类别名丢失现象PyTorch 模型推理正常导出 ONNX 部署后类别名变成class_0、class_1。原因是 ONNX 只保存张量计算图不保存names映射。解决在部署代码里手动维护类别名列表和data.yaml的names严格对应。导出时用yolo export modelbest.pt formatonnx opset12opset版本别太低否则某些算子不支持。5. 进阶技巧用测试时增强和切片推理榨干小目标召回基础训练跑通后真正拉开差距的是推理阶段的技巧。林业害虫检测最头疼的就是小目标我一般会在部署前加两道工序测试时增强TTA和切片推理SAHI。TTA 的思路是对同一张图做多种变换水平翻转、多尺度缩放分别推理后融合结果。Ultralytics 内置了 TTA 开关from ultralytics import YOLO model YOLO(runs/forest_pest/yolov8s_baseline/weights/best.pt) # 开启 TTA多尺度 翻转融合 results model.predict( sourceforest_pest/images/test, augmentTrue, # 开启测试时增强 conf0.2, iou0.5, imgsz1024 )augmentTrue会同时跑原图、翻转图、不同尺度图然后做 NMS 融合。代价是推理时间翻几倍但小目标召回能提升 5~10 个百分点。参数imgsz1024配合 TTA对松毛虫这种小目标效果明显。切片推理更适合高分辨率航拍图。把大图切成有重叠的小块每块单独推理再把结果拼回去。SAHI 库是这方面的标准工具from sahi import AutoDetectionModel from sahi.predict import get_sliced_prediction # 加载 YOLO 模型 detection_model AutoDetectionModel.from_pretrained( model_typeyolov8, model_pathruns/forest_pest/yolov8s_baseline/weights/best.pt, confidence_threshold0.2, devicecuda:0 ) # 切片推理512x512 切片重叠 128 像素 result get_sliced_prediction( forest_pest/images/test/sample.jpg, detection_model, slice_height512, slice_width512, overlap_height_ratio0.25, overlap_width_ratio0.25 ) result.export_visuals(export_dirsahi_output/)slice_height和slice_width决定切片大小overlap控制重叠比例重叠太小会在切片边界漏检太大则推理变慢。我一般设 0.2~0.3 的重叠。SAHI 会把每个切片的检测框映射回原图坐标再做全局 NMS。这套组合在无人机航拍林业场景里几乎是标配代价是推理速度下降但召回率的提升值得。还有一个容易被忽略的点置信度阈值不要一刀切。不同类别的最优阈值不一样松毛虫目标小、特征弱阈值要低一些松墨天牛特征明显阈值可以高一点。可以在验证集上对每个类别单独画 P-R 曲线找到 F1 最高的阈值部署时按类别分别设。从那以后我每次拿到新的目标检测数据集都强制先跑一遍标注校验脚本再确认 train/val/test 的划分逻辑最后才动训练命令。这个习惯帮我省了至少三次「训练三天发现标注是错的」的后悔药。希望帮到你。本文还有配套的精品资源点击获取
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →