单片机运行神经网络的总结:物尽其用
在之前的几篇博文中,我尝试在STM32F401(只有 64K Ram 和 256K 的Flash)上跑了几个常见模型,涵盖了DNN,RNN和CNN,做了MNIST的图像识别和运动检测两个类型的项目,对单片机运行神经网络有了一定经验,这里做一点大致总结。
ANN.h
在上述几个项目中,我通过整理和总结,对常用网络层做了函数封装,已经实现了下述的常用函数:
函数名 | 说明 |
---|---|
nn_dense | 全连接层 |
nn_rnn | 循环神经网络层,类似Keras里的SimpleRNN |
nn_conv2d | 2D卷积层 |
nn_pool2d | 2D池化层 |
nn_flatten | 展开,将深度卷积的结果展开到一维 |
active_softmax | 多分类问题时激活用,但不等价与真正的softmax |
这些函数原则上可以实现大部分常见的网络模型,至于到底能实现什么样的模型,就要看单片机的资源限制了,所以这里总结一些相关方面的问题。
问题1:F103系列能不能跑神经网络
原则上可以,但是要看你F103具体的型号,能跑什么样的网络跟你单片机的RAM有关,RAM很大程度上决定了单片机上网络的规模,一般来说小于5层的DNN和RNN在64k RAM的单片机上问题都不是很大。当然了,具体问题具体分析,上述只是通解。
问题2:F0系列能不能跑
参考问题1,原则上也可以,跟RAM有关,可以跑一些输入输出比较少的RNN和DNN,不建议跑卷积。
问题3:有没有性价比比较高的MCU或平台推荐
我写整个项目用的是F401CCU6这个MCU,淘宝上上单颗相对比较便宜,64K的RAM+256K的Flash,中规中矩,属于中下配置,F4的入门款,但是因为是F4有浮点单元,浮点运算可以加速,相对F0和F1会好一点;整体推荐上来说,F4系列都不错,毕竟能跑在单片机上的网络规模都不会很大,F4的xE及以上的资源基本上就比较充足了。
问题4:能不能人脸识别
人脸识别时两个问题,包含了:
- 有没有人脸(分类问题)
- 人脸在哪里(目标检测问题)
虽然上述两个问题最终都可以转化为 分类问题 求解,但这个过程相当于是通过分类对目标进行搜索。所以要在单片机上实现人脸识别,不是不可以,但是在我所使用的F401CC芯片上不可以,因为资源实在有限,内存不够用,可以在更高级的一些系列中找合适的芯片去尝试。
问题5:网络的规模怎么衡量
在PC端训练完网络以后,可以看看整个网络的权重参数的数量,每一个权重参数都是float型,占4个字节,那么64K的RAM理论上可以最多允许有16000个参数。
但实际上不可能,单片机运行状态下也会需要运行内存,假如运行时至少需要50%的内存,那么能允许的最大参数量就变成了8000个。
以上只是一个衡量的方法,我的建议是:
- 如果跑卷积层,那么至少预留50%的内存;
- 如果跑RNN或者DNN,可以留30%左右的内存;
- 多层卷积的,类似VGG这样的网络,至少留70%的内存。
具体留多少,可以在片上调试的时候具体看,以上只是对新手建议,避免能编译却跑不了的尴尬。如果能很好的控制内存开销,可以适当少留一点,所以具体问题还是要具体分析。