程序项目代做,有需求私信(小程序、网站、爬虫、电路板设计、驱动、应用程序开发、毕设疑难问题处理等)

龙芯2k0300 - 智能车走马观碑组目标检测算法

该片文章用于跑通测试数据集链路:在 WSL/Linux 上训练 YOLOv5,导出 TorchScript,转换为 ncnnparam/bin,再通过 example/yolo_ncnn_app 部署到久久派测试。

WSL/Linux 测试数据集训练 -> TorchScript 导出 -> pnnx 转换 ncnn -> example/yolo_ncnn_app 部署测试

当前使用 WSL2,可通过 NVIDIA WSL 驱动访问宿主机 GPU。目标检测训练、TorchScript 导出和 pnnx 转换统一在 WSL/Linux 中完成。

一、项目结构与环境准备

1.1 目录职责

当前仓库根目录:

/opt/2k0300/loongson_2k300_lib

与本流程相关的目录:

tb_yolo/
  configs/demo/target_board.names       # 类别名,一行一个类别
  configs/demo/target_board.yaml        # YOLOv5 数据集配置
  dataset/demo/images/train/            # 测试训练集图片
  dataset/demo/images/val/              # 测试验证集图片
  dataset/demo/labels/train/            # 测试训练集标签
  dataset/demo/labels/val/              # 测试验证集标签
  models/pretrained/yolov5n.pt     # 默认迁移学习权重
  models/demo/best.pt              # 演示 PyTorch 权重
  models/demo/best.torchscript            # 演示 TorchScript
  models/demo/best.param           # 演示 ncnn 结构文件,转换后生成
  models/demo/best.bin             # 演示 ncnn 权重文件,转换后生成
  scripts/train_yolov5_host.sh     # WSL/Linux 训练入口
  scripts/export_torchscript_host.sh      # WSL/Linux TorchScript 导出入口
  scripts/export_ncnn_host.sh      # WSL/Linux TorchScript 转 ncnn 入口
  vendor/yolov5/                   # YOLOv5 源码
example/yolo_ncnn_app/             # 久久派 ncnn 离线推理示例
scripts/build_ncnn_loongarch.sh    # 下载并交叉编译 ncnn
cross_lib/ncnn/                    # ncnn 安装目录,脚本生成

1.2 日常操作目录

tb_yolo 相关命令默认在:

cd /opt/2k0300/loongson_2k300_lib/tb_yolo

example 部署命令默认在仓库根目录或 example 目录执行,文档会分别写清楚。

1.3 初始化 WSL/Linux 训练环境

必须使用 Python 3.10Python 3.11,不要使用系统自带 Python 3.14

如果系统还没有 conda,先安装 Miniforge。如果 wget 不存在,先安装:

sudo apt update
sudo apt install -y wget

安装并初始化 Miniforge

cd /tmp
wget https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-Linux-x86_64.sh
bash Miniforge3-Linux-x86_64.sh -b -p "$HOME/miniforge3"
eval "$("$HOME/miniforge3/bin/conda" shell.bash hook)"
conda init bash

执行 conda init bash 后,重新打开一个终端,或者执行:

source ~/.bashrc

如果安装后当前终端仍提示 Command 'conda' not found,说明当前 shell 还没有加载 conda,先执行:

eval "$("$HOME/miniforge3/bin/conda" shell.bash hook)"
conda --version

确认能看到 conda 版本号后,创建并进入 loong 环境:

conda create -n loong python=3.10
conda activate loong

安装 YOLOv5 依赖:

cd /opt/2k0300/loongson_2k300_lib/tb_yolo
python -m pip install -r requirements-host.txt

requirements-host.txt 已固定使用 CUDA 12.8PyTorch

torch==2.11.0+cu128
torchvision==0.26.0+cu128

vendor/yolov5/requirements.txt 不直接写 --extra-index-url,因为 YOLOv5 训练启动时会检查该文件,运行期检查逻辑会把 pip 参数误当成包名。训练脚本会提前复用系统字体生成 ~/.config/Ultralytics/Arial.ttf,避免训练时联网下载字体。

确认 WSL 能访问 GPU:

