TinyMaix是面向单片机(MCUs)的超轻量级神经网络推理库(核心代码<400行),可以让你在任意单片机上运行深度学习模型。
TinyMaix据说是作者两个周末业余时间完成的项目(赞),所以它足够简单,可以在30分钟内走读完代码,可以帮助TinyML新手理解它是怎么运行的。
这一系列将会详细讲解TinyMaix的原理以及基于Nuclei 工具链上TinyMaix的使用情况。
官方库地址:
https://github.com/sipeed/TinyMaix.git
其整体流程如下:
简单来说:可以通过keras/tensorflow等训练模型,量化转换为tflite模型(支持INT8/FP32/FP16),tflite模型为flatbuffer格式的,需要转换为tmdl格式(TinyMaix自定义的格式,方便代码解析),然后使用c代码解析模型结构及权重,输入经过一系列计算后得到一个输出。
下面以mnist为例,来走一遍模型转换与解析流程。
step1:训练获得模型
假设我们使用keras训练获得mnist_valid.h5,参考《Keras入门第0讲之搭建神经网络的一般步骤》:可以通过查看其网络结构(截取局部):
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。
参考: