☰
基于Python与Shell的YOLOv5花卉识别模型训练与部署解析
2026/10/1 10:40:07 网站建设 项目流程

简介:基于Python与Shell的YOLOv5花卉识别完整源码,面向有一定深度学习基础的计算机视觉学习者与开发者,可直接用于花卉检测、分类识别项目,以及毕业设计、课程实验或算法二次开发。压缩包共102个文件,大小约1.19MB,其中包含40个YAML配置、32个Python源文件、11个YML模板、5个Shell脚本,以及Dockerfile、Notebook教程、测试图片和说明文档等。配置与源码分离,YAML/YML文件便于按需调整数据集路径、超参数与模型结构;Python代码覆盖数据预处理、模型训练、验证、推理等核心环节;Shell脚本可自动化完成依赖安装、数据准备与训练启动,Dockerfile则有助于快速搭建一致的运行环境。资源另附tutorial.ipynb交互式教程和样例图片,清晰展示从原始数据到识别结果的完整处理链路。目前已有370人学习,整体结构清晰、易于上手,是一款适合快速搭建花卉识别应用的开源参考实现。

1. 先拆源码包:Python 管模型,Shell 管流程,跑通才是硬道理

标题里这个“基于Python与Shell语言的yolov5花卉识别模型设计源码”,说白了就是一个把 YOLOv5 训练和推理封装成两套脚本的项目:Python 负责模型训练、数据转换、推理这些真正吃算力的活,Shell 负责环境安装、目录创建、批量跑任务这些脏活累活。第一次打开这种源码包,最容易踩的第一个坑就是不知道从哪个文件开始执行——先跑训练脚本还是先跑环境脚本?我的答案是:别急着看 train.py,先把 Shell 脚本按顺序过一遍,环境不通后面全是黑匣子。适合谁?手里有花卉图片数据集、想用 YOLOv5 训练一个能识别具体花种的模型、又不满足于只在 Jupyter 里点运行的人。它解决的核心问题不是模型精度,而是“训练流程能不能一键复用”。

2. 从目录到环境:Shell 如何把 YOLOv5 训练前置流程串成一条龙

打开源码包的第一件事,建议先看目录结构,而不是找 train.py。原因很简单:这个项目把 Python 和 Shell 的边界设在“模型逻辑”和“流程编排”上,不搞懂边界位置,后面所有路径都会对不上。常见做法是:

flowers_yolov5/ ├── setup.sh # 环境安装脚本 ├── prepare_data.sh # 数据集划分脚本 ├── train.sh # 一键训练脚本 ├── detect.sh # 推理脚本 ├── data/ │ ├── flower_dataset.yaml # 数据集配置 │ ├── images/ # 原始图片 │ └── labels/ # YOLO格式标签 ├── yolov5/ # 官方YOLOv5源码 └── scripts/ ├── voc_to_yolo.py # Python标注转换 └── verify_data.py # 数据校验脚本

这个目录树里,setup.sh 管环境、prepare_data.sh 管数据、train.sh 管启动训练、detect.sh 管推理,它们都只负责“把命令按顺序跑完”;而 yolov5 目录里的 train.py、val.py、detect.py 才是模型真正的入口。Python 脚本对系统环境不敏感,但对路径和依赖敏感;Shell 脚本刚好反过来,路径错了它会提前暴露,环境缺了它会直接中断。所以源码包把这两类脚本组合在一起,本质是用 Shell 的可读性来降低 Python 项目的落地门槛。

2.1 Python 与 Shell 的分工边界:为什么要用两套语言

我一般会按这个标准来划分:需要条件判断、数据计算、动态生成内容的逻辑放 Python;需要操作文件、调用外部命令、按固定顺序执行的任务放 Shell。YOLOv5 训练流水线里正好有大量后者。比如虚拟环境创建、pip 安装、目录初始化、数据集切分、训练启动、权重备份,这些用 Shell 写出来,任何人拿到源码包都能看得懂执行顺序;而模型结构、损失计算、数据增强、后处理这些,放进 Python 才有办法调试和扩展。

