以前的神经网络几乎都是部署在云端(服务器上),设备端采集到数据通过网络发送给服务器做inference(推理),结果再通过网络返回给设备端。如今越来越多的神经网络部署在嵌入式设备端上,即inference在设备端上做。嵌入式设备的特点是算力不强、memory小。可以通过对神经网络做量化来降load和省memory,但有时可能memory还吃紧,就需要对神经网络在memory使用上做进一步优化。本文就以一维卷积神经网络为例谈谈怎么来进一步优化卷积神经网络使用的memory。

文章(卷积神经网络中一维卷积的计算过程)讲了卷积神经网络一维卷积的处理过程,可以看出卷积层的输入是一个大矩阵,输出也是一个大矩阵,保存这些矩阵是挺耗memory的。其实做卷积计算时,每次都是从输入中取出kernel size大小的数据与kernel做卷积运算,得到的是一个值,保存在卷积层的输出buffer里,输出也是下一层的输入。如果输入是卷积层kernel的大小(即是能做运算的最小size),输出是下一层的能做运算的最小size,相对于整个输入和输出的size而言,能节省不少memory。下面就讲讲怎么用这种思路来做CNN的memory优化。

假设当前层和下一层均为卷积层,stride为1,padding模式为same。当前层的输入是一个MxN的矩阵,kernel size是P,kernel count是Q,所以kernel是一个MxP的矩阵,当前层的输出是一个QxN矩阵。当前卷积层的输出就是下一卷积层的输入。下一卷积层的kernel size是J,kernel count是K,所以下一卷积层的kernel是一个QxJ的矩阵,输出是一个KxN的矩阵。示意如下图:

首先从输入矩阵中取出0~(P-1)列(共P列)放进输入buffer中,正好放满。与第一个kernel做卷积运算就得到一个值放进输出buffer中(0,0)位置。同样与第二个kernel做卷积得到的值放在输出buffer中(1,0)位置,与所有kernel做完卷积后得到是一个Q行1列的矩阵,放在输出buffer第一列上,如下图:

再将输入矩阵的第1~P列取出放进输入buffer中(即把输入buffer中每列向前移一格,0列移出buffer,第P列放在最后1列),同上面一样计算,得到的依旧是1列数值放进输出buffer的第2列中。如下图:

依次这么做下去,当输出buffer里的最后一列被填满时,就要触发下一卷积层做卷积运算,与K个kernel卷积运算后得到的是一个K行1列的值放进下一卷积层输出buffer的第一列中。如下图:

由于下一卷积层的输出buffer未满,不能触发后面的运算。又回到从输入矩阵中取数据放进当前卷积层的输入buffer中,再进行当前卷积层和下一卷积层的运算,结果放在各自的输出buffer里(如输出buffer满了就要把每列左移一格,0列移出buffer,新生成的1列数据放在最后1列)。类似的处理,直到把输入矩阵中取到最后一列,再把各个层的输入buffer全处理完,最后得到结果。

从上面的思路看出,输入和输出buffer从大矩阵变成kernel大小的小矩阵可以省不少memory。具体软件实现时,有输入层,中间各层(包括卷积层等),每一层为一个整体,要用event机制去触发下一个要处理的层。当一层处理完后要判断下一步是哪一层做处理(有可能是下一层,也有可能是当前层或上一层,还有可能是输入层等),就给那一层发event,那一层收到event后就会继续处理。示意如下图:

软件实现时还有很多细节要处理,尤其是当输入层数据取完后后面各层的处理,这里就不一一细述了。软件调试时先用不省memory的原始code生成每层的输出,保存在各自的文件里,用于做比特校验。然后对省memory的code进行调试,先从第一层开始,一层一层的调试。优化后的代码每层的输出跟优化前的输出是完全一样的才算调试完成。

