内存256KB设备也能人脸检测,微软提出用RNN代替CNN | NeurIPS 2020
蕾师师 发自 凹非寺 量子位 报道 | 公众号 QbitAI
为了让更多IoT设备用上AI,在条件“简陋”的单片机上跑图像识别模型也成为一种需求。
但是图像识别对内存有较高的要求,一般搭载MCU的设备内存都不高,怎样才能解决这个问题呢?
最近,微软提出了一种RNNPool方法,甚至可在内存只有256 KB的STM32开发板上运行人脸检测模型。
这篇论文也发表在近期举行的顶会NeurIPS 2020上,相关代码已经开源。
CNN难以适应单片机低内存
目前,计算机视觉领域的主要架构都是基于CNN,但是CNN对处理器的内存要求比较高,所以对于微型处理器,更加不友好。
CNN主要分成两个部分,一是卷积层,用来提取被输入图像的视觉特征。二是池化层,用来组合特征,并且简单表达出来。
但这样的结构真的非常消耗内存,假如我们输入一张56×56的8位图像,在处理的过程中,至少需要800KB的内存。
边缘AI往往内存和功耗都有限,大多数Arm Cortex-M4微控制器设备的内存都少于256 KB。
显然,CNN方法应用在这类边缘设备上是不现实的。
虽然压缩激活图的大小可以减少输出通道的数量,但这可能会导致精度大大降低。
另一种方法是对图的行/列数量进行下采样。
假设是一个28×28×256的激活图取代56×56×256激活图。那么,一个图像就可以压缩到200 KB内。
池化算子和带状卷积是下采样激活图的标准方法,但这个方法依赖于相对简单和有损的聚合。若将其应用于较大的接收域,或者图像模块进行更激进的下采样,则可能会导致其精度降低。
因此,如上图中所示,在大多数标准CNN架构中,这种运算符仅限于在2×2的接收域才能保证它的准确度。
而且这种方法只将激活图大小减少了四倍,满足不了我们的要求。
因此,我们需要找到一个池化算子,它既可以总结激活图的大模块,并可以一次性降低激活图的大小。
这种方法就叫做RNNPool。
RNNPool所需内存减少80~90%
RNNPool在语法上等效于池化算子,可以快速减小中间图的大小。它的模型层数更少,对内存要求更低,可以在内存受限的小型设备上分析图像。
RNNPool由两个学习递归神经网络(RNN)组成,它们以每个模块为单个向量,在水平和垂直方向上扫过激活图的每个模块。
RNNPool获取一个激活图的模块并将其汇总为1×1体素,然后逐步执行下采样步骤。RNNPool可以支持8×8,甚至16×16的模块大小,并且可以以步长s = 4或s = 8采样,而不会显著降低精度。
第一个RNN遍历每一行和每一列,并将它们全部汇总为h1维的1×1体素,第二个RNN双向遍历这些体素,并且生成一个最终的1×4×h2向量。其中,h1是第一遍RNN隐藏状态的大小,其中h2是第二个RNN隐藏状态的大小。
因此,它可以在不损失准确度的情况下大幅降低激活图的采样率。
由于RNNPool与池化算子等价,所以它可用于替换CNN中的所有池化运算符,降低对内存需求。
将RNNPool放在CNN架构的开头,可以快速采样激活图,降低峰值内存需求。
在大多数情况下,研究人员发现基于RNNPool的模型所需的内存可以减少至原来的10~20%。同时,仍能保持几乎相同的准确度。
实验测试结果
研究人员将基于RNNPool的人脸检测模型(称为RNNPool-Face-M4)在一个叫做SeeDot的工具上编译。
RNNPool-Face-M4用在Arm Cortex-M4微控制器的STM32F439-M4器件上,通过测试,它能在10.45秒内处理单个图像,它的峰值内存仅需要188 KB。
再通过跟EagleEye(小型设备领域的SOTA技术)比较,可以看到,RNNPool-Face-Quant在内存消耗上的225KB明显明显优于EagleEye的1.17MB。
Demo
微软团队还基于RNNPool制作了两个图像任务Demo。
其中一个是脸部识别。
在训练时,根据参数不同,输入图像将为640x640的RGB图,或者为320x320的的单色图。
在测试时,主要运用了两种模式。一是为一组样本图像生成边界框的评估模式,二是计算诸如mAP分数之类的测试模式。
测试方法一是将图像保存在特定的文件夹中,并在具有高置信度的脸部周围标志上边框。如下图所示:
测试方法二对于每个图像,都提供了单独的预测文件,文件中的每一行都对应一个标识框。对于每个框,将生成五个数字:框的长度,框的高度,x轴偏移,y轴偏移,存在脸部的置信度值。
除了面部识别的程序代码外,他们还贴出了一个Visual_Wakeword的代码库,这是一个二元的识别程序,即判断图像里面,是否有人的出现。
官方介绍: https://www.microsoft.com/en-us/research/blog/seeing-on-tiny-battery-powered-microcontrollers-with-rnnpool/
论文地址: https://www.microsoft.com/en-us/research/publication/rnnpool-efficient-non-linear-pooling-for-ram-constrained-inference/
开源代码: https://github.com/microsoft/EdgeML/blob/master/pytorch/edgeml_pytorch/graph/rnnpool.py
https://github.com/microsoft/EdgeML/tree/master/examples/pytorch/vision
— 完 —
本文系网易新闻•网易号特色内容激励计划签约账号【量子位】原创内容,未经账号授权,禁止随意转载。
AI落地最佳参考!
2020中国人工智能年度评选结果揭晓
12月16日,量子位MEET 2021智能未来大会现场,50大领航企业、10大明星创业公司、30大商业领军人物、10大最佳产品、10大最佳解决方案、5大社会责任榜样、5大最佳技术社区等年度奖项悉数颁出。
点击图片查看完整榜单:
量子位 QbitAI · 头条号签约作者
վ'ᴗ' ի 追踪AI技术和产品新动态
一键三连「分享」、「点赞」和「在看」
科技前沿进展日日相见~
相关文章
- JVM内存与垃圾回收篇第1章JVM和Java体系架构
- 一篇文章弄懂Java多线程基础和Java内存模型
- 【说站】javascript内存泄漏的识别方法
- VB读取线程、句柄及写入内存的API代码实例分享
- 【Android 逆向】代码调试器开发 ( 代码调试器功能简介 | 设置断点 | 读写内存 | 读写寄存器 | 恢复运行 | Attach 进程 )
- Go内存对齐详解
- 1G以下小内存(512M或更小)使用swap方法安装fileinfo扩展
- Exploring the Memory Management of Linux Kernel(linux内核的内存管理)
- 使用内存借助Linux限制进程最大内存使用(linux限制进程)
- 微软承认新 BUG:使用持久性内存的设备会出现启动缓慢问题
- Rowhammer:针对物理内存的攻击可以取得 Android 设备的 root 权限
- 《JDK10新特性官方文档》在可选内存设备上的分配堆内存
- 探讨Redis所需的内存(redis需要多少内存)
- MySQL内存计算:优化程序性能的关键(mysql内存计算)
- Linux程序占用内存分析报告(linux程序占用内存)
- 调优Oracle内存优化,提升性能表现(oracle内存 性能)
- Oracle数据库内存利用率过高问题排查(oracle 内存 很高)
- 字符串内存驻留机制详解示例
- linux系统使用python获取内存使用信息脚本分享
- C#反射内存的处理分析