当你第一次拿到RK3576开发板时,可能会被这个小巧的硬件所震撼——它竟然能在边缘端运行复杂的深度学习模型。作为一名长期从事嵌入式AI开发的工程师,我清楚地记得第一次成功部署YOLOv5模型时的兴奋。本文将带你完整走一遍这个流程,从数据集准备到最终在开发板上运行口罩检测模型,每个步骤都会分享我踩过的坑和验证过的解决方案。
在开始之前,我们需要准备好两个环境:训练环境和部署环境。训练环境通常在性能更强的PC或服务器上,而部署环境则是我们的RK3576开发板。
推荐使用Ubuntu 20.04系统,这是目前最稳定的深度学习开发环境之一。以下是需要安装的核心组件:
bash复制# 安装Python环境
sudo apt update
sudo apt install python3.8 python3-pip
# 安装CUDA和cuDNN (如果使用NVIDIA GPU)
wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/cuda-ubuntu2004.pin
sudo mv cuda-ubuntu2004.pin /etc/apt/preferences.d/cuda-repository-pin-600
sudo apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/3bf863cc.pub
sudo add-apt-repository "deb https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/ /"
sudo apt install cuda-11-3
注意:CUDA版本需要与你的GPU驱动兼容,建议先检查GPU驱动版本再选择对应的CUDA版本
RKNN Toolkit2是Rockchip提供的模型转换工具,支持将主流框架训练的模型转换为RK3576可运行的格式。安装步骤如下:
bash复制docker load --input rknn-toolkit2-v2.3.0-cp38-docker.tar.gz
bash复制docker run -t -i --privileged -v /dev/bus/usb:/dev/bus/usb rknn-toolkit2:2.3.0-cp38 /bin/bash
口罩检测作为一个典型的二分类目标检测任务,数据集质量直接影响模型性能。我从公开数据集中筛选了约5000张标注良好的图片,包含各种场景下的口罩佩戴情况。
原始数据集通常需要重新组织为YOLOv5要求的格式:
code复制mask_dataset/
├── images/
│ ├── train/
│ └── val/
└── labels/
├── train/
└── val/
使用以下Python脚本可以自动完成这种转换:
python复制import os
import shutil
from sklearn.model_selection import train_test_split
def organize_dataset(raw_dir, output_dir):
# 创建目录结构
os.makedirs(f"{output_dir}/images/train", exist_ok=True)
os.makedirs(f"{output_dir}/images/val", exist_ok=True)
os.makedirs(f"{output_dir}/labels/train", exist_ok=True)
os.makedirs(f"{output_dir}/labels/val", exist_ok=True)
# 分割训练集和验证集
all_files = [f for f in os.listdir(raw_dir) if f.endswith('.jpg')]
train_files, val_files = train_test_split(all_files, test_size=0.2)
# 复制文件
for file in train_files:
base_name = os.path.splitext(file)[0]
shutil.copy(f"{raw_dir}/{file}", f"{output_dir}/images/train/{file}")
shutil.copy(f"{raw_dir}/{base_name}.txt", f"{output_dir}/labels/train/{base_name}.txt")
# 同上处理验证集...
在YOLOv5的配置文件中,可以启用以下增强策略提升模型鲁棒性:
yaml复制# data/mask.yaml
train: ../mask_dataset/images/train
val: ../mask_dataset/images/val
# 增强参数
augmentations:
hsv_h: 0.015 # 色调变化
hsv_s: 0.7 # 饱和度变化
hsv_v: 0.4 # 明度变化
degrees: 10 # 旋转角度
translate: 0.1 # 平移比例
scale: 0.5 # 缩放比例
shear: 0.0 # 剪切变换
perspective: 0.0 # 透视变换
flipud: 0.0 # 上下翻转概率
fliplr: 0.5 # 左右翻转概率
YOLOv5提供了多种规模的预训练模型,对于RK3576这样的边缘设备,建议从YOLOv5s开始:
| 模型 | 参数量(M) | 推理速度(ms) | mAP@0.5 |
|---|---|---|---|
| YOLOv5s | 7.2 | 15 | 0.56 |
| YOLOv5m | 21.2 | 28 | 0.63 |
| YOLOv5l | 46.5 | 53 | 0.67 |
针对口罩检测任务,我们可以简化模型输出:
python复制# models/yolov5s.yaml
nc: 1 # 只有口罩一个类别
depth_multiple: 0.33
width_multiple: 0.50
anchors:
- [10,13, 16,30, 33,23] # P3/8
- [30,61, 62,45, 59,119] # P4/16
- [116,90, 156,198, 373,326] # P5/32
启动训练时,推荐使用以下参数组合:
bash复制python train.py --img 640 --batch 32 --epochs 100 --data mask.yaml \
--cfg models/yolov5s.yaml --weights '' --name mask_detection \
--cache --device 0 --optimizer AdamW --patience 10
训练过程中需要监控的关键指标:
提示:如果显存不足,可以减小--batch-size或使用--img 320降低输入分辨率
YOLOv5提供了方便的导出脚本:
bash复制python export.py --weights runs/train/mask_detection/weights/best.pt \
--include onnx --imgsz 640 --simplify --opset 12
关键参数说明:
--simplify:启用ONNX简化,减少模型复杂度--opset 12:指定ONNX算子集版本--imgsz 640:保持与训练时相同的输入尺寸创建转换脚本convert_rknn.py:
python复制from rknn.api import RKNN
def convert_onnx_to_rknn():
rknn = RKNN(verbose=True)
# 模型配置
rknn.config(
target_platform='rk3576',
mean_values=[[0, 0, 0]],
std_values=[[255, 255, 255]],
optimization_level=3,
quantize_input_node=True
)
# 加载ONNX模型
ret = rknn.load_onnx(model='best.onnx')
if ret != 0:
print('Load model failed!')
exit(ret)
# 量化模型
ret = rknn.build(do_quantization=True, dataset='./dataset.txt')
if ret != 0:
print('Build model failed!')
exit(ret)
# 导出RKNN模型
ret = rknn.export_rknn('./mask_detection.rknn')
rknn.release()
将生成的RKNN模型上传到开发板后,可以使用Rockchip提供的C++接口进行推理。以下是核心代码片段:
cpp复制#include <rknn_api.h>
int init_model(const char* model_path) {
rknn_context ctx;
int ret = rknn_init(&ctx, model_path, 0, 0, NULL);
if (ret < 0) {
printf("rknn_init fail! ret=%d\n", ret);
return -1;
}
// 获取模型输入输出信息
rknn_input_output_num io_num;
ret = rknn_query(ctx, RKNN_QUERY_IN_OUT_NUM, &io_num, sizeof(io_num));
if (ret != RKNN_SUCC) {
printf("rknn_query fail! ret=%d\n", ret);
return -1;
}
return 0;
}
部署时常见的性能优化手段:
rknn_set_internal_mem启用内部内存当发现量化后模型精度下降明显时,可以尝试:
--quantized_dtype asymmetric_affine调整量化策略rknn.config()中调整quantized_method参数通过以下方法可以显著提升推理速度:
| 优化方法 | 预期加速比 | 适用场景 |
|---|---|---|
| 模型剪枝 | 1.2-1.5x | 冗余通道较多的模型 |
| 权重量化 | 2-3x | 所有模型 |
| 算子融合 | 1.1-1.3x | 有连续卷积操作的模型 |
| 内存优化 | 1.2x | 大输入尺寸场景 |
问题1:模型在PC上精度正常,但在开发板上检测效果差
do_quantization=False)排查量化误差问题2:推理时出现内存不足错误
rknn_set_internal_mem减少内存占用问题3:模型转换成功但推理结果全为零
在完成所有部署后,我强烈建议建立一个完整的测试流程:从图像采集、预处理、推理到结果可视化,确保每个环节都稳定可靠。在我的实际项目中,这种端到端的验证帮助发现了多个潜在问题,比如内存泄漏和线程同步问题。