ARTICLE DETAIL

资讯详情

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

Yolov5苹果检测实战:从环境配置到边缘部署的避坑指南

Yolov5苹果检测实战:从环境配置到边缘部署的避坑指南 简介这份资源面向深度学习入门者、计算机视觉方向学生及需要完成课程设计或毕业项目的开发者提供一套基于Python与Yolov5的苹果水果检测识别完整方案帮助解决目标检测从环境搭建到模型训练、推理落地的全流程问题。压缩包共171个文件约4.38MB以46个py源码、46个yaml配置、48个pyc编译文件为主辅以sh运行脚本、Dockerfile容器配置及png、jpg示例图片覆盖训练、推理与部署各环节。目前已有494人学习下载说明方案具备一定参考价值。读者可获得可直接运行的检测代码、数据集与模型配置、环境依赖说明及文档指引按文档配置后即可复现苹果识别效果并在此基础上替换数据集迁移到其他水果或目标检测任务适合作为课程作业、竞赛练手或入门Yolov5的实践素材。1. 从一份“高分项目”压缩包说起苹果检测到底难在哪拿到“基于PythonYolov5苹果水果检测识别源代码文档说明”这个标题多数人第一反应是苹果检测不是烂大街的入门案例吗能有什么门槛。真把一份果园实拍图丢进去跑你会发现模型把青苹果认成叶子、把两个挨着的苹果框成一个、把逆光下的红苹果直接漏掉。苹果检测的难点从来不在“苹果”这两个字而在果实的颜色随成熟度漂移、果实之间高度遮挡、枝叶背景纹理和果面高光极度相似这三件事上。Yolov5 之所以成为这类项目的默认选择是因为它在单阶段检测器里把工程可用性做到了极致权重文件小、推理速度快、训练脚本开箱即用配合 Python 生态能快速从标注走到部署。这套方案适合三类人想用 Yolov5 训练自己数据集的初学者、需要把检测模型落到边缘设备比如树莓派5的嵌入式开发者、以及要交一份完整课程设计或比赛作品的学生。接下来我会按“环境怎么搭、数据怎么标、参数怎么调、坑怎么避”的顺序把这份压缩包背后真正要做的活讲清楚。2. 环境配置与 Yolov5 源码跑通从 conda 到第一张推理图2.1 为什么优先用 conda 而不是裸 pipYolov5 的依赖里最麻烦的是 PyTorch 和 torchvision 的版本匹配裸 pip 装出来的组合经常在torch.cuda.is_available()上返回 False或者训练到一半报 CUDA 版本不兼容。conda 能把 Python 解释器、CUDA runtime、cuDNN 一起锁在同一个环境里这是我在多台机器上复现时最省心的做法。Python 版本建议 3.8 到 3.103.11 之后部分依赖轮子还不全容易在pycocotools这类包上翻车。# 创建独立环境Python 锁 3.9 conda create -n apple_yolo python3.9 -y conda activate apple_yolo # 安装 PyTorchCUDA 11.8 版本按自己显卡驱动调整 pip install torch2.0.1 torchvision0.15.2 --index-url https://download.pytorch.org/whl/cu118 # 克隆 Yolov5 源码用官方仓库别用来路不明的魔改版 git clone https://github.com/ultralytics/yolov5.git cd yolov5 pip install -r requirements.txt这段命令的逻辑是先隔离环境避免污染系统 Python再装带 CUDA 支持的 PyTorch最后装 Yolov5 自己的依赖。requirements.txt里会拉matplotlib、opencv-python、pandas、seaborn这些其中opencv-python在无桌面环境的服务器上要换成opencv-python-headless否则会报libGL.so.1找不到。参数上唯一要盯的是 PyTorch 的 CUDA 版本号它必须小于等于你显卡驱动支持的最高 CUDA 版本用nvidia-smi右上角那个数字去对。2.2 验证环境是否真的可用装完别急着训练先跑一次官方权重推理确认整条链路通。# 下载 yolov5s 权重并推理官方示例图 python detect.py --weights yolov5s.pt --source data/images/bus.jpg --device 0--weights指定权重--source可以是单张图、文件夹、视频甚至摄像头编号--device 0表示用第一块 GPU没有 GPU 就写cpu。跑完在runs/detect/exp/下会生成带框的图。如果这一步报AssertionError: CUDA unavailable说明 PyTorch 装成了 CPU 版回上一步重装。如果报显存不足把--device改成cpu先验证逻辑再回头查显卡占用。这一步能过说明 Python、Yolov5、推理后端三件事都对了后面训练出问题就只可能是数据或超参数的事排查范围直接缩小一半。3. 苹果数据集制作标注规范与 YOLO 格式转换3.1 采集与标注什么图该进数据集苹果检测的数据集质量决定上限。我一般会按三个维度凑图光照顺光、逆光、阴天、成熟度青果、半红、全红、遮挡程度单果、双果紧贴、被枝叶挡一半。每个维度至少覆盖 200 张总量 1500 到 3000 张起步。采集时手机或相机都行但同一批数据尽量保持相似分辨率避免模型在尺度上反复横跳。标注工具用 labelImg 或 Label Studio类别名统一写apple别一会儿apple一会儿AppleYolov5 对类别名大小写敏感混用会直接多出一个类。标注框的规则是框要贴紧果实可见轮廓被遮挡的果实只框可见部分不要凭想象补全。两个紧贴的苹果如果中间有可见缝隙就标两个框如果完全糊成一团宁可标一个框也不要硬拆否则模型学到的边界是错的。3.2 从 XML 到 YOLO txt转换脚本与四个边界坑labelImg 默认存 Pascal VOC 的 XMLYolov5 要的是每张图对应一个 txt每行类别 中心x 中心y 宽 高且全部归一化到 0 到 1。下面这个脚本我用了很多次直接抄。import os import xml.etree.ElementTree as ET # 类别映射必须和 data.yaml 里的 names 顺序一致 classes [apple] def convert(xml_dir, out_dir, img_w, img_h): os.makedirs(out_dir, exist_okTrue) for xml_file in os.listdir(xml_dir): if not xml_file.endswith(.xml): continue tree ET.parse(os.path.join(xml_dir, xml_file)) root tree.getroot() # 用 XML 里记录的真实尺寸别硬编码 size root.find(size) w int(size.find(width).text) h int(size.find(height).text) lines [] for obj in root.iter(object): cls obj.find(name).text if cls not in classes: continue cls_id classes.index(cls) bbox obj.find(bndbox) x1 float(bbox.find(xmin).text) y1 float(bbox.find(ymin).text) x2 float(bbox.find(xmax).text) y2 float(bbox.find(ymax).text) # 越界裁剪防止标注时手抖拖出画面 x1, y1 max(0, x1), max(0, y1) x2, y2 min(w, x2), min(h, y2) cx (x1 x2) / 2.0 / w cy (y1 y2) / 2.0 / h bw (x2 - x1) / w bh (y2 - y1) / h lines.append(f{cls_id} {cx:.6f} {cy:.6f} {bw:.6f} {bh:.6f}) with open(os.path.join(out_dir, xml_file.replace(.xml, .txt)), w) as f: f.write(\n.join(lines)) convert(annotations/xmls, labels/train, 0, 0)逻辑说明脚本遍历 XML读真实宽高做归一化对越界坐标做裁剪最后按 YOLO 格式写 txt。四个容易踩的边界坑一是 XML 里的size和实际图片尺寸不一致改过图没改标注归一化会整体偏移二是坐标出现负数或超过宽高不裁剪训练时会报non-normalized coordinates三是类别名不在classes列表里被静默跳过导致某些图变成空标签四是空标签文件要保留Yolov5 把空 txt 当负样本用删掉反而会让模型在纯背景图上乱框。3.3 data.yaml 怎么写path: ../datasets/apple train: images/train val: images/val nc: 1 names: [apple]path是数据集根目录train和val是相对路径。nc是类别数苹果只有一类就写 1。names的顺序必须和转换脚本里的classes完全一致错一位模型就会把苹果学成别的类。目录结构按images/train、images/val、labels/train、labels/val摆Yolov5 会自动把images替换成labels去找标签路径对不上是最常见的“训练不报错但 loss 不降”的原因。4. Yolov5 训练苹果检测模型超参数怎么设、指标怎么看4.1 从预训练权重开始别从零训苹果数据集通常几千张从零训收敛慢且容易过拟合。标准做法是加载yolov5s.pt做迁移学习骨干网络已经学过通用边缘和纹理特征微调检测头就够了。python train.py \ --weights yolov5s.pt \ --data data/apple.yaml \ --img 640 \ --batch 16 \ --epochs 100 \ --hyp data/hyps/hyp.scratch-low.yaml \ --device 0--img 640是输入分辨率苹果在画面里占比小就往上提到 960但显存占用按平方涨。--batch 16是批大小显存不够就降到 8 或 4同时把学习率按比例调小。--epochs 100对几千张数据够用看val/box_loss不再下降就可以提前停。--hyp选hyp.scratch-low.yaml是因为小数据集用低学习率增强更稳别一上来用hyp.finetune.yaml的高学习率容易把预训练权重冲垮。4.2 三个必调超参数第一个是学习率lr0默认 0.01小数据集建议降到 0.001 到 0.005配合lrf最终学习率比例0.01 做余弦退火。第二个是anchor苹果的宽高比接近 1:1如果默认 anchor 里长条框太多可以用python utils/autoanchor.py --data data/apple.yaml重新聚类让先验框贴合果实形状。第三个是mosaic增强概率默认 1.0 对苹果这种密集小目标有帮助但如果你的图里果实特别大mosaic 拼接后单果被切碎反而要降到 0.5。4.3 指标怎么看mAP 之外还要盯什么训练日志里mAP0.5是最常看的苹果检测一般能到 0.9 以上。但别只看这个数precision高recall低说明模型保守漏检多要降置信度阈值或加正样本recall高precision低说明乱框多要提阈值或清理误标。混淆矩阵在runs/train/exp/下重点看苹果有没有被分到背景类背景误检多通常是负样本纯背景图不够。验证集和训练集的 mAP 差距超过 0.1就是过拟合加数据或加dropout、weight_decay。5. 苹果检测的避坑与排查五个血泪教训5.1 训练 loss 正常但 mAP 一直是 0现象训练跑完box_loss和obj_loss都在降但验证 mAP 始终 0。原因九成是标签路径或类别映射错了。Yolov5 找标签是把图片路径里的images替换成labels如果你把标签放在labels/train但图片在datasets/apple/images/train路径对不上就全当负样本。解决用python utils/dataloaders.py里的检查逻辑或者手动打印一张图的标签路径确认存在再核对data.yaml的names和 txt 里的类别 id 是否对应。5.2 模型把青苹果全漏掉现象红苹果检测很好青苹果 recall 极低。原因是数据集中青果样本太少模型把“红色”当成了苹果的强特征。解决按成熟度分层采样青果至少占三分之一训练时开hsv_h、hsv_s、hsv_v色彩增强让模型对颜色脱敏更多依赖形状和纹理。5.3 两个紧贴的苹果被框成一个现象密集果实场景下两个苹果只出一个框。这是 NMS 的 IoU 阈值太高把相邻框合并了。解决推理时把--conf-thres提到 0.4 以上--iou-thres从默认 0.45 降到 0.3让重叠框保留更多。训练层面标注时紧贴果实要标两个独立框别图省事标一个。5.4 树莓派5上推理慢到没法用现象PC 上 30 FPS部署到树莓派5只有 2 FPS。原因是默认用 PyTorch 原生推理没做模型转换。解决用export.py导出 ONNX 或 NCNN 格式树莓派上跑 NCNN 版本能到 8 到 10 FPS。命令是python export.py --weights best.pt --include onnx再用 onnxruntime 加载。注意导出时--img要和训练一致否则精度掉得厉害。5.5 换一批新果园的图精度断崖下跌现象自测集 mAP 0.95换到另一个果园的图只有 0.5。这是域偏移训练集的光照、背景、品种和实际场景不匹配。解决把新场景的图加进训练集做增量训练或者用--freeze 10冻结骨干只微调检测头小样本也能快速适配。别指望一个模型通吃所有果园这是苹果检测最现实的边界。6. 把模型用起来导出、部署与一个提精度的小技巧训练完的best.pt只是半成品真正落地要过导出和部署两关。导出 ONNX 是最通用的路径python export.py --weights runs/train/exp/weights/best.pt --include onnx --img 640 --dynamic--dynamic让输入尺寸可变方便不同分辨率的摄像头。导出后用onnxruntime加载推理代码里注意预处理要和 Yolov5 的letterbox一致等比缩放后补灰边而不是直接 resize直接 resize 会让苹果变形精度掉 5 个点以上。部署到边缘设备时NCNN 和 TensorRT 是两条主流路线。NCNN 适合 ARM 架构树莓派5上按官方文档编译把.param和.bin两个文件拷过去就能跑。TensorRT 适合 NVIDIA 的 Jetson 系列用trtexec把 ONNX 转成 engine推理速度能再翻一倍但 engine 和显卡型号绑定换设备要重新转。最后分享一个我常用的提精度技巧测试时增强TTA。推理时把图水平翻转、多尺度缩放各跑一次把结果做 NMS 融合mAP 通常能涨 1 到 2 个点代价是推理时间翻倍。对离线检测任务值得对实时视频流就不划算。命令上 Yolov5 的detect.py加--augment就能开 TTA但部署到边缘设备时这个逻辑要自己写因为导出的 ONNX 不含 TTA。我自己踩过最深的一个坑是花了两周调超参数最后发现是标注时把十几张图的类别名写成了apples模型一直把这些图当负样本学。从那以后我养成了一个习惯训练前先跑一遍标签统计脚本把每个类别的框数量和图片数量打出来数字对不上就绝不开始训练。这个习惯帮我省下的时间比任何调参技巧都多。希望帮到你。本文还有配套的精品资源点击获取
返回列表