CMSIS-NN是什么?
官方的解释是:
CMSIS NN software library is a collection of efficient neural network kernels developed to maximize the performance and minimize the memory footprint of neural networks on Arm Cortex-M processors.
翻译一下就是:
CMSIS NN 软件库是一组高效的神经网络核(函数),旨在最大限度地提高 Arm Cortex-M 处理器上神经网络的性能并最大限度地减少内存占用。
CMSIS-NN是一个计算库,它向上提供了神经网络(NN)计算接口,实现了神经网络计算的硬件加速。它内部实现了纯CPU计算、DSP计算、MVE计算,屏蔽了底层硬件的具体细节,降低了编程难度。
为什么移植CMSIS-NN v6.0.0版本?
1
CMSIS-NN核心特性
总结一下官方的介绍,可以知道CMSIS-NN库的核心特性:
专为Cortex-M处理器开发;
神经网络计算函数;
最大化性能;
最小化内存占用
2
CMSIS-NN的硬件和软件支持
除此之外,CMSIS-NN库还有几点也是值得关注的:
支持DSP扩展的处理器,使用SIMD优化,例如Cortex-M4核;
支持ARM的Heilum技术的处理器,使用M核向量扩展(MVE,M-profile Vector Extension)进行优化,例如 Cortex-M55 或 Cortex-M85;
MVE扩展恰好是ARM Cortex-M85内置的;
VisionBoard主控芯片瑞萨RA8D1的CPU核正是ARM Cortex-M85;
CMSIS-NN可以作为TensorFlow Lite for Microcontroller的后端实现;
3
CMSIS-NN核心特性
CMSIS-NN v6.0.0版本的发布说明中,介绍了新特性:
全连接(FC)、卷积(CONV)和深度卷积(DWCONV)添加了MVE指令的int4类型支持;
重新实现 LSTM 以与 TFLM 参考内核保持一致;
LSTM 对 int16 输入的支持
DSP/MVEI 支持转置卷积
支持分组卷积
支持 FC 的非零滤波器偏移
对 MVEI 的 Int16 输入卷积支持
对 int16x8 卷积的 Int32 偏置支持
更能多内容可以查看本文末尾的CMSIS-NN v6.0.0 Release Note;
如何移植CMSIS-NN v6.0.0到VisionBoard?
1
创建RT-Thread项目
RT-Thread Studio创建基于VisionBoard开发板的模板项目,过程比较简单,不再赘述。
2
添加CMSIS-NN源码
RT-Thread Studio创建基于VisionBoard开发板的模板项目后,
在packages目录手动下载CMSIS-NN v6.0.0版本:
3
修改RT-Thread代码
修改项目顶层的Kconfig文件,添加如下代码行:
注意:Kconfig修改需要完需要保证最后有一行空行,否则menuconfig命令会报奇怪的错误。
检查packages目录内是否有SConsript文件,并且内容如下:
如果没有,可以手动创建。
4
修改CMSIS-NN代码
CMSIS-NN目录顶层创建SConscript文件,内容如下:
创建Kconfig文件,内容如下:
5
编译RT-Thread项目
完成以上修改之后,已经可以编译CMSIS-NN库的代码了。
在命令行中执行如下命令,编译整个项目:
编译输出最后部分如下图所示:
如何测试CMSIS-NN v6.0.0?
1
CMSIS-NN核心特性
CMSIS-NN库内部带有了单元测试,具体位于 Tests/UnitTest 子目录,其中 unittest_targets.py 脚本可以用于生成测试脚手架代码,使用方法如下:
当前生成的代码是单独生成elf文件,并在ARM虚拟硬件(AVH)平台上运行的。
默认情况下,执行python unittest_targets.py —download-and-generate-test-runners命令,会为每个测试用例生成一个main函数,每个测试用例单独编译为一个elf文件,之后使用ARM虚拟硬件(AVH)执行elf进行测试。
为了能够生成在RT-Thread上运行的测试代码,需要修改部分测试脚本代码,实现将每个测试用例注册为一个独立的finsh命令,在串口命令行中交互测试。
具体修改的代码差异如下:
这段修改实现了:
调用unity的ruby脚本,传递main_name命令行参数,用于修改单元测试入口函数名称(不指定默认是main);
生成一个独立的RT-Thread finsh命令注册代码.c文件;
生成一个用于编译的SConscript代码文件;
另外,再结合上层目录的SConcsript包含所有子目录的SConscript,就可以实现将所有单元测试编译为finsh命令了。
修改完该脚本文件后,执行如下命令,生成RT-Thread平台测试代码:
命令执行输出如下:
2
测试代码的构建规则SConscript
然后需要在CMSIS-NN的Tests子目录内,添加SConscript文件:
这段SConscript的作用是,将子目录的SConscript脚本包含到整个项目的构建流程中去。
接着需要在CMSIS-NN的Tests/UnitTest子目录内,添加SConscript文件:
完成以上修改后,通过menuconfig打开 PKG_USING_CMSIS_NN_TESTS 配置项目,再次 scons 编译,就可以编译单元测试代码文件了。
3
解决链接失败问题
但是还会有一些编译错误,原因主要有:
原来的测试脚本为每个测试用例独立生成main函数,每个目录单独编译;
链接到一起时,会有大量重复的setUp/tearDown/resetTest/verifyTest函数定义;
原来的测试数据数组没有加static修饰,被重复include到多个.c文件;
链接到一起时,会有数组重复的数组定义;
为了解决上述两类问题,分别创建两个脚本。
修复重复函数定义的 fix_testCode.sh:
解决方法,所有 setUp/tearDown/resetTest/verifyTest 函数添加 weak 属性修饰;
修复重复数组定义的 fix_testData.sh:
解决方法,所有测试数据的数组添加static修饰。
分别执行上面两个脚本之后,再次编译,就没有编译错误了。
4
运行单元测试
顺利编译之后,下载固件:
运行后,在串口输入help命令可以看到:
输入命令,运行avgpool算子的测试:
其他几个算子的s8类型测试:
全部0条评论
快来发表一下你的评论吧 !