本期将介绍如何在 RT-Thread 操作系统上运行 Mnist Demo(手写数字识别),可支持自己手写数字验证。
准备
- 系统:Windows | Ubuntu 18.04
- 板子:STM32 H743ZI NUCLEO
- RT-T hread运行环境
- MDK 5
- github: https://github.com/Lebhoryi/Edge\_AI/tree/master/Project2-Mnist
MNIST 在人工智能领域中的地位等同于 "Hello world" 在各个编程语言中的地位。
因此, 本次实验将以 MNIST 为主体, 进一步了解人工智能和嵌入式之间的神秘联系。
本期实现的是:
通过CMSIS NN
库复现神经网络, 导入int
型权重文件, 在 RT-Thread 系统中成功实现Mnist 推理.
如何将 Mnist 跑在 RT-Thread 上:
- 从
github
拉取Mnist_CMSIS
或者Mnist_CMSIS.7z
到本地,Mnist_CMSIS
有520M, 建议下载压缩包, 仅66.4M- 运行方法, 二选一:
- Scons
- MDK5 编译
- CMSIS + RT-Thread 推理成功界面
在github上的文件夹中,已经包含实验运行所需要的CMSIS packages, 下载即可运行, 自己新建的工程需要现在 RT-Thread 的
Menuconfig
中打开CMSIS
包
1. PC 训练 Model
File: mnist.ipynb
1.1 PC 端环境
- Tensorflow: 2.3.0-dev20200515
- Numpy: 1.16.4
- Keras: 2.2.4-tf
1.2 数据集
File: ./data/mnist.npz
MNIST 数据集由 60000 (训练集) + 10000(测试集) 手写字符组成, 每张图片的大小为 , 数据集手动下载地址 http://yann.lecun.com/exdb/mn... .
1.3 网络结构
- 两层卷积 + 一层全连接层
1.4 训练模型 & 验证模型
File: ./model/mnist.h5
- 训练模型
- 验证训练模型的准确率
- 保存权重文件
1# save weights 2model.save_weights(model_path / 'model_weights.h5') 3 4# load weights 5model.load_weights(model_path / 'model_weights.h5') 6 7model.compile(optimizer='adam', 8 loss='sparse_categorical_crossentropy', 9 metrics=['accuracy',])10loss, acc = model.evaluate(x_test, y_test)11print("Restored model, accuracy: {:5.2f}%".format(100*acc))
1313/313 [==============================] - 1s 2ms/step - loss: 0.1226 - accuracy: 0.96512Restored model, accuracy: 96.51%
ok, 至此, 模型已经训练完成, 但是, 准备工作还没有做完, 请接着往下看
1.5 Others
最终的目标是将训练好的 Model 在 RT-Thread 系统上能够推理(测试)成功.
本次实验所采用的方法是CMISIS + RT-Thread
, (需要一定的深度学习背景知识), 步骤如下:
- 转化权重数据为
int
型,并保存 - 使用 CMSIS NN 库复现神经网络, 文件为
.c
类文件 - 导入权重文件和测试样例
- 推理成功
2. 选择 CMSIS 软件包
前提: 已经安装好 RT-Thread 所需要的运行环境
1# windows 2> pkgs --upgrade 3# 开启 CMSIS 4> menuconfig 5> pkgs --update 6> scons --target=mdk5 7 8# linux 9# 如果开启不了, 请执行10# (base) Mnist_CMSIS[master*] % source ~/.env/env.sh11(base) Mnist_CMSIS[master] % pkgs --upgrade 12(base) Mnist_CMSIS[master] % scons --menuconfig13(base) Mnist_CMSIS[master*] % pkgs --update
3. 使用 CMSIS 软件包生成网络结构
通过调用CMSIS API, 实现网络结构, 此步骤需要一定的深度学习基础
另外, 在重构的过程中, 均用int
, 而非float
型
在该项目中实现数据传入的方式,目前是较为基础的方法,仅在 main.c 文件中定义一个大小为 784 的数组,储存 28*28 尺寸大小的手写数字图片,格式要求为 Int 型。具体读取图片数据的代码在 mnist.ipynb 中有实现。
由于输入是简单的 28*28 = 784 (一维)数组,可以支持自定义手写数字识别验证。建议先在 mnist.ipynb 中先进行自定义手写数字识别验证。
自定义手写数字保存的图片尽量要求和训练集中的图片类似,如果保存的图片非 28*28 尺寸大小,则可以参考 mnist.ipynb 中的代码,将其 Resize 为 28*28,确保输入的一维数组为 784 大小,和网络输入保持一致
感兴趣的可以阅读源文件,其他文件并无做任何改动
- ./Mnist\_CMSIS/applications/main.c
- ./Mnist\_CMSIS/applications/mnist\_parameters.h
4. 编译 & 烧录
- Windows (推荐使用MDK)
MDK 一键编译一键烧录,通过 Putty 观察输出情况 - Linux (推荐使用Scons)
Scons
编译, 通过STM32 Cube Programmer
烧录,minicom
观察输出情况 - *
成功界面:
5. FAQ
5.1 CMSIS + RT-Thread 找不到 arm_math.h
解决:
windows:
1、勾选DSP 开关
2.增加宏定义
USE\_STDPERIPH\_DRIVER,ARM\_MATH\_CM4,\_\_CC\_ARM,\_\_FPU\_PRESENT, ARM\_MATH\_DSP
- linux:
先解决找不到
math.h
在
./Mnist_CMSIS/packages/CMSIS-latest/SConscript
文件中,第15行, 手动添加DSP
, 新增:CPPPATH = CPPPATH + [cwd + '/CMSIS_5/CMSIS/DSP/Include']
Scons
之后会报这样一个错误:
解决方式如下:
在`./Mnist_CMSIS/board/SConscript` 文件下, 第22行, 改为:
```
CPPDEFINES = ['STM32H743xx','ARM_MATH_CM7','__FPU_PRESENT']
```
5.2 Scons 报错
但是文件均已经存在
解决:
在./Mnist_CMSIS/SConscript
下面, 改为如图所示
推荐阅读
【RT-Thread 开源作品秀】时光空间立方
【嵌入式AI入门日记】将 AI 模型移植到 RT-Thread 上(1)
原文链接:https://mp.weixin.qq.com/s/tjQjmyiFeAPC2NNNz4jx-A
转载已获授权,禁止二转