【嵌入式AI入门日记】将 AI 模型移植到 RT-Thread 上(2)

上期回顾:(点此跳转上一期)

本期将介绍如何在 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 上:

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

  2. 运行方法, 二选一:

  • Scons

  • MDK5 编译

  • CMSIS + RT-Thread 推理成功界面

  • 【嵌入式AI入门日记】将 AI 模型移植到 RT-Thread 上(2)_第1张图片

    在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/mnist/ .

    【嵌入式AI入门日记】将 AI 模型移植到 RT-Thread 上(2)_第2张图片

    1.3 网络结构

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

    【嵌入式AI入门日记】将 AI 模型移植到 RT-Thread 上(2)_第3张图片

    1.4 训练模型 & 验证模型

    File: ./model/mnist.h5

    • 训练模型

    【嵌入式AI入门日记】将 AI 模型移植到 RT-Thread 上(2)_第4张图片
    • 验证训练模型的准确率

    【嵌入式AI入门日记】将 AI 模型移植到 RT-Thread 上(2)_第5张图片
    • 保存权重文件

     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, 至此, 模型已经训练完成, 但是, 准备工作还没有做完, 请接着往下看

    1.5 Others

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

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

    1. 转化权重数据为int 型,并保存

    2. 使用 CMSIS NN 库复现神经网络, 文件为.c 类文件

    3. 导入权重文件和测试样例

    4. 推理成功

    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.sh
    11(base) Mnist_CMSIS[master] % pkgs --upgrade 
    12(base) Mnist_CMSIS[master] % scons --menuconfig
    13(base) Mnist_CMSIS[master*] % pkgs --update
    
    【嵌入式AI入门日记】将 AI 模型移植到 RT-Thread 上(2)_第6张图片 【嵌入式AI入门日记】将 AI 模型移植到 RT-Thread 上(2)_第7张图片 【嵌入式AI入门日记】将 AI 模型移植到 RT-Thread 上(2)_第8张图片 【嵌入式AI入门日记】将 AI 模型移植到 RT-Thread 上(2)_第9张图片

    3. 使用 CMSIS 软件包生成网络结构

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

    【嵌入式AI入门日记】将 AI 模型移植到 RT-Thread 上(2)_第10张图片

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

    【嵌入式AI入门日记】将 AI 模型移植到 RT-Thread 上(2)_第11张图片


    在该项目中实现数据传入的方式,目前是较为基础的方法,仅在 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 观察输出情况


    成功界面:

    【嵌入式AI入门日记】将 AI 模型移植到 RT-Thread 上(2)_第12张图片

    5. FAQ

    5.1 CMSIS + RT-Thread 找不到 arm_math.h

    【嵌入式AI入门日记】将 AI 模型移植到 RT-Thread 上(2)_第13张图片

    解决:

    windows:

    1、勾选DSP 开关

    • 【嵌入式AI入门日记】将 AI 模型移植到 RT-Thread 上(2)_第14张图片【嵌入式AI入门日记】将 AI 模型移植到 RT-Thread 上(2)_第15张图片

    2.增加宏定义

    USE_STDPERIPH_DRIVER,ARM_MATH_CM4,__CC_ARM,__FPU_PRESENT, ARM_MATH_DSP

    • linux:

    1. 先解决找不到math.h

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

      CPPPATH = CPPPATH + [cwd + '/CMSIS_5/CMSIS/DSP/Include']
      
      【嵌入式AI入门日记】将 AI 模型移植到 RT-Thread 上(2)_第16张图片
    2. Scons 之后会报这样一个错误:

      【嵌入式AI入门日记】将 AI 模型移植到 RT-Thread 上(2)_第17张图片【嵌入式AI入门日记】将 AI 模型移植到 RT-Thread 上(2)_第18张图片

      解决方式如下:

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

      CPPDEFINES = ['STM32H743xx','ARM_MATH_CM7','__FPU_PRESENT']
      
      【嵌入式AI入门日记】将 AI 模型移植到 RT-Thread 上(2)_第19张图片

    5.2 Scons 报错

    但是文件均已经存在

    【嵌入式AI入门日记】将 AI 模型移植到 RT-Thread 上(2)_第20张图片

    解决:

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

    【嵌入式AI入门日记】将 AI 模型移植到 RT-Thread 上(2)_第21张图片

    RT-Thread


    让物联网终端的开发变得简单、快速,芯片的价值得到最大化发挥。Apache2.0协议,可免费在商业产品中使用,不需要公布源码,无潜在商业风险。

    长按二维码,关注我们

    【嵌入式AI入门日记】将 AI 模型移植到 RT-Thread 上(2)_第22张图片

    转了吗

    【嵌入式AI入门日记】将 AI 模型移植到 RT-Thread 上(2)_第23张图片

    赞了吗

    【嵌入式AI入门日记】将 AI 模型移植到 RT-Thread 上(2)_第24张图片

    在看吗

    你可能感兴趣的:(【嵌入式AI入门日记】将 AI 模型移植到 RT-Thread 上(2))