• 龙芯2k0300 - 智能车走马观碑组目标分类算法


    tb_cls 是目标板轻量分类子项目,移植自龙邱 TinyClassifier 方案,用于管理真实目标板三大类分类数据、训练产物、模型转换和板端部署。

    需要先明确一点:TinyClassifier 是图像分类模型,不是目标检测模型。它只判断输入图或裁剪 ROI 属于 weaponsuppliesvechicle 中的哪一类,不输出目标框。当前数据集里的图片都是无框图片,标签来自图片所在文件夹。

    WSL/Linux 主机 GPU/CPU 训练 -> 导出 TorchScript -> WSL/Linux 主机 pnnx 转 ncnn -> 久久派/龙芯板端分类推理
    

    主机侧先得到 TorchScript,再用 pnnx 转成 ncnnparam/bintb_cls 只保留 TorchScript -> pnnx -> ncnn 这一条部署链路。

    一、目录分层规则

    1.1 统一目录结构

    tb_cls 采用单一目标板分类工程结构,配置、真实数据、模型和输出都直接放在根目录对应位置:

    ├── configs
    │   ├── README.md
    │   └── labels.txt
    ├── dataset
    │   ├── dataset.zip
    │   ├── supplies
    │   ├── vechicle
    │   └── weapon
    ├── models
    │   ├── README.md
    │   ├── best.bin
    │   ├── best.param
    │   ├── best.torchscript
    │   ├── best_model.pt
    │   ├── labels.txt
    │   └── metrics.json
    ├── outputs
    │   └── train
    

    tb_cls 的标签来自文件夹名,数据目录是 ImageFolder 结构。当前三类目录为:

    dataset/
    ├── supplies/
    ├── vechicle/
    └── weapon/
    

    类别顺序由 torchvision.datasets.ImageFolder 按文件夹名字典序生成,训练结束后会写入 labels.txt。当前 labels.txt 顺序为:

    supplies
    vechicle
    weapon
    

    车端解析分类结果时必须使用同一份 labels.txt。其中 vechicle 对应交通工具类。当前仓库中已有模型可能仍带有旧版 labels.txt,以重新训练后生成的 models/labels.txtconfigs/labels.txt 为准。

    仓库提交时只需要保留 dataset/dataset.zip,解压后的图片目录由 .gitignore 忽略。训练脚本会在发现三类图片目录不存在时,自动解压 dataset/dataset.zip

    二、环境准备和已有模型

    2.1 Linux/WSL 训练环境

    requirements.txt 是从 conda env: loong 导出的固定版本依赖,建议使用 Python 3.10 的独立环境。不要直接使用系统自带的 Python 3.14 安装本文件,因为 numpytorch 等固定版本可能没有对应兼容包。

    如果系统还没有 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.8PyTorch

    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.param
    models/best.bin
    models/labels.txt
    

    configs/labels.txt 是同一份类别顺序文件,车端推理显示类别时必须按该顺序解析输出。

    三、真实目标板数据集

    3.1 数据内容

    当前 dataset/ 目录下的数据就是真实目标板数据。图片内容来自赛道中心目标板,按业务含义分成三个大类,当前训练集已经整理为 64x64 图片。

    weapon    武器:枪支、爆炸物、匕首、警棍、消防斧
    supplies 物资:急救包、手电筒、对讲机、防弹背心、望远镜、头盔
    vechicle   交通工具:消防车、救护车、装甲车、摩托车
    

    所有图片都是无框图片,不包含检测框标注。训练时只使用图片所在的大类文件夹作为分类标签,不区分大类内部的小类编号。大类目录下的图片已经平铺,文件名只作为样本编号,不参与标签解析。

    3.2 输入边界

    TinyClassifier 只做整图分类,不做检测框定位。用于智能车目标板时,建议输入已经裁剪好的目标板 ROI,而不是整张赛道图。

    可选裁剪方式:

    1. 目标板出现在固定区域时,直接从摄像头画面裁剪固定 ROI
    2. 目标板位置有轻微变化时,先用颜色、边缘或几何规则定位候选区域,再送入分类模型。
    3. 如果目标板位置完全不稳定,需要额外实现轻量定位或裁剪逻辑。

    3.3 数据目录

    当前压缩包解压后按三大类建立文件夹:

    dataset/
    ├── dataset.zip
    ├── supplies/
    ├── vechicle/
    └── weapon/
    

    如果提交仓库,保留:

    dataset/dataset.zip
    

    不要提交解压后的 dataset/supplies/dataset/vechicle/dataset/weapon/ 图片目录。运行训练脚本时会自动检查并解压。

    四、训练和导出

    4.1 模型结构

    TinyClassifier 是轻量级卷积分类网络,主体由普通卷积、深度可分离卷积、全局池化和全连接分类头组成。当前计划使用 64x64 输入训练,输出类别数由 dataset/ 下的三类目录自动决定。

    网络结构概览:

    输入 1x3x64x64
    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(64x64)
    RandomHorizontalFlip
    RandomRotation(10)
    ColorJitter
    ImageNet Normalize
    

    验证、测试和导出推理只使用 ResizeToTensorImageNet Normalize

    4.2 训练并归档模型

    4.2.1 WSL/Linux GPU/CPU 训练

    WSL/Linux 中可运行:

    ./scripts/train_classifier_host.sh --run-name exp_cls_64 --img-size 64
    

    常用参数示例:

    ./scripts/train_classifier_host.sh \
      --run-name exp_cls_64 \
      --img-size 64 \
      --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
    ├── labels.txt
    └── metrics.json
    

    包装脚本会把关键产物同步到:

    models/best_model.pt
    models/best.torchscript
    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 64 输入图片尺寸。当前 64x64 数据训练时使用 64;训练、导出和板端推理必须保持一致。
    --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 本地验证单张图片识别结果

    训练结束并归档到 models/ 后,可以先在主机上拿一张图片做单图识别,确认模型、标签顺序和预处理尺寸是否一致:

    python vendor/lq_tiny_classifier/predict_image.py \
      --checkpoint models/best_model.pt \
      --image dataset/supplies/000001.jpg \
      --img-size 64
    

    输出示例:

    image: dataset/supplies/000001.jpg
    prediction: supplies (0.9821)
    topk:
      supplies: 0.9821
      weapon: 0.0113
      vechicle: 0.0066
    

    如果要验证其他类别,替换 --image 即可,例如:

    python vendor/lq_tiny_classifier/predict_image.py \
      --checkpoint models/best_model.pt \
      --image dataset/weapon/000001.jpg \
      --img-size 64
    

    这里使用的是训练 checkpoint best_model.pt,预处理与训练/测试一致:Resize(64x64)ToTensorImageNet Normalize。如果单图预测类别明显不对,优先检查三点:图片是否来自正确的大类目录、--img-size 是否和训练一致、models/labels.txt 是否为本次训练生成。

    4.4 导出 ncnn 模型

    WSL/Linux 主机中使用 pnnxTinyClassifier 训练脚本导出的 TorchScript 转为 ncnn

    ./scripts/export_ncnn_host.sh --torchscript models/best.torchscript --img-size 64
    

    输出文件为:

    models/best.param
    models/best.bin
    

    需要带到开发板的文件:

    models/best.param
    models/best.bin
    models/labels.txt
    

    导出脚本参数:

    参数 默认值 说明
    --torchscript FILE models/best.torchscript 主部署链路使用的 TorchScript 模型。
    --param FILE 模型同目录 best.param 输出的 ncnn 结构文件。
    --bin FILE 模型同目录 best.bin 输出的 ncnn 权重文件。
    --img-size N 64 pnnx 输入尺寸,必须与训练时的 --img-size 一致。当前 64x64 模型导出时使用 64
    --pnnx FILE PATH 中的 pnnx 指定 pnnx 可执行文件路径。
    --fp16 0 1 0

    4.5 输入输出约定

    当前 64x64 训练方案的输入尺寸为 1x3x64x64,图像预处理使用 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 接入车端策略

    车模通过识别赛道中心目标板内容选择通过方式。车端推理应保持和训练一致的预处理:

    1. BGR/RGB 通道顺序与实现保持一致。
    2. resize64x64
    3. ImageNet 均值和方差归一化。
    4. ncnn 前向推理。
    5. 对输出 logits 取最大值或做 softmax 后取最大概率。

    分类结果到通行策略的映射为:

    weapon    左侧绕行
    supplies 右侧绕行
    vechicle   直行压过
    

    分类结果不要单帧直接控制车辆走向。建议使用连续多帧投票或置信度保持机制:

    1. 连续 N 帧类别一致才触发动作。
    2. 分类置信度低于阈值时保持上一状态或忽略。
    3. 只在目标板可能出现的赛段启用分类推理。

    六、来源和许可证

    训练代码来自龙邱资料包中的 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 手册,只保留训练、评估、转换所需的源码、真实目标板数据和当前归档模型。

    亲爱的读者和支持者们,自动博客加入了打赏功能,陆陆续续收到了各位老铁的打赏。在此,我想由衷地感谢每一位对我们博客的支持和打赏。你们的慷慨与支持,是我们前行的动力与源泉。

    日期姓名金额
    2023-09-06*源19
    2023-09-11*朝科88
    2023-09-21*号5
    2023-09-16*真60
    2023-10-26*通9.9
    2023-11-04*慎0.66
    2023-11-24*恩0.01
    2023-12-30I*B1
    2024-01-28*兴20
    2024-02-01QYing20
    2024-02-11*督6
    2024-02-18一*x1
    2024-02-20c*l18.88
    2024-01-01*I5
    2024-04-08*程150
    2024-04-18*超20
    2024-04-26.*V30
    2024-05-08D*W5
    2024-05-29*辉20
    2024-05-30*雄10
    2024-06-08*:10
    2024-06-23小狮子666
    2024-06-28*s6.66
    2024-06-29*炼1
    2024-06-30*!1
    2024-07-08*方20
    2024-07-18A*16.66
    2024-07-31*北12
    2024-08-13*基1
    2024-08-23n*s2
    2024-09-02*源50
    2024-09-04*J2
    2024-09-06*强8.8
    2024-09-09*波1
    2024-09-10*口1
    2024-09-10*波1
    2024-09-12*波10
    2024-09-18*明1.68
    2024-09-26B*h10
    2024-09-3010
    2024-10-02M*i1
    2024-10-14*朋10
    2024-10-22*海10
    2024-10-23*南10
    2024-10-26*节6.66
    2024-10-27*o5
    2024-10-28W*F6.66
    2024-10-29R*n6.66
    2024-11-02*球6
    2024-11-021*鑫6.66
    2024-11-25*沙5
    2024-11-29C*n2.88
    2024-12-27*鱼5
    2024-12-30*心2.88
    2025-1-2*新6
    2025-1-6w*h6.66
    2025-1-25*光10
    2025-1-27*松10
    2025-2-8M*X18.88
    2025-2-8*H6.66
    2025-3-24S*g20
    2025-4-25*虎6.66
    2025-6-29c*n0.88
    2025-7-5B*n6.66
    2025-7-12*林10
    2025-7-31t*a10
    2025-8-30*钊6.66
    2025-9-22*爷6.66
    2026-2-2小*6.66
    2026-2-24L*o100
    2026-3-24t*s66.6

     

  • 相关阅读:
    [ 英语 ] 马斯克抱水槽“入主”推特总部中那句 Let that sink in 到底是什么梗?
    [Spring Cloud] Open Feign---扩展
    curl 和 wget 的使用和区别
    【JAVA刷题初阶】刷爆力扣第十一弹——二叉树
    根据3d框的八个顶点坐标,求他的中心点,长宽高和yaw值(Python)
    编译源码报build/make/core/artifact_path_requirements.mk:26: error: Build failed.解决方法
    规则漂移
    神经辐射场 (NeRF) 概念
    docker发布镜像到阿里云与私服
    ChatGPT在生态保护和可持续发展中的潜在作用如何?
  • 原文地址:https://www.cnblogs.com/zyly/p/20098480