有人觉得 Shell 脚本可有可无,直接在终端敲命令更灵活。真到了把训练任务交给定时任务或者部署到树莓派上的时候,你就明白需要一条可复现的脚本。用 shell 命令行串起来,换一台机器只需要改前几行的路径变量,后面完全不用动。这个源码包设计的合理之处就在于:Shell 不越界去写模型逻辑,Python 不越界去管系统依赖,两类文件各管一段,训练流程才不容易翻车。

2.2 环境配置脚本:把 Python、PyTorch 和 YOLOv5 依赖一次装齐

如果你按“python安装教程”那套思路先装 Python 再一个个装包,很容易装完 torch 发现版本和 CUDA 对不上,然后又去重装。源码包里一般都会带一个 setup.sh,把环境准备固化成一条命令。下面是我常用的写法:

#!/bin/bash # setup.sh —— 创建虚拟环境并安装 YOLOv5 依赖 set -e ENV_NAME="yolov5" PYTHON_VERSION="3.9" # 1. 创建 conda 虚拟环境 conda create -n $ENV_NAME python=$PYTHON_VERSION -y # 2. 激活虚拟环境,非交互环境下必须用 conda.sh 做初始化 source "$(conda info --base)/etc/profile.d/conda.sh" conda activate $ENV_NAME # 3. 安装 PyTorch 与 YOLOv5 依赖 pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118 pip install -r yolov5/requirements.txt # 4. 验证关键依赖 python -c "import torch, cv2, PIL; print('env ready')"

这段脚本我一般放在源码包根目录,第一行 set -e 的意思是:只要中间任何一条命令失败,整个脚本立刻停止。实际踩坑点在第 2 步:在脚本里直接写 conda activate 经常会报 command not found,因为 conda 的初始化函数只在交互式 shell 里加载。提前 source conda.sh 是常见解法。至于 PyTorch 版本,要根据服务器 CUDA 版本调整,不熟的话先用 CPU 版跑通流程也行,别让版本选择卡住整个项目。本地用 vscode python环境配置调试时,记得在 vscode 底部选择这个 conda 环境,不要用系统默认解释器。

2.3 数据集切分脚本:用 Shell 在训练前把图片和标签按 8:1:1 拆好

花卉识别数据集不管是从网上下载还是自己拍照,原始文件通常堆在一个目录里。YOLOv5 训练时要求 train/val 分开,而且 images 和 labels 必须成对出现,手工拖文件夹不仅慢还容易漏。prepare_data.sh 就是为这个写的,核心是 Shell 的 find、shuf 和 while 循环:

#!/bin/bash # prepare_data.sh —— 把原始花卉图片和标签按 8:1:1 划分 RAW="data/raw" TRAIN="data/train" VAL="data/val" TEST="data/test" mkdir -p $TRAIN/images $TRAIN/labels mkdir -p $VAL/images $VAL/labels mkdir -p $TEST/images $TEST/labels # 生成随机排序的文件清单,shuf 保证每次划分顺序不同 find $RAW -name "*.jpg" | shuf > _all_images.txt TOTAL=$(wc -l < _all_images.txt) TRAIN_COUNT=$((TOTAL * 8 / 10)) VAL_COUNT=$((TOTAL * 1 / 10)) idx=0 while read -r img; do base=$(basename "$img" .jpg) label="$RAW/${base}.txt" # 没有对应标签的文件直接跳过,避免训练时报警 if [ ! -f "$label" ]; then echo "skip $img : label missing" continue fi if [ $idx -lt $TRAIN_COUNT ]; then dest=$TRAIN elif [ $idx -lt $((TRAIN_COUNT + VAL_COUNT)) ]; then dest=$VAL else dest=$TEST fi cp "$img" "$dest/images/" cp "$label" "$dest/labels/" idx=$((idx + 1)) done < _all_images.txt rm _all_images.txt echo "done. train=$TRAIN_COUNT val=$VAL_COUNT"