嵌入式设备上卷积神经网络推理时memory的优化的更多相关文章

  1. Local Binary Convolutional Neural Networks ---卷积深度网络移植到嵌入式设备上?

    前言:今天他给大家带来一篇发表在CVPR 2017上的文章. 原文:LBCNN 原文代码:https://github.com/juefeix/lbcnn.torch 本文主要内容:把局部二值与卷积神 ...

  2. 嵌入式设备上的 Linux 系统开发

    转载:http://www.ibm.com/developerworks/cn/linux/embed/embdev/index.html   如果您刚接触嵌入式开发,那么大量可用的引导装载程序(bo ...

  3. MNIST数据集上卷积神经网络的简单实现(使用PyTorch)

    设计的CNN模型包括一个输入层,输入的是MNIST数据集中28*28*1的灰度图 两个卷积层, 第一层卷积层使用6个3*3的kernel进行filter,步长为1,填充1.这样得到的尺寸是(28+1* ...

  4. 用Qemu模拟vexpress-a9 (七) --- 嵌入式设备上安装telnet服务

    转载: http://blog.csdn.net/liuqz2009/article/details/6921789 Telnet协议是登陆远程网 络主机最简单的方法之一,只是安全性非常低.对targ ...

  5. 嵌入式设备上运行AllJoyn注意事项

    1. 交叉编译AllJoyn库.编译成功后的文件位于:alljoyn-3.3.0-src\build\linux\arm\debug\dist\目录下: 2. 程序要使用AllJoyn,必须要启动al ...

  6. 嵌入式Linux设备驱动程序:在运行时读取驱动程序状态

    嵌入式Linux设备驱动程序:在运行时读取驱动程序状态 Embedded Linux device drivers: Reading driver state at runtime 在运行时了解驱动程 ...

  7. 轻量级卷积神经网络——MobileNet

    谷歌论文题目: MobileNets: Efficient Convolutional Neural Networks for Mobile Vision Applications 其他参考: CNN ...

  8. FFMPEG在嵌入式硬件上应用之 —— 基本环境搭建及编译

    前段时间在翻看电脑里面资料时,发现了以前做的在嵌入式硬件上面运行以ffmepg为基础,以嵌入式硬件解码的多媒体播放工作,发现都快忘记完了.今日得闲整理温习了一下ffmpeg在嵌入式上的运用,这里给大家 ...

  9. 在嵌入式设备中使用 JavaScript 的前景

    by Conmajia PC上的JavaScript已经发展到ECMAScript 6(ES6),马上ES10都快出来了(虽然还是草案),但是硬件上的JS却很少听说.这几年手持设备/可穿戴设备的发展非 ...

随机推荐

  1. Windows下使用Graalvm将Javafx应用编译成exe

    1 背景 Graalvm是Oracle推出的一款新型虚拟机,其中一个吸引人的功能是:它可以将Java代码编译成各个平台的本地代码,这些平台包括:linux.macOS.windows.iOS.andr ...

  2. Docker踩过的坑

    前言 主要是记录Docker遇到的坑,更多的是因为自己的粗心大意,以此警示 正文 Dockerfile里的RUN 某一次把启动服务的命令写在了 Dockerfile 中,后来发现服务一直拉不起来. 原 ...

  3. 【Java基础】面向对象上

    面向对象上 这一章主要涉及 Java 类及类的成员,包括属性.方法.构造器:代码块.内部类. 面向过程与面向对象 面向过程(Procedure Oriented Programming,POP)与面向 ...

  4. Python pip install 默认路径修改。

    pip动不动就下载数百M的文件.这些文件默认在C:盘,那么为了节省空间需要修改这些路径: 打开cmd命令窗口.输入: python -m site C:\Users\hewei>python - ...

  5. (十)Python装饰器

    装饰器:本质就是函数,功能是为其他函数添加附加功能. 两个原则: 1.不修改被修饰函数的源代码 2.不修改被修饰函数的调用方式 一个栗子 def test(): res = 0 for i in ra ...

  6. 【Linux】shell脚本实现多并发

    情景 shell脚本的执行效率虽高,但当任务量巨大时仍然需要较长的时间,尤其是需要执行一大批的命令时.因为默认情况下,shell脚本中的命令是串行执行的.如果这些命令相互之间是独立的,则可以使用&qu ...

  7. [Usaco2007 Dec]宝石手镯

    题目描述 贝茜在珠宝店闲逛时,买到了一个中意的手镯.很自然地,她想从她收集的 N(1 <= N <= 3,402)块宝石中选出最好的那些镶在手镯上.对于第i块宝石,它的重量为W_i(1 & ...

  8. CNN可视化技术总结(一)--特征图可视化

    导言: 在CV很多方向所谓改进模型,改进网络,都是在按照人的主观思想在改进,常常在说CNN的本质是提取特征,但并不知道它提取了什么特征,哪些区域对于识别真正起作用,也不知道网络是根据什么得出了分类结果 ...

  9. 三分钟学会 ASP.NET Core WebApi使用Swagger生成api说明文档

    什么是Swagger?为啥要用Swagger? Swagger可以从不同的代码中,根据注释生成API信息,Swagger拥有强大的社区,并且对于各种语言都支持良好,有很多的工具可以通过swagger生 ...

  10. Spring Security OAuth2.0认证授权六:前后端分离下的登录授权

    历史文章 Spring Security OAuth2.0认证授权一:框架搭建和认证测试 Spring Security OAuth2.0认证授权二:搭建资源服务 Spring Security OA ...