nvidia-smi
python -c "import torch; print(torch.__version__); print(torch.cuda.is_available()); print(torch.cuda.get_device_name(0) if torch.cuda.is_available() else 'cpu')"

成功后应看到:

torch: 2.11.0+cu128
CUDA available: True
CUDA device: NVIDIA GeForce RTX 5060 Laptop GPU
CUDA tensor test: 1.0

只看 torch.cuda.is_available() 不够,必须确认 CUDA 张量能实际创建和同步。

1.4 检查类别配置

测试数据集当前类别文件:

configs/demo/target_board.names

内容:

Mouse
Printer
drill
Wrench
Screwdriver

类别顺序必须同时匹配:

YOLO 标签 class_id
configs/demo/target_board.yaml
开发板运行目录中的 names.txt

二、使用测试数据集训练和转换

2.1 测试数据集位置

测试数据集已经放在:

tb_yolo/dataset/demo/images/train
tb_yolo/dataset/demo/images/val
tb_yolo/dataset/demo/labels/train
tb_yolo/dataset/demo/labels/val

本场景只用于验证流程,不代表最终上车效果。

注意:当前已经按数据集名隔离目录,不再使用拆分前的平铺目录。demo 场景统一使用:

outputs/train/demo/exp_demo_gpu/weights/best.pt
dataset/demo/images/val
configs/demo/target_board.yaml

2.2 启动训练

执行:

./scripts/train_yolov5_host.sh --name exp_demo_gpu

默认核心参数:

参数 默认值 说明
--name 命令指定(必填) 本次实验目录名,输出在 outputs/train/demo/<name>/
--weights models/pretrained/yolov5n.pt 迁移学习预训练权重,轻量模型适合开发板部署
--data configs/demo/target_board.yaml 数据集配置文件
--epochs 150 训练轮数
--batch-size 32 批量大小;显存不足时降低,例如 --batch-size 16
--imgsz 96 输入尺寸;后续 TorchScript 导出和 ncnn 推理必须与此一致
--device 0 使用第 0 块 GPU;CPU 训练用 --device cpu
--project outputs/train/demo 训练输出根目录
--optimizer SGD 优化器,可选 AdamAdamW
--hyp vendor/yolov5/data/hyps/hyp.scratch-low.yaml 超参数配置文件,小型数据集推荐 hyp.scratch-low.yaml
--patience 100 早停耐心值;验证集指标连续不提升的轮数
--cache -(不使用) 缓存图片到内存/磁盘,加速训练;可选 ramdisk
--resume - 从断点恢复训练,传入中断的权重路径
--noval switch(默认不启用) 跳过每轮验证,加快训练但无法观察过拟合
--nosave switch(默认不启用) 不保存中间权重,只保留 last.ptbest.pt
--exist-ok switch(默认不启用) 允许覆盖已存在同名输出目录
--freeze -(默认不冻结) 冻结前 N 层,例如 --freeze 10 只微调检测头

训练完成后优先使用:

outputs/train/demo/exp_demo_gpu/weights/best.pt

2.3 查看训练结果

重点查看:

outputs/train/demo/exp_demo_gpu/results.png
outputs/train/demo/exp_demo_gpu/confusion_matrix.png
outputs/train/demo/exp_demo_gpu/weights/best.pt

曲线含义:

曲线 含义 判断方法
train/box_loss 训练集框回归损失 越低越好,应逐步下降
train/obj_loss 训练集目标置信度损失 越低越好,反映是否能找到目标
train/cls_loss 训练集分类损失 越低越好,类别少时通常下降较快
val/box_loss 验证集框回归损失 如果训练下降但验证上升,可能过拟合
val/obj_loss 验证集目标置信度损失 验证集稳定下降更可信
val/cls_loss 验证集分类损失 类别混淆时会偏高
metrics/precision 预测为目标的结果有多少是真的 误检多时偏低
metrics/recall 真实目标有多少被检出 漏检多时偏低
metrics/mAP_0.5 IoU=0.5 下的检测精度 判断是否大体能检出
metrics/mAP_0.5:0.95 更严格的综合精度 判断框是否贴合

2.4 本机检测验证

执行:

python vendor/yolov5/detect.py --weights outputs/train/demo/exp_demo_gpu/weights/best.pt --source dataset/demo/images/val --data configs/demo/target_board.yaml --imgsz 96 --conf-thres 0.25 --project outputs/detect/demo --name exp_demo_val