逻辑说明:先用 shuf 打乱图片列表,再用 wc -l 统计总数;Shell 的整数除法只有整除,所以 test 集的数量就是总数减去 train 和 val,不会多算。代码里用 basename 取出不带 .jpg 的文件名,拼出同名 txt 路径,这是最容易被忽视的一步。参数可调的是 8 和 1 的比例,如果图片数量不到 1000,我一般改成 8:2:0,把 test 也并入 val,节约标注样本。另外这里用的是 cp 而不是 mv,保留原始数据等于给自己留后悔药。

3. 用 Python 改数据集与超参:YOLOv5 花卉识别训练的入口配置

YOLOv5 源码本身是一个通用目标检测架子,想让它变成“花卉识别模型”,核心工作集中在这几个文件上:数据集配置文件 data/.yaml、超参数文件 data/hyps/.yaml,以及把原始标注转换成 YOLO 格式的 Python 脚本。很多教程只告诉你“改完就能训”,但花点时间搞懂每个字段为什么这么设计,后面调参才不抓瞎。

3.1 数据集 YAML 配置:nc 和 names 写错,训练立刻崩

用 yolov5 训练自己的数据集,最典型的就是先写数据集 yaml。这个文件告诉训练脚本去哪里找图片、有哪些类别。以五种常见花卉为例:

# data/flower_dataset.yaml path: /home/user/flowers_yolov5/data # 数据集根目录,建议用绝对路径 train: images/train val: images/val test: images/test nc: 5 names: 0: rose 1: sunflower 2: tulip 3: daisy 4: dandelion

参数说明:path 是根目录,train 和 val 是相对 path 的路径。YOLOv5 会根据 train 自动推导 labels 目录——如果 train 指向 images/train,那么 labels 必须放在 labels/train,两个目录呈同级关系。把这个结构理解透,后面遇到 “No labels found” 就能秒定位。nc 是类别总数,必须和 names 的长度一致;names 的索引顺序决定模型输出的数字对应哪朵花,这个顺序从训练到推理都要统一。

常见翻车点是相对路径。如果 path 写成 data/,而当前目录不在 data 上一级,训练时大概率找不到图片。我习惯把 path 写死成绝对路径,或者用 readlink -f 在 Shell 里动态解析,这样不管在哪个目录执行脚本都不会漂。

3.2 超参文件里最值得调的参数:lr0、mosaic、mixup

YOLOv5 源码里的 yolov5超参数 文件叫 hyp.scratch-low.yaml,控制着学习率、动量、数据增强强度。花卉识别任务视觉上靠颜色和纹理区分,和 COCO 那种通用检测不一样,所以超参必须改。下面是几个我在花卉任务里经常动的参数:

# data/hyps/hyp.scratch-low.yaml 中修改 lr0: 0.005 # 初始学习率,花卉数据量不大时从 0.01 降到 0.005 更稳 lrf: 0.2 # 最终学习率为 lr0 * lrf momentum: 0.937 weight_decay: 0.0005 warmup_epochs: 3.0 # 数据增强 mosaic: 0.8 # mosaic 增强概率,小数据集建议调低或关闭 mixup: 0.2 # 混合增强概率,类别间重叠多时才建议调高 fliplr: 0.5 # 左右翻转 hsv_h: 0.015 # 色调增强范围 hsv_s: 0.7 # 饱和度增强范围 hsv_v: 0.4 # 明度增强范围

