RISC-V MCU中文社区

TinyMaix上手之第0讲TinyMaix整体介绍

发表于 2023-07-18 17:52:04
0
3132
0

1 TinyMaix简介

TinyMaix是面向单片机(MCUs)的超轻量级神经网络推理库(核心代码<400行),可以让你在任意单片机上运行深度学习模型。

TinyMaix据说是作者两个周末业余时间完成的项目(赞),所以它足够简单,可以在30分钟内走读完代码,可以帮助TinyML新手理解它是怎么运行的。

这一系列将会详细讲解TinyMaix的原理以及基于Nuclei 工具链上TinyMaix的使用情况。

官方库地址:

https://github.com/sipeed/TinyMaix.git

2 TinyMaix的执行流程

其整体流程如下:

简单来说:可以通过keras/tensorflow等训练模型,量化转换为tflite模型(支持INT8/FP32/FP16),tflite模型为flatbuffer格式的,需要转换为tmdl格式(TinyMaix自定义的格式,方便代码解析),然后使用c代码解析模型结构及权重,输入经过一系列计算后得到一个输出。

3 mnist的模型转换与解析

下面以mnist为例,来走一遍模型转换与解析流程。

step1:训练获得模型

假设我们使用keras训练获得mnist_valid.h5,参考《Keras入门第0讲之搭建神经网络的一般步骤》:可以通过https://netron.app/查看其网络结构(截取局部):

step2:模型量化转换为tflite格式

进入TinyMaix的tools目录,执行如下脚本将h5模型全整形量化为mnist_valid_test.tflite:

# 参数1为脚本名:h5_to_tflite.py
# 参数2为输入要转化的h5模型: mnist_valid.h5
# 参数3为输出转化后的tflite模型: mnist_valid_test.tflite
# 参数4为是否全整形量化
# 参数5为样本路径,如果参数4为1,则需准备一些样本,整形量化需要提取一些特征
# 参数6为“0to1”或“n1to1”代码图片归一化的两种不同方式

# Usage: python3 h5_to_tflite.py h5_name tflite_name is_quant quant_dir norm_type
python3 h5_to_tflite.py mnist_valid.h5 mnist_valid_test.tflite 1 quant_img_mnist/ 0to1

step3:将tflite格式转为tmdl格式

# 参数1为脚本名:tflite2tmdl.py
# 参数2为输入要转化的tflite模型: mnist_valid_test.tflite
# 参数3为输出转化后的tmdl模型: mnist_valid_test_int8.tmdl
# 参数4为是数据类型(支持:fp32, int8, int16, fp16, fp8_143, fp8_152)
# 参数5为输出是否反量化
# 参数6为in_dims输入图像尺寸,多维度用逗号分割
# 参数7为out_dims,为输出维度
# 参数8为大端小端,0为小端(默认),1为大端

# Usage: python3 tflite2tmdl.py tflite_name tmdl_name mdl_type out_deq in_dims out_dims [is_be]
python3 tflite2tmdl.py mnist_valid_test.tflite mnist_valid_test_int8.tmdl int8 1 28,28,1 10

执行脚本后,得到mnist_valid_test_int8.tmdl以及模型序列化数组mnist_valid_test_int8.h,便于嵌入式中使用。

step4:将模型h文件移植到嵌入式环境中,并测试

这一步使用的nuclei提供的工具进行测试的,nuclei提供了工具链以及qemu测试环境,下一篇讲述怎么使用nuclei qemu环境运行。

准备输入数据:

将其转为数组,注意,这个脚本转换ndim为2维的图像有问题,需要简单修改一下脚本(脚本比较简单,不再赘述):

python3 img2c.py quant_img_mnist/11.bmp

修改 TinyMaix/examples/mnist 用例,替换模型文件头文件以及测试数据,然后编译并在qemu上运行(nuclei 环境搭建见下一篇)。

在命令行下运行,日志如下:

mdl_type=0 (int8))
out_deq=1
input_cnt=1, output_cnt=1, layer_cnt=6
input 3dims: (28, 28, 1)
output 1dims: (1, 1, 10)
main buf size 1464; sub buf size 0
//Note: PARAM is layer param size, include align padding

Idx     Layer           outshape       inoft   outoft PARAM   MEMOUT OPS
---     Input           28, 28, 1     -       0       0       784     0
000     Conv2D           13, 13, 4     0       784     72     676     6084
001     Conv2D           6, 6, 8     784     0       352     288     10368
002     Conv2D           2, 2, 16     0       1400   1280   64     4608
003     GAP               1, 1, 16     1400   0       0       16     64
004     FC               1, 1, 10     0       1448   240     10     160
005     Softmax           1, 1, 10     1448   0       0       10     60

Total param ~1.9 KB, OPS ~0.02 MOPS, buffer 1.4 KB

===tm_run start 664 us, finish 1268 us
===tm_run use 0.604 ms
0: 0.004
1: 0.000
2: 0.000
3: 0.000
4: 0.000
5: 0.004
6: 0.996
7: 0.000
8: 0.000
9: 0.000
### Predict output is: Number 6, prob 0.996

可见预测为数字6。

参考:

  1. TinyMaix README.md

  2. 使用TinyMaix识别手写数字

  3. 单片机也能玩神经网络-TinyMaix实测开源

  4. xddcore/OpenNNA2.0: OpenNNA2.0,一个基于C语言(C99)的开源神经网络推理框架 (github.com)


喜欢0
用户评论
sureZ-ok

sureZ-ok 实名认证

懒的都不写签名

积分
问答
粉丝
关注
专栏作者
  • RV-STAR 开发板
  • RISC-V处理器设计系列课程
  • 培养RISC-V大学土壤 共建RISC-V教育生态
RV-STAR 开发板