输出图片在:

outputs/detect/demo/exp_demo_val

图片框上的数字是置信度,例如 0.91 表示模型认为该框属于对应类别的综合置信度约为 91%

2.5 导出 TorchScript

执行:

zhengyang@ubuntu:/opt/2k0300/loongson_2k300_lib/tb_yolo$ ./scripts/export_torchscript_host.sh --weights models/demo/best.pt --imgsz 96 --copy-model demo

TorchScript 导出不强制需要 GPU;脚本默认使用 --device cpu。导出时不要加 --optimizepnnx 需要标准 TorchScript 文件,不使用移动端 lite interpreter 格式。

参数说明:

参数 默认值 说明
--weights 必填 训练好的 .pt 权重路径,例如 outputs/train/demo/exp_demo_gpu/weights/best.pt
--imgsz 96 导出输入尺寸,必须与训练时的 --imgsz 一致
--copy-model - 导出后拷贝 best.torchscriptbest.ptmodels/<name>/ 目录
--batch 1 导出时的 batch 大小,部署推理通常为 1
--device cpu 导出设备;Linux 虚拟机没有 GPU 时保持 cpu
--install-deps false 导出前安装 YOLOv5 requirements.txt 依赖

生成:

models/demo/best.torchscript
models/demo/best.pt

--imgsz 必须与训练时一致。

2.6 检查 TorchScript

Netron 是神经网络模型结构查看工具,用来确认输入输出,不负责训练或推理。

网页版:

https://netron.app

本地安装:

zhengyang@ubuntu:/opt/2k0300/loongson_2k300_lib/tb_yolo$ pip install netron
zhengyang@ubuntu:/opt/2k0300/loongson_2k300_lib/tb_yolo$ netron ./models/demo/best.torchscript

重点确认:

输入尺寸:1x3x96x96
模型类型:TorchScript
导出尺寸与训练 `imgsz` 一致

注意:pnnx 转换后,ncnn 输入输出名固定按 in0out0out1out2 使用。

2.7 生成 ncnn 部署模型

前面导出的 best.torchscript 是中间格式,久久派上的 yolo_ncnn_app 使用 ncnn 推理,实际加载的是:

best.param
best.bin

其中:

best.param  网络结构
best.bin    网络权重

因此流程是:

best.pt -> best.torchscript -> best.param + best.bin

pnnxncnn 官方提供的模型转换工具。本流程中它负责读取 TorchScript,根据 inputshape 推断输入输出形状,完成算子转换和必要图优化,最终直接生成 ncnn 加载用的 best.parambest.bin。开发板端只加载转换产物,不再解析 .ptTorchScript

本项目使用 TorchScript -> pnnx -> ncnn 链路。部署端读取 out0 候选框矩阵,再在 C++ 中完成置信度过滤和 NMS

先安装官方 pnnx 命令行工具:

python3 -m pip install pnnx

然后在 tb_yolo 下转换:

cd /opt/2k0300/loongson_2k300_lib/tb_yolo
./scripts/export_ncnn_host.sh --torchscript models/demo/best.torchscript --imgsz 96 --copy-model demo

该脚本会:

调用 pnnx
使用 inputshape=[1,3,96,96]
生成 best.param / best.bin
复制 best.param / best.bin 到 models/demo/

参数说明:

参数 默认值 说明
--torchscript models/demo/best.torchscript TorchScript 模型路径
--imgsz 96 pnnx 输入尺寸,必须与训练和 TorchScript 导出尺寸一致
--copy-model - 转换后拷贝 best.parambest.binmodels/<name>/ 目录
--pnnx 自动查找 指定其他 pnnx 可执行文件
--fp16 1 pnnx 权重存储选项,默认启用 FP16 存储以减小模型体积
--optlevel 2 pnnx 优化等级
--device cpu pnnx 转换设备
--moduleop 可选 pnnx 高级参数;本项目默认不使用

生成:

models/demo/best.param
models/demo/best.bin

后续部署到久久派时,example/build_deploy_run.sh 会默认上传这两个文件到开发板运行目录。

转换后的 ncnn 模型使用以下 blob 名:

