ARTICLE DETAIL

资讯详情

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

YOLOv5草地冬虫夏草检测:数据集、训练与部署全流程

YOLOv5草地冬虫夏草检测:数据集、训练与部署全流程 简介本资源是一套面向计算机视觉初学者与农业AI应用开发者的冬虫夏草目标检测实战方案基于YOLOv5框架实现草地场景下的高精度识别任务。资源包含完整标注数据集共613张RGB图像及对应txt标签、可直接运行的训练/验证/推理代码、两个已训练权重文件best.pt与last.pt以及训练过程生成的PR曲线、混淆矩阵、F1曲线等可视化结果显著降低模型复现门槛。压缩包共1552个文件涵盖748张640×480分辨率JPG图像、615个YOLO格式标签、52个配置YAML文件、51个核心Python脚本及Docker相关部署文件总大小129.43MB结构规范便于二次开发与迁移适配。目前已有267人学习下载配套博文还提供YOLOv5改进技巧与训练调优指南助力用户快速掌握小众药材检测项目的全流程实践。 做目标检测也有些年头了最近忙里偷闲把“基于YOLOv5的草地冬虫夏草检测”这个项目好好收了个尾。标题里说的三样东西——数据集、代码、训练好的权重都已经打包整理好拿过去就能直接跑推理也可以按自己的数据重新训练。这篇文章就把整个流程从头到尾捋一遍为什么选YOLOv5、数据集怎么采集和标注、训练参数怎么调、实际部署会遇到哪些坑。给准备做类似小目标检测项目的朋友一个完整参考能少踩一个坑是一个坑。这个项目的场景其实很具体在自然草地里通过手持设备或低空无人机采集图像把隐藏在草丛中的冬虫夏草找出来。冬虫夏草本身颜色偏黄褐和枯草、泥土、碎石非常接近属于典型的小目标加复杂背景问题。这类项目听起来简单真正跑起来你会发现数据比模型更费精力标注规范比网络结构更影响最终效果。1. 项目整体设计与思路拆解1.1 为什么选YOLOv5而不是更新版本的检测模型先回答一个很多人都问过的问题现在YOLOv8、YOLOv11都出来了为什么还要用YOLOv5我的答案很直接稳定、生态成熟、部署资料多。对于一个实际交付项目来说能复现、能排错、能顺利部署到目标设备比“用了最新模型”重要得多。YOLOv5在2020年发布后经过多轮迭代社区沉淀了大量教程和踩坑记录。无论你遇到环境安装失败、训练不收敛还是推理崩溃基本都能搜索到对应解决方案。而且YOLOv5的代码结构相对清晰train.py、detect.py、val.py分工明确对新手来说非常友好。相比之下YOLOv8虽然API更现代但在一些边缘计算设备上的支持反而不如v5完善。在精度和速度的平衡上YOLOv5s的模型体积约14MB单张640x640图片在普通消费级GPU上推理速度可以达到毫秒级完全满足冬虫夏草野外检测的实时性需求。如果后续需要部署到Jetson、RK3588这类嵌入式平台YOLOv5的ONNX导出和量化工具链也是最成熟的。提示选模型不是选最新而是选你从训练到部署全链路都搞得定的那个。对大多数中小型检测项目YOLOv5s是一个性价比极高的起点。1.2 草地场景下的检测难点与应对思路冬虫夏草检测和常规的行人、车辆检测有本质区别。常规目标通常颜色鲜明、形状规整而冬虫夏草在自然草地中呈现三个明显难点。第一目标尺寸小。一条成年冬虫夏草的长度通常只有3到6厘米在手机拍摄的照片中占的像素区域很小如果采集距离较远目标可能只有几十个像素。这直接导致特征信息不足模型很难学出稳定特征。第二背景干扰强。草地里的枯草根茎、土块、碎石子颜色和纹理都与冬虫夏草高度接近。人眼都需要仔细辨别模型更容易被背景中的相似纹理带偏。第三光照变化大。不同时间段的光照角度、阴晴天气、树荫遮挡都会让目标的颜色呈现巨大差异。如果训练数据里光照场景覆盖不全模型在新的光线条件下表现会明显下降。针对这些问题我在方案设计上做了一些取舍。首先是采用高分辨率输入训练时把图像缩放到640甚至是1280像素确保小目标在特征图中保留足够信息。其次是强化数据增强尤其是色彩扰动和仿射变换让模型学会忽略光照变化带来的颜色漂移。最后是引入负样本也就是加入没有冬虫夏草的纯草地图片让模型学会区分“有目标”和“没有目标”。1.3 项目文件结构与全套交付内容这是整套项目的目录结构方便你拿到手就知道每部分放在哪里cordyceps_yolov5/ ├── datasets/ │ ├── images/ │ │ ├── train/ # 训练集图片 │ │ └── val/ # 验证集图片 │ ├── labels/ │ │ ├── train/ # 训练集标签YOLO txt格式 │ │ └── val/ # 验证集标签 │ └── data.yaml # 数据集配置 ├── weights/ │ ├── best.pt # 验证集mAP最高的权重 │ └── last.pt # 最后一个epoch的权重 ├── train.py # 训练脚本 ├── detect.py # 推理脚本 ├── requirements.txt # 依赖环境 └── README.md # 使用说明数据集部分是整个项目最花时间的环节。我采集了超过2000张自然草地图片包含不同季节、不同时段、不同草密度、不同光照条件下的目标样本每张图片都经过手工标注。训练好的最佳权重在验证集上mAP0.5达到0.82左右mAP0.5:0.95约0.55对于这种小目标场景已经具备实用价值。2. 数据集构建与标注细节2.1 数据采集怎么拍、拍多少、拍什么很多项目翻车不是翻在模型上而是翻在数据上。冬虫夏草检测尤其如此因为草地的背景形态实在太多了。我之前见过有朋友用几百张一个角度拍出来的图片训练模型在测试集上看着挺准一到真实环境就漏检严重原因就是数据太单一。采集数量上我的经验是原始图片不要低于1000张。YOLOv5官方建议每类目标至少1500张图片每张图片包含10个以上实例但这在冬虫夏草这种稀缺目标场景里很难实现。实际操作中800到1200张图片是性价比比较高的区间配合充分的数据增强也能训练出可用模型。如果条件允许2000张以上效果会有明显提升。采集场景覆盖是决定泛化能力的关键。我按下面几个维度做了覆盖光照条件覆盖早晨、中午、傍晚三个时段天气覆盖晴天、阴天、雨后草地类型覆盖稀疏草地、茂密草地、退化草地拍摄角度以俯瞰为主同时加入一定比例的斜视角度距离上近景和远景都要有确保不同尺度下的目标都出现在训练集里。拍摄工具用手机或普通相机都可以关键要保证目标清晰。照片分辨率建议不低于1200万像素因为分辨率太低小目标在裁剪缩放后容易丢失细节。采集时有一个容易被忽略的点不要只拍有冬虫夏草的地方也要拍大量没有目标的纯草地图片。这些负样本对降低误检率作用非常大模型只有见过“没有目标”的草地长什么样才能在推理时对背景区域给出低置信度。2.2 标注规范与格式转换标注我使用的是LabelImg工具开源免费操作简单支持直接输出YOLO格式。整个标注过程最核心的是统一标注标准我在这个项目里定了几条规则。类别只设置一个cordyceps。有人可能会问为什么不把虫体和子座草头分两个类别实际应用中用户只需要知道“哪里有冬虫夏草”不需要区分部位。而且虫体和子座在不同成熟度下形态差异很大如果强制分成两类反而会导致标注不一致增加模型的困惑。统一一个类别标注一致性高模型学习也更稳定。边界框要尽可能紧贴目标外围。框太大模型会学到大量背景信息框太小又会截断目标特征。冬虫夏草通常呈长条形边界框应该是一个能完整包围虫体和子座的最小矩形不要留超过目标轮廓10%的背景边距。对于部分被草叶遮挡的目标按照可见部分来框不要脑补完整轮廓。生成标签时LabelImg会输出class_id、x_center、y_center、width、height这五个数值坐标都是归一化到0到1之间的。例如一条标签可能是0 0.5234 0.6831 0.1247 0.0872转换完成后要抽样检查打开图片和标签叠加重叠显示确认没有错标、漏标、重复框。这一步一定不能省我见过不少项目因为标签坐标文件为空或者class_id写错导致训练时loss异常。2.3 数据增强图片不够增强来凑冬虫夏草数据集的结构相对单一如果直接用原始图片训练容易过拟合。YOLOv5内置了非常强的数据增强管线在训练时自动进行mosaic、随机仿射变换、色彩空间扰动等操作不需要额外写代码。其中mosaic增强对这个小目标检测项目帮助最大。它把4张训练图片随机拼接成一张让模型在拼接缝处学习检测小目标相当于变相增加了每张图片中的目标密度对提升小目标召回率非常有效。色彩扰动方面我重点调了HSV空间中的亮度扰动参数hsv_v。因为野外光照变化大同样的目标在强光和阴影下的颜色差异可以非常大。把亮度扰动范围适当调大让模型在训练过程中见到更多亮度变化能显著提升在复杂光照下的鲁棒性。还有一个容易被忽略的点不要过度使用水平翻转。冬虫夏草虽然不存在明显的方向性但如果背景中草叶纹理方向比较一致过度翻转可能让模型学到错误的背景模式。我最终只启用了水平翻转垂直翻转和90度旋转都没有打开经验是翻转对这类自然场景目标作用不大反而会拉低验证集mAP。3. 环境搭建与训练全流程3.1 YOLOv5环境安装与代码准备先说环境版本这是我实测稳定的一套组合组件版本说明操作系统Ubuntu 20.04 / 22.04Windows也能跑但Linux下省心很多Python3.8 或 3.9兼容性最好PyTorch1.10 到 2.0不要用太旧的版本CUDA11.3 到 12.1与PyTorch版本对应GPU显存8GB以上建议低于6GB需要大幅降batch安装步骤并不复杂。先创建虚拟环境然后安装PyTorch最后安装依赖conda create -n yolov5 python3.9 -y conda activate yolov5 pip install torch1.13.1cu117 torchvision0.14.1cu117 --index-url https://download.pytorch.org/whl/cu117 cd cordyceps_yolov5 pip install -r requirements.txt依赖安装完成后先别急着训练。我建议先跑一次推理测试确认环境没问题再继续。用官方提供的yolov5s.pt权重随便找一张图测试python detect.py --weights yolov5s.pt --source data/images/bus.jpg如果能成功输出检测结果图说明环境基本可用。这一步能提前排查出很多问题比如PyTorch与CUDA版本不匹配、opencv安装异常等。3.2 配置data.yaml与训练参数数据集的配置文件是最容易出错的地方。YOLOv5要求data.yaml里的路径要么写绝对路径要么写相对YOLOv5根目录的路径。我的配置如下train: datasets/images/train val: datasets/images/val nc: 1 names: [cordyceps]train和val指定的是图片文件夹路径标签文件夹会被自动推断为同路径下labels目录。nc是类别数这里只有1类。names列表与类别顺序对应。训练命令我使用这样的配置python train.py \ --img 640 \ --batch 16 \ --epochs 150 \ --data datasets/data.yaml \ --weights yolov5s.pt \ --cache逐项说明一下参数含义--img 640训练时把输入图片缩放到640x640像素。目标较小可以尝试1280但显存占用和训练时间都会显著增加。640起步跑通后再实验1280。--batch 16批大小。这个值受显存限制8GB显存建议1612GB可以到32。如果训练时出现CUDA out of memory就减半。--epochs 150训练轮数。150轮在单类小数据集上足够配合早停机制如果连续50轮验证集mAP没有提升会自动停止。--weights yolov5s.pt使用预训练权重。这是迁移学习的关键比从头训练收敛快得多精度也更高。--cache把图片预加载到内存减少磁盘IO等待训练速度能提升不少。内存够用就加上。学习率一般不用动YOLOv5默认0.01配合余弦退火调度器已经经过大量验证。如果训练时loss波动很大可以改成0.001再试。3.3 训练过程监控与权重选择训练启动后日志会实时打印每一轮的损失值和验证指标。对于单类别检测最需要关注的指标是mAP0.5和mAP0.5:0.95。mAP0.5指的是IoU阈值0.5下的平均精度可以理解为“框得差不多算对”的精度mAP0.5:0.95则是更严格的标准要求预测框和真实框重合度更高。在这个项目中mAP0.5达到0.8以上就基本具备使用价值了。如果训练到100轮后mAP还在0.5以下先别急着调模型结构大概率是数据标注有问题或者数据增强参数设置不合理。训练结束后有两个权重文件best.pt和last.pt。best.pt是验证集mAP最高时保存的模型last.pt是最后一轮的模型。常规操作是选best.pt做推理。我测试下来两者差距可能在两三个点mAP看起来不大但实际检测效果差异明显坚持用best.pt就对了。4. 使用训练好的权重进行检测4.1 单张图片、视频与批量的推理操作推理用自带的detect.py即可非常简单python detect.py \ --weights weights/best.pt \ --source test_images/ \ --conf-thres 0.25 \ --img-size 640--source可以指向单张图片、图片文件夹、视频文件甚至摄像头设备号。--conf-thres是置信度阈值只有置信度大于该值的检测框才会被保留。默认0.25对这个项目可以用0.3到0.35能有效过滤背景干扰带来的低置信度误检。如果需要保存检测框的坐标信息加上--save-txt --save-conf输出文件会保存在runs/detect/exp*/labels/目录下每行格式与训练标签一致只是多了置信度0 0.5234 0.6831 0.1247 0.0872 0.87这个功能在做批量统计时非常有用。比如你要统计一批照片中冬虫夏草的分布密度直接解析txt结果就行不需要一张张看图。4.2 检测结果分析与效果调优第一次跑推理后建议把输出的检测图和原图放在一起逐张检查。看有没有漏检有没有把枯草根误判成目标边界框有没有明显偏大或偏小。漏检多的场景通常是目标太小或者颜色太接近背景。我遇到最典型的案例是阴天光线暗的情况下目标整体呈暗褐色模型置信度会明显降低。解决办法有两种一是把这部分场景的图片补进训练集重新训练二是在推理时把--img-size从640提高到1280让模型看到更高分辨率的输入小目标的特征会更明显但推理时间会增加一倍。误检大多发生在碎石多、苔藓多的草地因为颜色和纹理高度相似。解决误检比解决漏检更麻烦最有效的手段是增加负样本数据。我把这些误检图片单独挑出来确认没有标注遗漏后作为纯背景图片加入训练集。YOLOv5会自动处理没有标签文件的图片模型会学习到这些场景应该输出低置信度。4.3 模型导出与轻量化部署思路训练好的PyTorch权重如果要部署到实际产品中一般需要导出为更通用的格式。YOLOv5官方提供了export.py脚本支持导出ONNX、TensorRT、CoreML等格式python export.py --weights weights/best.pt --include onnx --img-size 640ONNX格式是当前最通用的部署中间格式。后续如果要部署到嵌入式平台比如瑞芯微RK3588、RV1106或者Jetson系列ONNX都是关键一步。以RK平台为例拿到ONNX后用RKNN-Toolkit转成平台专用的rknn格式再接入RKNN API做推理整个过程在官方文档中都有完整说明。如果部署目标是PC端且使用NVIDIA GPU最推荐TensorRT加速。TensorRT的优化效果非常可观一张640x640图片的推理时间可以从5毫秒级降到2毫秒级而且显存占用更低。导出命令python export.py --weights weights/best.pt --include engine --device 05. 常见问题与排查技巧实录5.1 训练不收敛、loss异常偏高训练过程中最常遇到的情况是loss一直不下降或者前期下降后突然反弹。我把常见的几种情况整理成了一张速查表症状可能原因处理方法loss完全不下降标签文件为空检查labels目录下是否有.txt文件坐标是否是归一化0-1范围loss震荡剧烈学习率过高将--hyp中的lr0从0.01降到0.001loss出现nan梯度爆炸降低batch size或检查数据是否有异常像素训练很快但mAP很低数据集太小增加数据增强力度或更换yolov5n小模型mAP一直停滞在0.3以下标注严重不一致抽查标签与图片重点检查边界框是否忽大忽小一个容易被忽视的问题是类别编号。冬虫夏草只有1个类别但如果标签文件里的class_id误标成大于0的数值比如1或2模型训练时会出现“类别数不匹配”的错误提示或者明明设置了nc1但训练日志里出现奇怪的类别数。遇到这种情况用脚本扫描所有标签文件检查class_id的最大值是否等于nc-1。5.2 漏检和误检严重漏检和误检是这类检测项目的核心痛点排查思路不太一样。漏检也就是该检测到的目标没检测到本质上是因为模型没有学到足够的目标特征或者目标在输入图像中太小。先看漏检的目标大多数出现在小目标区域还是颜色相近的区域。小目标区域漏检优先提高--img-size到1280颜色相近的漏检需要补充类似光照和背景的数据。还有一个技巧推理时开启TTA增强加上--augment参数模型会对输入做多尺度变换和翻转后取平均结果小目标召回率会有明显提升但推理时间会成倍增加适合离线处理后使用。误检则多数出在数据层面。模型把枯草根、苔藓、虫子残骸识别成了目标说明训练数据中缺少这些相似背景的负样本或者正样本的标注框过于宽松导致模型学到了太多背景特征。我的处理流程是先收集误检图片逐一确认不是标注遗漏如果标注遗漏反而说明模型比标注工作做得更好然后把确认无目标的图片直接丢进训练集。做两到三轮这样的迭代误检率一般能显著下降。5.3 显存不足、环境报错等实战坑点训练阶段最常见的报错是CUDA out of memory。解决办法是降低batch size从16降到8再到4总能跑起来。但要注意batch size太小会导致batchnorm统计不稳定模型收敛变慢。一个折中方案是保持较小batch size的同时增加梯度累积步数YOLOv5暂时没有直接参数需要手动在train.py中修改。对于新手我建议直接换一张显存更大的显卡或者用云GPU省下折腾的时间。环境版本不匹配的坑也很频繁。最常见的是PyTorch版本太新导致加载老权重文件报错。有时候你从网上下载的权重是用PyTorch 1.10保存的但本地环境是PyTorch 2.2运行时会出现类似Cant get attribute __numba_signature__的错误这是因为pickle序列化过程中的兼容性问题。解决办法是尽量保持训练和推理环境版本一致或者把权重转换为兼容格式。另外一个容易踩的坑是中文路径问题。YOLOv5代码对中文路径支持不友好训练或推理的目录如果带中文可能会出现图片读取失败、标签文件找不到等莫名其妙的问题。所有路径全部使用英文命名能避免大量无意义排查。6. 后续扩展方向6.1 小目标优化方向切图推理与高分辨率训练如果想把检测精度再往上提一个台阶最有效的方式是切图推理也就是SAHI方案。把一张高分辨率大图切成若干有重叠的patch分别送入模型检测再把结果拼回去并做去重合并。这个方案对小目标检测效果提升非常明显因为目标在patch里的相对尺寸变大了特征更容易被提取。实现起来也不复杂网上有开源的SAHI库可以无缝对接YOLOv5检测结果。代价是推理时间会随着切图数量成倍增加适合对精度要求高、实时性要求低的应用场景。如果后续要做无人机巡草这类任务配合切图推理几乎是最佳方案。6.2 多类别扩展与品质评估当前的模型只判断“有没有冬虫夏草”。实际业务中客户往往还想知道“这棵冬虫夏草的品质如何”。要做到这一点可以引入多类别分类按子座长度、虫体完整度、颜色状态等分成不同等级。这时需要重新标注一份带有等级标签的数据集把nc从1改成对应类别数其他训练流程基本不变。但要注意等级之间的边界往往很模糊标注一致性很难保证。我建议先只分两到三个等级比如“完整品”和“残次品”不要一上来就分四五个档。把标注标准写清楚给标注员提供明确的视觉参照图能有效降低标注噪声。6.3 移动端与嵌入式平台的部署思路冬虫夏草检测如果要走出实验室大概率需要一个便携式的硬件方案。常见选择是手机App加云侧推理或者边缘计算盒子。后者的好处是不依赖网络适合偏远野外环境。在RK3588这类边缘设备上部署流程是将best.pt导出为ONNX再转成RKNN格式。转换时要注意几个点ONNX导出时固定输入尺寸为640不要用动态尺寸如果遇到不支持的算子可以在导出时加--simplify参数做图优化转换后务必在板子上验证精度RKNN量化到int8后通常会有1到3个点的mAP损耗这在大部分场景下是可以接受的。在项目交付时我一般建议客户先用浮点模型跑通完整流程再考虑量化部署。不要一上来就追求极致性能功能正确永远优先于跑得多快。本文还有配套的精品资源点击获取
返回列表