结合RT-Thread实现MNIST识别Demo

文章目录

  • 0x00 Prepares
  • 0x01 PC 训练 Model
    • 1.1 PC 端环境
    • 1.2 数据集
    • 1.3 网络结构
    • 1.4 训练模型 & 验证模型
    • 1.5 Others
  • 0x02 打开 CMSIS 包
  • 0x03 CMSIS 重构网络结构
  • 0x04 编译 & 烧录
  • 0x05 FAQ
    • 5.1 CMSIS + RTT 找不到 `arm_math.h`
    • 5.2 scons 报错

0x00 Prepares

  • 系统: Windows | Ubuntu 18.04
  • 板子: STM32 H743ZI NUCLEO
  • RTT 运行环境
  • MDK 5
  • github: https://github.com/Lebhoryi/Edge_AI/tree/master/Project2-Mnist

MNIST 在人工智能领域中的地位等同于 “Hello world” 在各个编程语言中的地位.

因此, 本次实验将以 MNIST 为主体, 进一步了解人工智能和嵌入式之间的神秘联系,

本期实现的是:

​ 通过CMSIS NN 库复现神经网络, 导入int 型权重文件, 在 RTT 系统中成功实现Mnist 推理.


如何将 Mnist 跑在 RTT 上:

  1. github 拉取Mnist_CMSIS 或者 Mnist_CMSIS.7z 到本地, Mnist_CMSIS 有520M, 建议下载压缩包, 仅66.4M

  2. 运行方法, 二选一:

    • scons
    • MDK5 编译
  3. CMSIS + RTT 推理成功界面

结合RT-Thread实现MNIST识别Demo_第1张图片

在github上的文件夹中,已经包含实验运行所需要的CMSIS packages, 下载即可运行, 自己新建的工程需要现在 RTT 的 Menuconfig 中打开CMSIS

0x01 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(测试集) 手写字符组成, 每张图片的大小为 $ 28 * 28 $, 数据集手动下载地址 http://yann.lecun.com/exdb/mnist/ .

结合RT-Thread实现MNIST识别Demo_第2张图片

1.3 网络结构

  • 两层卷积 + 一层全连接层

结合RT-Thread实现MNIST识别Demo_第3张图片

1.4 训练模型 & 验证模型

File: ./model/mnist.h5

  • 训练模型

结合RT-Thread实现MNIST识别Demo_第4张图片

  • 验证训练模型的准确率

结合RT-Thread实现MNIST识别Demo_第5张图片

  • 保存权重文件
# save weights
model.save_weights(model_path / 'model_weights.h5')

# load weights
model.load_weights(model_path / 'model_weights.h5')

model.compile(optimizer='adam',
             loss='sparse_categorical_crossentropy',
             metrics=['accuracy',])
loss, acc = model.evaluate(x_test, y_test)
print("Restored model, accuracy: {:5.2f}%".format(100*acc))
313/313 [==============================] - 1s 2ms/step - loss: 0.1226 - accuracy: 0.9651
Restored model, accuracy: 96.51%

ok, 至此, 模型已经训练完成, 但是, 准备工作还没有做完, 请接着往下看

1.5 Others

最终的目标是将训练好的 Model 在 RT-Thread 系统上能够推理(测试)成功.

本次实验所采用的方法是CMISIS + RTT, (需要一定的深度学习背景知识), 步骤如下:

  1. 转化权重数据为int 型,并保存
  2. 使用 CMSIS NN 库复现神经网络, 文件为.c 类文件
  3. 导入权重文件和测试样例
  4. 推理成功

0x02 打开 CMSIS 包

前提: 已经安装好 RT-Thread 所需要的运行环境

# windows
> pkgs --upgrade
# 开启 CMSIS
> menuconfig
> pkgs --update
> scons --target=mdk5

# linux
# 如果开启不了, 请执行
# (base) Mnist_CMSIS[master*] % source ~/.env/env.sh
(base) Mnist_CMSIS[master] % pkgs --upgrade 
(base) Mnist_CMSIS[master] % scons --menuconfig
(base) Mnist_CMSIS[master*] % pkgs --update

结合RT-Thread实现MNIST识别Demo_第6张图片

结合RT-Thread实现MNIST识别Demo_第7张图片

结合RT-Thread实现MNIST识别Demo_第8张图片

结合RT-Thread实现MNIST识别Demo_第9张图片

0x03 CMSIS 重构网络结构

通过调用CMSIS API, 实现网络重构, 此步骤需要一定的深度学习基础

结合RT-Thread实现MNIST识别Demo_第10张图片

另外, 在重构的过程中, 均用int, 而非float

结合RT-Thread实现MNIST识别Demo_第11张图片

感兴趣的可以阅读源文件

  • ./Mnist_CMSIS/applications/main.c
  • ./Mnist_CMSIS/applications/mnist_parameters.h

其他文件并无做任何改动

0x04 编译 & 烧录

  • Windows (推荐使用MDK)

    MDK 一键编译一键烧录, 时间略久, 通过 Putty 观察输出情况

  • Linux (推荐使用scons)

    scons 编译, 通过STM32 Cube Programmer 烧录, minicom 观察输出情况


成功界面:

结合RT-Thread实现MNIST识别Demo_第12张图片

0x05 FAQ

5.1 CMSIS + RTT 找不到 arm_math.h

结合RT-Thread实现MNIST识别Demo_第13张图片


解决:

  • windows:

    1. 勾选DSP 开关

    结合RT-Thread实现MNIST识别Demo_第14张图片

    1. 增加宏定义

      USE_STDPERIPH_DRIVER,ARM_MATH_CM4,__CC_ARM,__FPU_PRESENT, ARM_MATH_DSP

    结合RT-Thread实现MNIST识别Demo_第15张图片

  • linux:

    1. 先解决找不到math.h

      ./Mnist_CMSIS/packages/CMSIS-latest/SConscript 文件中,第15行, 手动添加DSP, 新增:

      CPPPATH = CPPPATH + [cwd + '/CMSIS_5/CMSIS/DSP/Include']
      

      结合RT-Thread实现MNIST识别Demo_第16张图片

    2. scons 之后会报这样一个错误:

      结合RT-Thread实现MNIST识别Demo_第17张图片

      结合RT-Thread实现MNIST识别Demo_第18张图片

      解决方式如下:

      ./Mnist_CMSIS/board/SConscript 文件下, 第22行, 改为:

      CPPDEFINES = ['STM32H743xx','ARM_MATH_CM7','__FPU_PRESENT']
      

      结合RT-Thread实现MNIST识别Demo_第19张图片

5.2 scons 报错

但是文件均已经存在

结合RT-Thread实现MNIST识别Demo_第20张图片

解决:

./Mnist_CMSIS/SConscript 下面, 改为如图所示

结合RT-Thread实现MNIST识别Demo_第21张图片

你可能感兴趣的:(EmbeddedSystem)