简介:YOLOv8农业害虫检测源码包,面向深度学习初学者、农业图像识别开发者及植保相关研究人员,解决害虫识别依赖人工、效率低的问题。基于YOLOv8目标检测框架,提供从数据集构建、模型训练到界面部署的完整闭环,可用于棉铃虫、草地螟、东亚蟋蟀等24类常见害虫的快速识别。压缩包共98个文件,以jpg图像、txt标注文件、py训练脚本和yaml配置为主,配套README与依赖清单,结构清晰,便于直接运行与二次开发,包体约15.47MB。已有203人学习下载。资源内含25378张JPEG害虫图片及YOLO格式标注,划分好训练集、验证集与测试集;训练脚本覆盖学习率调整、超参数调优等优化思路,并提供PyQt5可视化界面,支持图像上传、自动检测与结果保存。通过该源码包,读者可掌握整套农业害虫检测系统的搭建方法,理解数据标注、模型训练和界面交互的衔接要点,为实际田间监测或科研实验提供可复用的技术底座。
1. 害虫检测项目为什么选择YOLOv8
农业害虫检测这个需求,我做了不止一次。最开始是帮一个植保站的朋友做果园虫情监测,他们白天用诱虫灯拍照,晚上人工数虫,一天几千张照片看得眼睛都快瞎了。后来换成了目标检测模型自动识别,虽然不能100%替代人工,但至少能把“数虫子”这个动作从几小时压缩到几秒钟。
那为什么最终选YOLOv8而不是YOLOv5、RT-DETR或者其他模型?先说YOLOv8,它是Ultralytics在2023年初发布的一代目标检测框架,最大的特点是把backbone和head都做了重新设计,C2f模块在保持轻量的同时增强了梯度流,anchor-free检测头省去了和anchor相关的很多调参工作。对农业害虫这种目标小、密度大、背景复杂的场景,anchor-free的设计在通用性上更友好。再加上Ultralytics团队把训练、验证、导出、部署的整个链路都整合在一个库里,对于做项目交付的人来说,省下的时间不是一星半点。
有人会问怎么不直接用最新的一代YOLO11?我对比过,YOLO11确实在COCO上有更高的精度,但它在一些边缘设备上的兼容性还在磨合期,而且很多第三方推理框架,比如OpenCV DNN、边缘设备上的加速库,对YOLOv8的支持最成熟。做农业项目往往要部署到田间地头的低成本设备上,稳定比指标更重要。这也是很多实际项目仍然选用v8的原因。当然,如果你的设备算力足够,想追求极限精度,后面我也会提到怎么把v8的改进思路迁移到新版模型上。
这篇文章适合正在做农业AI项目、或者拿YOLOv8训练自己数据集的开发者参考。我会把整个项目的环境搭建、数据准备、模型训练、部署导出都过一遍,重点讲那些文档里不写、但实际跑起来一定会踩到的坑。
2. 环境配置清单:一套能直接跑通的组合
2.1 硬件与软件版本组合
先说硬件。我手头这台开发机最常用来跑YOLOv8的是GTX 1660 Ti,6GB显存。很多人觉得6GB跑深度学习很吃力,其实YOLOv8的定位就是轻量级,只要不拿大batch去硬扛,跑yolov8s完全没问题。实测下来,imgsz=640、batch=8,GPU占用大约在5.2GB左右,训练一张图的耗时大概是0.15秒量级,一个100个epoch的常规训练大约需要5到7个小时,完全在可接受范围内。
软件版本方面推荐一套组合,我踩过好多轮坑以后定的:
- Python 3.8或3.9,不建议直接上3.12,很多第三方依赖在3.12上还没有预编译包;
- PyTorch 2.0.1 + CUDA 11.8,这个组合最稳,针对1660Ti这种Turing架构的支持也最好;
- ultralytics 8.0.x或8.1.x,不建议追最新minor版本,先用稳定版把流程跑通;
- OpenCV 4.8.0。
2.2 安装过程中最容易被卡住的三个环节
第一个坑是torch和CUDA版本不匹配。很多人直接从官网复制最新命令安装torch,装上以后一看torch.cuda.is_available()返回False。解决办法很简单,安装前先看显卡驱动支持的CUDA版本,在NVIDIA控制面板里能看到,然后到PyTorch官方的install页面选择对应版本生成命令。1660Ti的驱动通常已经支持CUDA 12.x,但装torch的时候选CUDA 11.8的版本也完全没问题,因为这边要求的是PyTorch编译时候带上的CUDA runtime,跟驱动版本是向下兼容的。
第二个坑是在Linux下跑的时候缺libGL.so.1,报错信息是ImportError: libGL.so.1: cannot open shared object file。这是因为opencv-python需要这个动态库,但系统没装。Ubuntu下直接apt-get install libgl1 libglib2.0-0,CentOS下执行yum install mesa-libGL。
第三个坑和项目本身相关,就是数据集路径。YOLOv8的训练命令是yolo train data=... model=...,如果你把数据集放在中文路径或者带空格的目录下,有概率在处理过程中出问题。虽然新版已经修了不少,但为了省心,所有项目路径我都建议用纯英文小写,连下划线都不加。
3. 数据集准备:标注、格式转换与类别平衡
3.1 公开数据集与自采数据怎么选
农业害虫检测最大的问题不是模型,而是数据。公开数据集里比较常用的是IP102,包含102类农业害虫,大约75000余张图。但它有个明显的问题:不少类别的图像是在实验室背景下拍的,背景干净、目标大,放到真实的大田场景里泛化性很差。我自己的做法是拿IP102做预训练数据,再用现场拍摄的图片做增量训练。毕竟你最终要检测的对象和拍摄条件,才是模型真正要面对的分布。
自采数据时有一个容易被忽略的点:拍摄角度和距离要尽量贴近实际部署位置。比如你是装在诱虫灯旁边的,拍出来的虫子通常是从侧面或者顶部打光,这和从网上随便下载的标本科普图差距很大。所以哪怕前期标500张现场图,也比标5000张网络图更能提升实际效果。
3.2 标注格式转换与目录组织
标注工具一般用LabelImg或者X-AnyLabeling。我习惯用X-AnyLabeling,它可以直接导出YOLO格式,还带模型辅助标注功能,效率高很多。YOLO格式的标注文件是.txt,每行一个目标,格式是class_id x_center y_center width height,坐标是相对于图片宽高的归一化值。
目录组织是YOLOv8训练能不能直接跑起来的关键,参考格式:
dataset/ images/ train/ val/ labels/ train/ val/YOLOv8可以直接用这个目录结构,配合一个data.yaml文件,里面写path: dataset、train: images/train、val: images/val以及names列表。
第一次做最常犯的错是训练集和验证集划分不干净,导致验证指标虚高。我会用scikit-learn的train_test_split在图片列表上按类别分层采样切分,保证每个类别在train和val里都有分布。如果某一类样本太少,宁可先不放进训练集,否则模型在验证集上会表现得极不稳定。
3.3 类别不平衡与小目标问题处理
农业害虫里常见的稻飞虱、蚜虫这一类体型极小,一张640x640的图中可能只有十几个像素大小,模型非常容易漏检。处理这个问题的三条路我建议一起做:
- 训练时把
imgsz提到960甚至1280,小目标尺寸在缩放后变大,特征更好提取,代价是显存和训练时间增加; - 使用马赛克增强,开启
mosaic=1.0,让模型同时看到多个背景下的目标,对小目标泛化有提升; - 单独给小目标类别的损失加权,在YOLOv8里可以通过自定义loss或者在采样时对小目标样本过采样实现。
类别不平衡也是老问题,比如某类害虫数量远多于其他类,模型最后会对多类过拟合,少类基本不检出。我的经验是先统计每类样本的数量,把少于30张的目标类合并成“other”类别或者干脆删掉,专业术语叫类别裁剪——宁可少认几类,也要保证每一类都能真的检出。
4. 训练配置与实测:不只是改个nc
4.1 模型结构参数详解
很多人拿到YOLOv8项目后第一件事就是改yaml里的nc,从80改成自己的类别数。这当然没错,但要注意YOLOv8的模型yaml不只是nc一个参数。以yolov8s.yaml为例,里面定义了backbone里的每个层的参数,比如from表示输入来自哪一层,repeats表示C2f模块重复几次。大多数情况下你不需要动这些,但有一些“改进”操作会在这些配置上做文章。
比如想在网络里引入多头注意力机制MHSA,通常做法是在backbone的深层(比如第8、9层之后)插入MHSA模块,替换掉一部分C2f,然后在yaml里对应添加新层的定义。同理,想把主干网络换成ConvNeXt V2,也是要重写整个backbone部分,而不是简单改一个参数。这两类改进对精度都有帮助,特别是小目标占多数的时候,但代价是训练时间和显存明显上升。项目工期紧的话,我的建议是先用原生结构做一版完整的基线,再考虑改进,不要一上来就上花活儿。
另一点很关键:YOLOv8默认会加载COCO预训练权重,也就是model=yolov8s.pt的时候,它会把COCO上80类的权重加载进来。这对你的农业害虫检测来说是个很好的起点,虽然COCO里没有害虫类别,但模型已经学到了大量通用的边缘、纹理、形状特征,迁移过来比从零训练收敛更快。
4.2 训练超参数设置与显存策略
我通常用这样的参数作为起点:
yolo train \ model=yolov8s.pt \ data=agri_pest.yaml \ imgsz=640 \ epochs=100 \ batch=8 \ workers=4 \ device=0 \ optimizer=AdamW \ lr0=0.001 \ mosaic=1.0关于batch,这里多说一句:显存不够的时候不要一次性把batch降到1。batch太小会导致BN层统计不稳定,模型收敛变慢甚至震荡。更好的方案是保持batch=8,把imgsz降到544,或者开启梯度累积。Ultralytics里没有直接的gradient accumulation参数,但可以通过batch=8外加在训练脚本里重写trainer的方式实现,新手不建议折腾这个,直接用imgsz=544方案最简单。
1660Ti上如果你想试着跑yolov8m,显存就非常吃紧了,需要imgsz=512、batch=4。实测yolov8s在害虫检测上已经能拿到满意的效果,mAP50大概在78到85之间(视数据集难度),v8m的提升通常在2到3个百分点,但训练时间直接翻倍。如果项目要求快速迭代,我优先推荐v8s。
4.3 增量训练:用自己的数据集续训
增量训练在我的项目里用的最多。因为大田里的害虫种类不是固定的,今天发现一种新害虫,我不可能重头把所有数据重新标一遍。这时只需要把新类别的样本加到数据集里,更新data.yaml,然后加载之前训练好的best.pt继续训练,就是所谓的fine-tune。
这里有一个非常重要的细节:如果你的新增类别会导致类别数变化,需要把模型head对应的输出通道一并更新。YOLOv8的head输出维度跟类别数相关,直接加载旧权重会报shape不匹配。正确做法是先用旧的best.pt重新构建一个不同nc的模型(也可以直接改pt里的nc参数),或者干脆用model = YOLO('yolov8s.pt')加载预训练权重,然后在训练命令里指定新的data.yaml,Ultralytics会自动调整最后一层。另一种做法是冻结backbone训练几个epoch,再解冻全部层做二次精调,这也叫两阶段微调。我实测下来,冻结backbone两个epoch再解冻全部层训练的效果,往往比直接全部训练更好,因为新类别的数据量通常较少,全量训练容易把已有特征破坏掉。
5. 训练过程解读:损失函数曲线、验证指标与常见坑
5.1 损失函数曲线怎么判断收敛
训练结束后,Ultralytics会在runs/detect/train/目录下生成一堆曲线图,包括results.png和results.csv。我一般不看单纯的loss曲线,而是框损失(box_loss)、分类损失(cls_loss)和DFL损失这三条曲线一起看。如果三条曲线都在下降并且最终趋于平缓,说明模型正常收敛;如果训练损失还在下降但验证损失已经开始上升,那就是典型的过拟合,此时应该考虑早停、增强或者减小模型容量。
还有一个常见现象是loss曲线前期剧烈抖动。这个通常是学习率设置过高或者batch太小导致的。排查方法:把初始学习率从0.01降到0.001,如果抖动明显缓解,说明是学习率问题;如果还在抖,检查数据增强是否过于激进,特别是mosaic和mixup开得太猛的时候,前几个epoch loss曲线不太平滑是正常的,不用急着干预。
5.2 验证指标怎么看
训练完以后,val阶段会输出一组指标,核心的包括mAP50、mAP50-95、precision、recall。在害虫检测场景里,我更看重recall,因为漏检比误检更严重——漏掉一只虫子意味着虫情估计偏低,可能错过防治窗口期;而误检还可以通过人工复核过滤。所以调参的时候如果precision和recall冲突,我会倾向于让recall高一些,然后再实测调整置信度阈值(conf_thres)来平衡误检率。
关于mAP50-95,很多人纠结这个值低,但要注意农业害虫数据集的标注质量参差不齐,再加上很多害虫本身边界模糊,mAP50-95能达到50左右已经算是不错了。这个指标更多用于模型之间的横向比较,不必当作项目验收的唯一标准。
5.3 排查链路:训练不收敛、loss为NaN、显存溢出
我整理了几次实际排查的经验,按出现频率排序:
loss变成NaN。这个我遇到过两次,一次是数据里有空的标注文件(0个目标的txt),一次是某张图片损坏导致读取出来全黑。处理方式是写一个脚本遍历所有标注文件,删除没有目标的txt,同时对图片做完整性校验,比如用OpenCV读取一次,无法正常解码的直接删掉。另外如果初始学习率设得过高(比如超过0.01),也可能在第一个epoch就出现NaN。
验证集的mAP一直是0。这个大概率是数据集划分出了问题,最常见的是验证集里放了一张训练中出现过的图片,数据泄漏导致结果虚高(反向也有问题);或者类别编号和data.yaml里的names顺序对不上,模型学到的类别和验证集标注的类别错位。排查方法很简单,随机挑几张验证集图片,把标注框可视化出来,一眼就能看出问题。
显存溢出(CUDA out of memory)。在1660Ti上最常触发。我的排查顺序是:先把batch砍半,如果还溢出,检查是不是验证阶段也占用了太多显存(可以把val关闭,只在最后评估);再不行就降低imgsz。还有一个容易忽略的点,是开了cache=True把整个数据集缓存到显存,这个在6GB卡上一定不要开,默认False就对了。
还有一个我踩过比较深的坑是Windows下workers设置太高导致训练卡死。在Windows上DataLoader的worker数超过4就容易出问题,直接设成workers=0最稳妥,虽然慢一点,但不会莫名其妙地中断。Linux服务器上workers=8没问题,Windows上的多进程机制有坑,别硬扛。
6. 部署导出:从pt权重到可用的检测服务
6.1 导出ONNX与模型压缩
训练完的best.pt只能在PyTorch环境里运行,交付给实际的虫情监测系统时通常要导出成ONNX或者TensorRT格式。我自己最常用的是导出ONNX然后用ONNX Runtime推理,兼顾兼容性和性能。
yolo export model=best.pt format=onnx imgsz=640 opset=12导出时有两个参数值得注意:opset不要设太高,有些老设备上的ONNX Runtime版本不支持最新的opset,opset=12是兼容性最好的选择;还有simplify=True可以简化模型结构,但偶尔会因为算子融合导致输出和原始模型有些许误差,实测对检测结果影响不大,但如果你对精度极其敏感,可以先不简化。
导出的ONNX文件可以进一步用onnxruntime的OrtSession做推理。一个完整的推理流程包括:读取图像、resize到640x640并做归一化、执行session.run、处理输出结果、恢复坐标到原始图像尺寸、过滤低置信度框并做NMS。
6.2 边缘设备的实际部署体验
我部署过的场景主要有两种:一种是田间有个小型工控机或Jetson设备,接摄像头连续抓拍;另一种是纯后端的服务器推理,前端只需要展示检测结果。如果是Jetson平台,我建议直接导出TensorRT格式,推理速度可以提升两到三倍,但TensorRT的版本跟CUDA、CUDNN版本强相关,环境不一致的时候容易导出失败,需要仔细对照版本表。如果只是PC上的原型验证,ONNX Runtime已经足够,640x640图像的单帧推理在1660Ti上大约耗时20到30毫秒,一个摄像机画面根本不在话下。
部署的时候还要注意一个细节:训练时的imgsz和推理时的imgsz要保持一致,或者推理时用更大的尺寸。比如训练用的是640,推理时因为要检测小目标,我通常也固定用640,因为尺寸变大虽然对小目标检测有好处,但也会显著增加耗时。如果项目对实时性要求很高,可以考虑半精度推理,把模型转为FP16,在1660Ti上能获得接近一倍的加速,而精度损失通常在1%以内。
6.3 检测线问题:目标检测与线检测的边界
我在做害虫项目的时候经常被问到:“YOLOv8可以检测线吗?”这里要区分一下,“检测线”在视觉任务里通常指的是车道线检测、电线检测这类线状目标检测,它不是目标检测的直接输出。YOLOv8的输出是矩形框,包括中心点坐标和宽高,这本身是描述一个“物体”,而线是一组点集,无法用矩形框拟合。如果真有检测线状目标的需求,路线应该是改成语义分割或者实例分割,或者用YOLOv8-seg版本,把线区域当成一个masks来分割。所以如果你想要的是“检测图片里有没有害虫、在哪”,那就是普通的目标检测;如果是“检测一条线、一根电线”,那要换模型,不能指望YOLOv8直接输出线的点坐标。
顺带提一句,YOLOv8官方也提供了分割模型yolov8s-seg.pt,如果你的场景需要精确到害虫轮廓,比如计算虫体面积、做虫龄分级,可以考虑用分割代替检测,效果会比检测框更精细,但标注成本也会翻倍。
6.4 可视化与结果输出
部署时最终要输出的是带框的图片或者检测结果JSON。有一个小技巧:如果后端只是把检测结果存库,前端负责画框,那后端就不需要做画框的渲染,只要输出类别、置信度和归一化坐标即可,这样可以省掉一部分CPU开销。如果确实需要直接输出带框图片,用OpenCV的rectangle和putText画就足够,不需要额外引入matplotlib这类重库。
我还建议在推理代码里加一条日志,记录每张图的平均推理耗时和检测到的目标数量。之前有个现场设备跑了一段时间后突然变慢,查了半天发现是日志文件无限增长导致磁盘满了,加上日志轮转之后问题立刻解决。这些看起来跟模型无关的小问题,在真实项目里往往比模型本身更影响交付体验。
我做完这套流程之后最大的体会是:农业害虫检测这类垂直场景,真正花时间的不是调模型结构,而是数据清洗、类别定义、标注规范、部署链路这些“脏活”。YOLOv8把模型部分做得足够省心,我们只需要把精力放在业务和数据上,就已经能拿到不错的结果。如果你手头也正攒了一批害虫图片不知道怎么下手,先从30张标注样本开始,走一遍完整流程,比看十篇教程都管用。
本文还有配套的精品资源,点击获取