输入尺寸:float32[1,3,96,96]
输入:in0
输出:out0

这里 out0YOLOv5 已解码的候选框矩阵,每行格式为:

x_center, y_center, width, height, objectness, class0, class1, ...

yolo_ncnn_app 会在 C++ 里完成置信度过滤、坐标还原和 NMS

三、编译 ncnn 和部署到久久派

3.1 编译 ncnncross_lib

在能运行 bashgitcmake 和仓库交叉工具链的环境中执行:

./scripts/build_ncnn_loongarch.sh

环境变量说明:

环境变量 默认值 说明
NCNN_GIT_REF master 要编译的 ncnn git 版本标签,例如 20250503
NCNN_INSTALL_PREFIX cross_lib/ncnn 安装目标目录
NCNN_GIT_URL https://github.com/Tencent/ncnn.git ncnn 源码仓库地址
NCNN_JOBS $(nproc) 编译并行任务数,默认使用全部 CPU 核心

脚本会从 NCNN_GIT_URL 下载 Tencent/ncnn 源码,使用:

cross_lib/loongarch64-linux-gnu-gcc13.3

安装到:

cross_lib/ncnn

cross_lib/src/cross_lib/build/ 是源码和中间构建目录,已加入 .gitignore。需要固定源码版本时,可在运行前设置 NCNN_GIT_REF,例如:

NCNN_GIT_REF=20250916 ./scripts/build_ncnn_loongarch.sh

3.2 编译 yolo_ncnn_app

在仓库根目录执行:

cd example/yolo_ncnn_app
make clean
make

默认依赖:

cross_lib/ncnn
cross_lib/opencv-4.10.0
cross_lib/loongarch64-linux-gnu-gcc13.3

yolo_ncnn_app 使用 ncnn 推理,使用 OpenCV 读取图片、缩放和保存结果。

3.3 一键部署运行

在仓库根目录执行:

cd example
./build_deploy_run.sh --app yolo_ncnn_app -- --param best.param --bin best.bin --names names.txt --image test.jpg --output result.jpg

脚本会自动:

编译 example/yolo_ncnn_app/main
上传可执行文件到 /opt/yolo_ncnn_app/yolo_ncnn_app
上传 OpenCV core/imgproc/imgcodecs 运行库到 /usr/local/opencv/lib
上传 libncnn.so 到 /usr/local/ncnn/lib
上传 models/demo/best.param 到 /opt/yolo_ncnn_app/best.param
上传 models/demo/best.bin 到 /opt/yolo_ncnn_app/best.bin
上传 configs/demo/target_board.names 到 /opt/yolo_ncnn_app/names.txt
上传一张验证集图片到 /opt/yolo_ncnn_app/test.jpg
在开发板运行 /opt/yolo_ncnn_app/yolo_ncnn_app

3.4 部署参数说明

