上期回顾:(点此跳转上一期)
本期将介绍如何在 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
包
File: mnist.ipynb
Tensorflow: 2.3.0-dev20200515
Numpy: 1.16.4
Keras: 2.2.4-tf
File: ./data/mnist.npz
MNIST 数据集由 60000 (训练集) + 10000(测试集) 手写字符组成, 每张图片的大小为 , 数据集手动下载地址 http://yann.lecun.com/exdb/mnist/ .
两层卷积 + 一层全连接层
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.9651
2Restored model, accuracy: 96.51%
ok, 至此, 模型已经训练完成, 但是, 准备工作还没有做完, 请接着往下看
最终的目标是将训练好的 Model 在 RT-Thread 系统上能够推理(测试)成功.
本次实验所采用的方法是CMISIS + RT-Thread
, (需要一定的深度学习背景知识), 步骤如下:
转化权重数据为int
型,并保存
使用 CMSIS NN 库复现神经网络, 文件为.c
类文件
导入权重文件和测试样例
推理成功
前提: 已经安装好 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.sh
11(base) Mnist_CMSIS[master] % pkgs --upgrade
12(base) Mnist_CMSIS[master] % scons --menuconfig
13(base) Mnist_CMSIS[master*] % pkgs --update
通过调用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
观察输出情况
成功界面:
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']
但是文件均已经存在
解决:
在./Mnist_CMSIS/SConscript
下面, 改为如图所示
RT-Thread
让物联网终端的开发变得简单、快速,芯片的价值得到最大化发挥。Apache2.0协议,可免费在商业产品中使用,不需要公布源码,无潜在商业风险。
长按二维码,关注我们
转了吗
赞了吗
在看吗