龙芯2k0300 - 智能车走马观碑组目标分类算法
tb_cls 是目标板轻量分类子项目,移植自龙邱 TinyClassifier 方案,用于管理真实目标板三大类分类数据、训练产物、模型转换和板端部署。
需要先明确一点:TinyClassifier 是图像分类模型,不是目标检测模型。它只判断输入图或裁剪 ROI 属于 weapon、supplies、vechicle 中的哪一类,不输出目标框。当前数据集里的图片都是无框图片,标签来自图片所在文件夹。
WSL/Linux 主机 GPU/CPU 训练 -> 导出 TorchScript -> WSL/Linux 主机 pnnx 转 ncnn -> 久久派/龙芯板端分类推理
主机侧先得到 TorchScript,再用 pnnx 转成 ncnn 的 param/bin。tb_cls 训练脚本仍会额外保留一份 ONNX 作为辅助产物,但开发板部署默认走 TorchScript -> pnnx -> ncnn。
一、目录分层规则
1.1 统一目录结构
tb_cls 采用单一目标板分类工程结构,配置、真实数据、模型和输出都直接放在根目录对应位置:
configs/labels.txt
dataset/dataset.zip
dataset/supplies/*.jpg
dataset/vechicle/*.jpg
dataset/weapon/*.jpg
models/best_model.pt
models/best.torchscript
models/best.onnx
models/best.param
models/best.bin
models/labels.txt
outputs/train/<实验名>
tb_cls 的标签来自文件夹名,数据目录是 ImageFolder 结构。当前三类目录为:
dataset/
├── supplies/
├── vechicle/
└── weapon/
类别顺序由 torchvision.datasets.ImageFolder 按文件夹名字典序生成,训练结束后会写入 labels.txt。当前 labels.txt 顺序为:
supplies
vechicle
weapon
车端解析分类结果时必须使用同一份 labels.txt。其中 vechicle 是当前目录和标签文件中的实际拼写,对应交通工具类。
仓库提交时只需要保留 dataset/dataset.zip,解压后的图片目录由 .gitignore 忽略。训练脚本会在发现 dataset/supplies、dataset/vechicle、dataset/weapon 不存在时,自动解压 dataset/dataset.zip。
二、环境准备和已有模型
2.1 Linux/WSL 训练环境
requirements.txt 是从 conda env: loong 导出的固定版本依赖,建议使用 Python 3.10 的独立环境。不要直接使用系统自带的 Python 3.14 安装本文件,因为 numpy、onnxruntime、torch 等固定版本可能没有对应兼容包。
如果系统还没有 conda,先安装 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 版本号后,再继续创建环境。
如果 wget 不存在,先安装:
sudo apt update
sudo apt install -y wget
创建并进入 loong 环境:
conda create -n loong python=3.10
conda activate loong
cd /opt/2k0300/loongson_2k300_lib/tb_cls
python -m pip install -r requirements.txt
requirements.txt 已固定使用 CUDA 12.8 版 PyTorch:
torch==2.11.0+cu128
torchvision==0.26.0+cu128
如果只做 ncnn 导出,还需要额外安装 pnnx:
python -m pip install pnnx
验证 PyTorch 环境:
python -c "import torch, torchvision; print(torch.__version__); print(torchvision.__version__); print(torch.cuda.is_available())"
Linux/WSL 没有配置 NVIDIA GPU 时,输出 False 也可以训练,只是会使用 CPU。
2.2 已有模型位置
当前仓库只保留真实目标板分类数据,dataset/ 下的数据就是后续训练使用的 ImageFolder 数据集。数据按三大类放置,不需要目标框标注。已经训练或转换好的模型统一归档在:
models/best_model.pt
models/best.torchscript
models/best.onnx
models/best.param
models/best.bin
models/labels.txt
configs/labels.txt 是同一份类别顺序文件,车端推理显示类别时必须按该顺序解析输出。
三、真实目标板数据集
3.1 数据内容
当前 dataset/ 目录下的数据就是真实目标板数据。图片内容来自赛道中心目标板,按业务含义分成三个大类,每个大类内部包含若干小类物体。
weapon 武器:枪支、爆炸物、匕首、警棍、消防斧
supplies 物资:急救包、手电筒、对讲机、防弹背心、望远镜、头盔
vechicle 交通工具:消防车、救护车、装甲车、摩托车
所有图片都是无框图片,不包含检测框标注。训练时只使用图片所在的大类文件夹作为分类标签,不区分大类内部的小类编号。
3.2 输入边界
TinyClassifier 只做整图分类,不做检测框定位。用于智能车目标板时,建议输入已经裁剪好的目标板 ROI,而不是整张赛道图。
可选裁剪方式:
- 目标板出现在固定区域时,直接从摄像头画面裁剪固定
ROI。 - 目标板位置有轻微变化时,先用颜色、边缘或几何规则定位候选区域,再送入分类模型。
- 如果目标板位置完全不稳定,需要额外实现轻量定位或裁剪逻辑。
3.3 数据目录
当前压缩包解压后按三大类建立文件夹:
dataset/
├── dataset.zip
├── supplies/
├── vechicle/
└── weapon/
ImageFolder 按文件夹名字典序生成类别编号。后续策略层应使用 labels.txt 映射业务动作,不要在车端硬编码类别编号。
如果提交仓库,保留:
dataset/dataset.zip
不要提交解压后的 dataset/supplies/、dataset/vechicle/、dataset/weapon/ 图片目录。运行训练脚本时会自动检查并解压。
四、训练和导出
4.1 模型结构
TinyClassifier 是轻量级卷积分类网络,主体由普通卷积、深度可分离卷积、全局池化和全连接分类头组成。当前默认输入尺寸为 96x96,输出类别数由 dataset/ 下的三类目录自动决定。
网络结构概览:
输入 1x3x96x96
Conv3x3 stride=2 + BN + ReLU
DWConvBlock stride=1
DWConvBlock stride=2
DWConvBlock stride=1
DWConvBlock stride=2
DWConvBlock stride=1
Conv1x1 + BN + ReLU
AdaptiveAvgPool2d(1)
Linear(num_classes)
输出 1x3 logits
DWConvBlock 内部结构为:
Depthwise Conv3x3 + BN + ReLU
Pointwise Conv1x1 + BN + ReLU
通道数由 --width-mult 控制,默认 0.6。基础通道序列为 12 -> 16 -> 24 -> 32 -> 48 -> 48 -> 64,实际通道数会乘以 width_mult,并保证最小通道数不低于 8。增大 width_mult 会提高模型容量和计算量;减小它会让模型更小,但可能降低准确率。
训练时使用 AdamW 优化器、CrossEntropyLoss 损失函数和 CosineAnnealingLR 学习率调度。数据集按类别内随机划分为 80% 训练集、10% 验证集、剩余 10% 测试集。
训练增强包括:
Resize(96x96)
RandomHorizontalFlip
RandomRotation(10)
ColorJitter
ImageNet Normalize
验证、测试和导出推理只使用 Resize、ToTensor 和 ImageNet Normalize。
4.2 训练并归档模型
4.2.1 WSL/Linux GPU/CPU 训练
WSL/Linux 中可运行:
./scripts/train_classifier_host.sh --run-name exp_cls
常用参数示例:
./scripts/train_classifier_host.sh \
--run-name exp_cls \
--img-size 96 \
--batch-size 64 \
--epochs 35 \
--width-mult 0.6 \
--target-acc 0.95
训练源码会自动选择设备:torch.cuda.is_available() 为真时使用 cuda,否则使用 cpu。首次从压缩包训练时,脚本会先自动解压数据集,再开始训练。正常日志示例:
[cls-train] Dataset class folders not found; extracting .../tb_cls/dataset/dataset.zip
[cls-train] Python: python
[cls-train] Dataset: .../tb_cls/dataset
Using device: cuda
Classes: ['supplies', 'vechicle', 'weapon']
4.2.2 训练输出
训练输出先写入:
outputs/train/<实验名>/
随后脚本会把关键产物复制到:
models/
训练结束后,原始输出位于:
outputs/train/<实验名>/
├── best_model.pt
├── tiny_classifier.torchscript
├── tiny_classifier_fp32.onnx
├── labels.txt
└── metrics.json
包装脚本会把关键产物同步到:
models/best_model.pt
models/best.torchscript
models/best.onnx
models/labels.txt
models/metrics.json
configs/labels.txt
4.2.3 训练脚本参数
| 参数 | 默认值 | 说明 |
|---|---|---|
--data-root DIR |
dataset |
ImageFolder 数据集根目录。默认目录缺少三类文件夹时,会自动解压 dataset/dataset.zip。 |
--run-name NAME |
exp_cls |
实验名,默认输出到 outputs/train/<实验名>/。 |
--out-dir DIR |
outputs/train/<实验名> |
显式指定训练输出目录。 |
--img-size N |
96 |
输入图片尺寸。训练、导出和板端推理必须保持一致。 |
--batch-size N |
64 |
批大小。显存不足或内存不足时调小。 |
--epochs N |
35 |
最大训练轮数。可能因达到目标准确率或早停提前结束。 |
--lr VALUE |
1e-3 |
AdamW 初始学习率。 |
--weight-decay V |
2e-4 |
权重衰减系数。 |
--num-workers N |
0 |
数据加载线程数。WSL/Linux 可按机器性能调大。 |
--seed N |
42 |
数据划分和训练随机种子。 |
--width-mult VALUE |
0.6 |
网络宽度倍率,控制通道数和参数量。 |
--patience N |
8 |
验证准确率连续 N 轮不提升时早停。 |
--target-acc VALUE |
0.95 |
验证准确率达到该值后提前停止训练。 |
--python FILE |
python3 |
Linux/WSL 训练脚本使用的 Python 可执行文件。 |
4.3 导出 ncnn 模型
WSL/Linux 主机中使用 pnnx 从 TinyClassifier 训练脚本导出的 TorchScript 转为 ncnn:
conda activate loong
python -m pip install pnnx
./scripts/export_ncnn_host.sh --torchscript models/best.torchscript --img-size 96
输出文件为:
models/best.param
models/best.bin
需要带到开发板的文件:
models/best.param
models/best.bin
models/labels.txt
导出脚本参数:
| 参数 | 默认值 | 说明 |
|---|---|---|
--torchscript FILE |
models/best.torchscript |
主部署链路使用的 TorchScript 模型。 |
--onnx FILE |
无 | 兼容选项,可指定 ONNX 模型;默认仍推荐 TorchScript。 |
--param FILE |
模型同目录 best.param |
输出的 ncnn 结构文件。 |
--bin FILE |
模型同目录 best.bin |
输出的 ncnn 权重文件。 |
--img-size N |
96 |
pnnx 输入尺寸,必须与训练时的 --img-size 一致。 |
--pnnx FILE |
PATH 中的 pnnx |
指定 pnnx 可执行文件路径。 |
| `--fp16 0 | 1` | 0 |
4.4 输入输出约定
TinyClassifier 默认输入尺寸为 1x3x96x96,图像预处理使用 ImageNet 归一化参数:
mean = [0.485, 0.456, 0.406]
std = [0.229, 0.224, 0.225]
输出是一维分类 logits,车端需要对输出做 softmax 或直接取最大 logit 对应类别。
五、板端验证和接入
5.1 板端 ncnn 库配置
当前仓库的板端验证脚本会自动处理 ncnn 运行库,不需要手动修改开发板系统库配置。
example/build_deploy_run.sh 在运行 classifier_ncnn_app 时会:
1. 从 cross_lib/ncnn/lib 查找 libncnn.so*
2. 上传到开发板 /usr/local/ncnn/lib
3. 在远端创建 libncnn.so 和 libncnn.so.1 软链接
4. 运行程序前设置 LD_LIBRARY_PATH=/usr/local/ncnn/lib
如果本机 ncnn 库目录不是默认位置,可以通过参数指定:
cd ../example
./build_deploy_run.sh --app classifier_ncnn_app \
--ncnn-lib-dir ../cross_lib/ncnn/lib \
--remote-ncnn-lib-dir /usr/local/ncnn/lib -- \
--param best.param --bin best.bin --labels labels.txt --image test.jpg --output result.jpg
如果仍遇到 libncnn.so.1: cannot open shared object file,优先检查 --ncnn-lib-dir 是否指向包含 libncnn.so* 的目录,以及远端运行命令是否由 build_deploy_run.sh 启动。
5.2 板端验证分类模型
使用 example/classifier_ncnn_app 在久久派上验证真实目标板分类模型:
cd ../example
./build_deploy_run.sh --app classifier_ncnn_app -- \
--param best.param --bin best.bin --labels labels.txt --image test.jpg --output result.jpg
脚本会自动上传:
tb_cls/models/best.param
tb_cls/models/best.bin
tb_cls/models/labels.txt
tb_cls/dataset 下第一张图片
如果需要指定测试图,请显式传入 --cls-image:
./build_deploy_run.sh --app classifier_ncnn_app --cls-image ../tb_cls/dataset/supplies/xxx.jpg -- \
--param best.param --bin best.bin --labels labels.txt --image test.jpg --output result.jpg
5.3 接入车端策略
车模通过识别赛道中心目标板内容选择通过方式。车端推理应保持和训练一致的预处理:
BGR/RGB通道顺序与实现保持一致。resize到96x96。- 按
ImageNet均值和方差归一化。 ncnn前向推理。- 对输出
logits取最大值或做softmax后取最大概率。
分类结果到通行策略的映射为:
weapon 左侧绕行
supplies 右侧绕行
vechicle 直行压过
分类结果不要单帧直接控制车辆走向。建议使用连续多帧投票或置信度保持机制:
- 连续
N帧类别一致才触发动作。 - 分类置信度低于阈值时保持上一状态或忽略。
- 只在目标板可能出现的赛段启用分类推理。
六、来源和许可证
训练代码来自龙邱资料包中的 LQ_TinyClassifier-master,原始源码声明为 GPL-3.0-or-later。本子项目保留了原始许可证:
tb_cls/vendor/lq_tiny_classifier/LICENSE
训练、评估源码位于:
tb_cls/vendor/lq_tiny_classifier/
原始资料包中的 Windows 一键脚本未作为工程入口保留,当前统一使用 scripts/ 下的包装脚本执行训练和模型转换,避免与本工程的目录结构混淆。
数据集批处理工具位于:
tb_cls/tools/photo_maker/
本次迁移没有拷贝资料包中的 Windows pnnx.exe、样例 AprilTag 图片和 PDF 手册,只保留训练、评估、转换所需的源码、真实目标板数据和当前归档模型。

浙公网安备 33010602011771号