3.4.1 脚本参数(-- 之前,控制编译和上传行为)
参数 类型 默认值 说明
--app string 必填 要部署的应用名,对应 example/<app>/ 目录
--deploy string scripts/board_env.sh 开发板 SSH 地址,例如 root@172.23.15.40
--remote-dir string /opt 开发板上的部署基础目录,实际使用 /opt/<app>/
--remote-name string APP_NAME 远端可执行文件名
--target string main 本地构建产物文件名
--model string demo 本地模型/数据集名,对应 tb_yolo/models/<name>/tb_yolo/dataset/<name>/
--yolo-param string tb_yolo/models/<model>/best.param 本地 .param 文件路径,通常不用手动写
--yolo-bin string tb_yolo/models/<model>/best.bin 本地 .bin 文件路径,通常不用手动写
--yolo-names string 自动推导 本地类别名文件,默认使用 tb_yolo/configs/<model>/target_board.names
--yolo-image string 自动推导 本地测试图片路径,默认从 tb_yolo/dataset/<model>/images/val/ 取第一张
--ncnn-lib-dir string cross_lib/ncnn/lib 本机 libncnn.so 所在目录
--remote-ncnn-lib-dir string /usr/local/ncnn/lib 开发板 libncnn.so 部署目录
--opencv-lib-dir string cross_lib/opencv-4.10.0/lib 本机 OpenCV 运行库目录
--remote-lib-dir string /usr/local/opencv/lib 开发板 OpenCV 运行库目录
--no-run switch false 只编译和上传,不执行推理
--skip-build switch false 跳过本地构建,只上传已有可执行文件
--no-clean switch false 构建前不执行 make clean
--stop-old switch false 部署运行前先停止远端同名旧进程
--stop-only switch false 只停止远端同名旧进程,不构建、不上传
3.4.2 应用参数(-- 之后,传给 yolo_ncnn_appargv

重要--param--bin--names--image 的值是开发板上的文件名,不是本地路径。脚本上传时会自动做文件名映射:

  • 本地 .param → 远端 best.param(固定命名)
  • 本地 .bin → 远端 best.bin(固定命名)
  • 本地类别名文件(来自 --yolo-names 或默认配置)→ 远端 names.txt(固定命名)
  • 本地图片(来自 --yolo-image 或默认验证集第一张)→ 远端 test.jpg(固定命名)

所以 --image test.jpg 中的 test.jpg 是脚本上传图片时强制重命名的结果,无需用户关心本地图片叫什么。

参数 说明
--param <name> 开发板上 .param 文件名,与脚本上传时固定使用的名称一致,例如 best.param
--bin <name> 开发板上 .bin 文件名,与脚本上传时固定使用的名称一致,例如 best.bin
--names <name> 开发板上类别名文件名,与脚本上传时固定使用的名称一致,例如 names.txt
--image <name> 开发板上测试图片的文件名,脚本 scp 上传时固定重命名为 test.jpg
--output <name> 开发板上输出结果图片的名称,例如 result.jpg
--conf <value> 置信度阈值,默认 0.25;检测不到目标时可临时降低到 0.1 排查
--nms <value> NMS 交并比阈值,默认 0.45

3.5 常用部署示例

指定模型和测试图片:

./build_deploy_run.sh --app yolo_ncnn_app --model demo --yolo-image ../tb_yolo/dataset/demo/images/val/resized-171.jpg -- --param best.param --bin best.bin --names names.txt --image test.jpg --output result.jpg

指定本机 ncnn 库目录:

./build_deploy_run.sh --app yolo_ncnn_app --ncnn-lib-dir ../cross_lib/ncnn/lib -- --param best.param --bin best.bin --names names.txt --image test.jpg --output result.jpg

只构建和上传,不立即运行:

./build_deploy_run.sh --app yolo_ncnn_app --no-run

跳过本地构建,只重新上传已有可执行文件:

./build_deploy_run.sh --app yolo_ncnn_app --skip-build -- --param best.param --bin best.bin --names names.txt --image test.jpg --output result.jpg

部署运行前先停止远端旧进程:

./build_deploy_run.sh --app yolo_ncnn_app --stop-old -- --param best.param --bin best.bin --names names.txt --image test.jpg --output result.jpg

四、常见问题与排查

4.1 缺少 pnnx

报错类似:

Missing pnnx

说明当前机器找不到 pnnx 转换工具。安装官方 pnnx

python3 -m pip install pnnx

4.2 缺少 libncnn.so

如果部署时报:

ncnn library directory not found
Missing ncnn library

先执行:

./scripts/build_ncnn_loongarch.sh

确认存在:

cross_lib/ncnn/lib/libncnn.so

4.3 输出维度不匹配

优先检查:

names.txt 行数是否等于类别数量
--input-name 是否等于 best.param 中输入 blob 名,pnnx 默认 in0
--output-name 是否等于 best.param 中输出 blob 名,pnnx 默认 out0
训练、TorchScript 导出、ncnn 推理的输入尺寸是否一致

4.4 框位置不对

优先检查:

是否使用 letterbox 预处理
是否按 letterbox 的 scale/pad 还原坐标
输入 BGR/RGB 是否处理一致
imgsz 是否一致

4.5 类别整体错位

优先检查:

configs/demo/target_board.names
LabelImg classes.txt
开发板运行目录中的 names.txt

三处顺序必须完全一致。

posted @ 2026-05-11 23:04  大奥特曼打小怪兽  阅读(197)  评论(0)    收藏  举报
如果有任何技术小问题,欢迎大家交流沟通,共同进步