参数说明:lr0 默认 0.01 是 COCO 百亿级样本的经验值,花卉数据集通常只有几千张,学习率太大会导致 loss 震荡;我一般先用 0.005 或者 0.003。mosaic 默认 1.0,意思是每张训练图都由四张图拼接生成,这对小目标和遮挡有帮助,但花卉识别更依赖整体颜色分布,四图拼接后经常出现一朵花被切一半、颜色混杂的情况,所以降到 0.8 甚至 0.5 更合理。mixup 是两张图混合,在类间比较像的 rose 和 tulip 之间有正效果,但如果数据量小,效果不稳定。hsv 增强参数要保守,后面避坑章节会单独说。

判断超参是否合适,最直接的做法是先用 20 个 epoch 跑一轮,观察训练集和验证集的 loss 曲线。如果训练 loss 下降而验证 loss 回升,说明增强不够或者模型过拟合;如果两条曲线都平着走,可能是学习率过小。

3.3 用 Python 把原始标注转成 YOLO 格式:XML 到 txt 的完整脚本

很多花卉数据集来自公开的 VOC 格式标注,也就是每个文件对应一个 XML。而 YOLOv5 只需要一个 txt,每行内容为:类别索引 中心点x 中心点y 宽度 高度。转换脚本是源码包里最标准的 Python 工具脚本,下面是我平时直接抄过来改的版本:

# scripts/voc_to_yolo.py # 把 Pascal VOC 格式的 XML 标注转成 YOLOv5 的 txt,输出归一化坐标 import os import xml.etree.ElementTree as ET # 类别名到索引的映射,必须和 flower_dataset.yaml 的 names 顺序一致 CLASS_MAP = {"rose": 0, "sunflower": 1, "tulip": 2, "daisy": 3, "dandelion": 4} def convert_annotation(xml_path, out_dir, img_w, img_h): tree = ET.parse(xml_path) root = tree.getroot() out_lines = [] for obj in root.findall("object"): name = obj.find("name").text if name not in CLASS_MAP: print(f"skip unknown class: {name}") continue xml_box = obj.find("bndbox") x_min = float(xml_box.find("xmin").text) y_min = float(xml_box.find("ymin").text) x_max = float(xml_box.find("xmax").text) y_max = float(xml_box.find("ymax").text) # 归一化到 [0, 1],YOLO 格式是 center_x center_y width height x_center = (x_min + x_max) / 2.0 / img_w y_center = (y_min + y_max) / 2.0 / img_h w = (x_max - x_min) / img_w h = (y_max - y_min) / img_h out_lines.append( f"{CLASS_MAP[name]} {x_center:.6f} {y_center:.6f} {w:.6f} {h:.6f}" ) if out_lines: txt_name = os.path.splitext(os.path.basename(xml_path))[0] + ".txt" with open(os.path.join(out_dir, txt_name), "w") as f: f.write("\n".join(out_lines))

逻辑说明:YOLO 格式不接受左上角和右下角坐标,必须转成中心点加宽高,并且都除以图片宽高做归一化。img_w 和 img_h 不要从 XML 里读,因为很多 XML 里写的是标注时的尺寸而不是实际原图尺寸,正确做法是用 PIL 读取真实图片大小。类别名映射这里是简单字典,如果遇到不在映射里的类名,脚本会跳过并打印,这就是一种留痕,方便后续检查。这个脚本可以配合 Shell 的 for 循环批量执行:

for xml in data/raw/*.xml; do python scripts/voc_to_yolo.py "$xml" data/raw/labels 640 480 done

如果数据集是 csv 或 json 标注,转换思路完全一样,只是解析部分换成对应库。核心原则不变:输出一定是“类别索引 + 归一化中心点 + 归一化宽高”,且类别索引顺序和 yaml 完全一致。这个一致性一旦破坏,模型训练不报错,但推理结果会张冠李戴。

4. 启动训练并读验证指标:从命令行参数到 mAP 的完整闭环

数据集准备好了,下一步是把 YOLOv5 跑起来。这一步最容易翻车的不是模型结构,而是命令行参数设置。很多人习惯直接 python train.py 不带任何参数,结果用默认 COCO 的 80 类配置训练花卉模型,跑了两天发现类别数对不上。我的做法是先把一条最小可用的训练命令固定成 Shell 脚本,后面只改参数。

4.1 train.sh 里的参数逐个拆解:epochs、batch-size、imgsz、device

train.sh 是源码包里最核心的入口脚本。环境配置到位后,参数就是唯一的变量。下面这条命令可以覆盖绝大多数花卉识别训练需求:

#!/bin/bash # train.sh —— 一条命令启动花卉识别训练 set -e source "$(conda info --base)/etc/profile.d/conda.sh" conda activate yolov5 python yolov5/train.py \ --weights yolov5s.pt \ --data data/flower_dataset.yaml \ --epochs 100 \ --batch-size 16 \ --imgsz 640 \ --device 0 \ --workers 4 \ --project runs/flowers \ --name experiment_01

参数说明:--weights yolov5s.pt 是 COCO 预训练权重,花卉虽然不是 COCO 里的类别,但底层边缘、纹理特征通用,用迁移学习能让 loss 起点低一大截。如果下载困难,可以去掉这个参数从零训练,但收敛会慢很多,不建议。--epochs 先给 100,一个小规模花卉数据集通常 50 到 80 个 epoch 就收敛,多了容易过拟合。--batch-size 按显存定,8GB 显存跑 16 比较稳,24GB 可以上 32,爆显存时直接减半。--imgsz 是训练分辨率,640 是默认值,如果图片里花朵很小,可以试 1280,但显存和时间翻倍,先别冲动。--device 0 表示用第一张 GPU,树莓派上改成 --device cpu。--workers 默认 4,Windows 下如果报 DataLoader 相关错误,改成 0 可以绕过去。

还有一个容易被忽略的参数是 --cache。YOLOv5 会每次迭代都读图片,磁盘慢时训练速度被 IO 卡住,加上 --cache 可以把图片预加载到内存里,对文件数量大的花卉数据集效果明显,前提是内存足够。这个参数不会改变精度,只影响训练速度。

4.2 训练日志与结果文件:怎么判断模型在正常收敛而不是原地打转

训练结束后,所有结果在 runs/flowers/experiment_01 目录里。我一般先看三个东西:weights 目录下的 best.pt 和 last.pt、results.png、confusion_matrix.png。

results.png 是训练曲线的总览,包含 box_loss、obj_loss、cls_loss、precision、recall、mAP 六条曲线。判断标准很简单:训练 loss 应该整体下行,偶尔震荡正常;验证集的 precision 和 mAP 如果一路往上,说明模型在学;如果 loss 下降但 mAP 不涨,先看是不是类别不平衡,某种花占了八成样本,模型学成了“看到花就猜那一种”。

best.pt 是按验证集 mAP 自动保存的最优权重,last.pt 是最后一个 epoch 的权重。epochs 没跑够被中断时,可以用 last.pt 加 --resume 恢复训练,这就是后悔药。我自己习惯每隔几个 epoch 看一眼 runs/flowers/experiment_01/weights,如果 last.pt 的文件修改时间正常跳着走,说明训练进程没挂。

4.3 用 Python 验证脚本计算 mAP:一个可靠的判断标准

训练完成不等于模型能用。best.pt 在验证集上的表现才是可信的。YOLOv5 里验证入口是 val.py:

python yolov5/val.py \ --weights runs/flowers/experiment_01/weights/best.pt \ --data data/flower_dataset.yaml \ --task val \ --conf-thres 0.25 \ --iou-thres 0.45

参数说明:--task val 表示只跑验证集;--conf-thres 0.25 是置信度阈值,低于 0.25 的框不纳入计算;--iou-thres 0.45 是 NMS 的 IoU 阈值,两个框重叠超过 0.45 会被合并。val.py 会打印 P、R、mAP@0.5、mAP@0.5:0.95 四项核心指标。

mAP@0.5 是 IoU 阈值 0.5 下的平均精度,花卉检测任务里我一般要求它到 0.9 以上才算能用;mAP@0.5:0.95 是更严格的指标,取多个 IoU 阈值的平均,通常比 mAP@0.5 低十几个点,不用强求。验证完后还会生成 confusion_matrix.png,这个图非常重要:如果 rose 和 tulip 互相混,说明这两个类在模型眼里太像,需要从数据层补样本或者调整增强参数;如果某个类别 precision 高但 recall 低,说明框太紧或者漏检多,可以适当调低置信度阈值。

5. 花卉识别训练与部署避坑:五个高频故障的排查路径

YOLOv5 训练花卉模型,坑很少出现在模型结构上,大多藏在数据路径、标注格式、Shell 环境这类看起来不起眼的地方。下面五条是我在多个项目里反复遇到的,每条都按现象、原因、解决的顺序说清楚。

5.1 “No labels found”警报:标签路径对不上

现象:train.py 启动后终端反复输出 WARNING,提示 No labels found in data/train/images,但目录里明明有 txt 文件。原因:YOLOv5 会根据 train 路径推断 labels 路径,train 是 images/train,它就去 labels/train 找同名文件,不会扫描整个 data 目录。解决:确认 images 和 labels 是同级目录,即 data/train/images 与 data/train/labels,不是 data/images/train。训练前先用一段 Python 校验脚本扫一遍:

import os root = "data/train" img_dir = os.path.join(root, "images") lab_dir = os.path.join(root, "labels") imgs = os.listdir(img_dir) missing = [ f for f in imgs if os.path.splitext(f)[0] + ".txt" not in os.listdir(lab_dir) ] print(f"missing labels: {len(missing)}") if missing: print("\n".join(missing[:10]))

这个脚本的逻辑很简单:遍历 train images 目录下每张图,检查 labels 目录里是否存在同名 txt,最后把缺失列表打印出来。我每次训练前都会跑一遍,能把“训练到一半发现标注丢了几百个”这种事消灭在启动前。

5.2 CUDA out of memory:batch-size 与 imgsz 的妥协

现象:训练刚开始几十个迭代就崩,日志最后一行是 CUDA out of memory,有时在验证阶段才爆。原因:batch-size 和 imgsz 的乘积超过显存大小。解决:先把 batch-size 降到 8,imgsz 保持 640;如果还是爆,imgsz 降到 512,或者换更小的模型权重 yolov5n.pt。不要一上来就换大模型,花卉识别的目标不算极端小,yolov5s 训练到 95% 的 mAP 完全有可能。如果显存只有 4GB,可以试试 batch-size 4 加 --cache,用内存换显存。注意推理阶段同样会爆,部署到嵌入式设备时,imgsz 和 batch-size 都要按设备算力重设。

5.3 混淆矩阵里两个花种永远分不开:类名顺序与数据不均衡

现象:训练 loss 正常收敛,验证 mAP 也不低,但打开混淆矩阵发现 rose 和 tulip 互相错分,精度损失集中在这两个类上。原因有两个:第一是转换脚本里 CLASS_MAP 的顺序和 yaml names 顺序不一致,导致索引错乱;第二是这两个类别在图像上本身相似,且样本量差距大。解决:先检查分类映射,手动找出 rose 的标注在训练 txt 里是不是 0,如果不对应,立刻重新生成标注;确认映射无误后,对易混类增加训练样本,或者把这两个类的 fliplr 关闭——因为有些花旋转后形态确实会变,垂直翻转更少见。数据不均衡时,可以在数据切分时用占比而不是绝对数量来取样,让每个 class 都参与训练。

5.4 Shell 脚本报 command not found:CRLF 换行和 conda 环境

现象:执行 setup.sh 报 conda: command not found,或者报 /bin/bash^M: bad interpreter。原因:conda 的初始化函数只写在 .bashrc 里,非交互式 shell 默认不加载;脚本如果在 Windows 上用记事本改过,换行符是 CRLF,Linux 下会把 \r 当成命令名的一部分。解决:脚本开头加上 source 那两行,见第 2 章;换行问题用 sed 直接处理:

sed -i 's/\r$//' setup.sh

这是 shell 中常见坑里最典型的两个。我每次拿到源码包第一件事是把所有 .sh 跑一遍 sed 换行清洗,避免后面被这种低级错误卡半天。另外在 Linux 系统安装 Python 时不要覆盖系统自带的 python3,优先用 conda 虚拟环境隔离,避免污染系统环境。

5.5 训练 loss 很低但真实照片识别差:数据增强把颜色改没了

现象:训练集和验证集 mAP 都很高,拿手机拍一张真实花卉测试,要么漏检要么错检。原因:数据增强里的 HSV 参数范围过大,模型在训练时看到大量颜色被扭曲的“假花”,反而把颜色当成了噪声。花卉识别和行人检测不一样,颜色是最重要的特征之一。解决:把 hyp 文件里的 hsv_h 从 0.015 降到 0.005,hsv_s 从 0.7 降到 0.3,hsv_v 从 0.4 降到 0.2;同时把 mosaic 概率调回 0.8。如果想验证是不是增强的问题,可以临时把 mosaic 和 hsv 全部关掉,重新训练 20 个 epoch,对比同一批真实图片的检测结果。注意部署时的图像预处理要和训练时一致,YOLOv5 的 detect.py 会统一做归一化,不要自己在外面再套一层预处理。

6. 把推理封装成 Shell 一键脚本:批量验证与树莓派部署技巧

训练完 best.pt,不能只在验证集上看指标,要拿真实图片走一遍完整推理流程。YOLOv5 的 detect.py 本身支持单张和目录输入,但真正落地时我习惯用 Shell 脚本把批量推理和后处理串起来。

6.1 用 shell 脚本 for 循环批量跑 detect.py

#!/bin/bash # detect.sh —— 遍历本地图片目录,逐张执行 yolov5 推理 source "$(conda info --base)/etc/profile.d/conda.sh" conda activate yolov5 RESULT_DIR="runs/inference" mkdir -p $RESULT_DIR for img in data/test/images/*.jpg; do echo "process: $img" python yolov5/detect.py \ --weights runs/flowers/experiment_01/weights/best.pt \ --source "$img" \ --conf-thres 0.25 \ --project "$RESULT_DIR" done

这里的 shell 脚本 for 循环负责把每个文件路径传给 Python,避免在 Python 里手动拼接系统路径。detect.py 每次运行都会新建一个 exp 目录,所以如果不想让结果散落,可以在 --name 上指定统一名称。detect.py 输出目录里每张图会生成对应的 txt,内容是类别索引、置信度和归一化框坐标,这个 txt 就是 yolov5 后处理阶段最常读取的产物,后续做数量统计或者温度上报都从这里取数据。

6.2 导出 ONNX 并在树莓派 5 上验证推理速度

如果想把训练好的模型部署到树莓派 5 上跑实时识别,常见做法是先把 best.pt 导出成 ONNX,再交给 onnxruntime 加载。命令很简单:

python yolov5/export.py \ --weights runs/flowers/experiment_01/weights/best.pt \ --include onnx \ --dynamic

导出后用一段 Python 读取:import onnxruntime,session.run 输出检测框。树莓派 5 上 CPU 跑 yolov5s 的 ONNX,输入 640 分辨率大约几百毫秒级别,做静态图片识别够用。如果追求更快,可以继续量化或者缩减 imgsz,但至少先确认 ONNX 的推理和 PyTorch 原版结果对齐。我自己现在每次训练前都会先跑一遍 5.1 的标签校验脚本,确认每张训练图都有对应 txt,再执行 train.sh。这个习惯救过我很多次,因为很多训练翻车并不是模型结构问题,而是上游某个 label 文件悄悄丢了。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询