如何在手机上跑深度神经网络

这天,老板跟你说,希望能在手机上跑深度神经网络,并且准确率要和 VGG、GoogleNet 差不多。

接到这个任务后你有点懵逼,这些网络别说计算量大,就连网络参数也要 100MB 的空间才存得下,放在手机上跑?开玩笑呗。

老板又说,怎么实现是你的事,我要的只是这个功能。

你默默地点了点头。

初步尝试:MobileNet v1

问题出在哪

要在手机上跑深度网络,需要在模型参数和计算量上进行优化。

那深度神经网络的计算量和参数量主要体现在哪呢?这里以 VGG16 为例:

第一层卷积: [224 x 224 x 3] --> [224 x 224 x 64],卷积核大小为 3 x 3(简单起见,这里计算量的计算忽略激活函数)

计算量为:\(3 \times 3 \times 3 \times 224 \times 224 \times 64 \approx 8.7 \times 10^7\)

参数量为:\(3 \times 3 \times 3 \times 64 = 1728\)

第二层卷积:[112 x 112 x 64] --> [112 x 112 x 128],卷积核大小为 3 x 3。

计算量为:\(3 \times 3 \times 64 \times 112 \times 112 \times 128 \approx 9.2 \times 10^8\)

参数量为:\(3 \times 3 \times 64 \times 128 = 73728\)

......

第一层全连接层:[14 x 14 x 512] --> [4096]。

计算量为:\(14 \times 14 \times 512 \times 4096 \approx 4.1 \times 10^8\)

参数量为:\(4096 \times 1000 = 4096000\)

......

两相对比,同时考虑到网络中卷积层比全连层多,就不难发现深度卷积网络中的计算量主要由卷积层承包,而参数则集中在全链接层。因此,要想对模型做优化,可以在卷积层的计算上做点手脚,同时减小全连接层的维度。

Separable Convolution

虽然找到了问题所在,但具体要如何优化卷积层的计算量呢?幸运的是,你在搜索的过程中发现已经有人针对这个问题给出了解决方案:Separable Convolution。这是一种对卷积运算进行分解的方法。

以下例子摘自文末链接:卷积神经网络中的Separable Convolution

假设现在需要做这样一个卷积操作:[64 x 64 x 3] --> [64 x 64 x 4],那么通常的操作是这样的(假设卷积核大小为 3 x 3):

这种做法的计算量为:\(3 \times 3 \times 3 \times 64 \times 64 \times 4 = 442368\),

参数量为:\(3 \times 3 \times 3 \times 4 = 108\)。

而 Separable Convolution 会将该操作分解为两步:Depthwise ConvolutionPointwise Convolution

Depthwise Convolution 的过程其实非常简单,顾名思义,Depthwise 就是每个通道单独做一遍卷积:

这种做法的效果是:[64 x 64 x 3] --> [64 x 64 x 3],由于是 Depthwise 的,所以只需要三个 [3 x 3 x 1] 的 filter 即可。

因此计算量为:\(3 \times 3 \times 64 \times 64 \times 3=110592\),

参数量为:\(3 \times 3 \times 3 = 27\)。

不过 Depthwise 将不同通道之间的联系断开了,而且输出的通道数与输入是一样的。为了得到 [64 x 64 x 4] 的输出,还需要经过 Pointwise Convolution。

Pointwise Convolution 的过程在 Depthwise 之后进行,它是用一个 [1 x 1] 的卷积核把 [64 x 64 x 3] 的 feature map 转换为 [64 x 64 x 4]:

计算量为:\(1 \times 1 \times 64 \times 64 \times 3 \times 4=49152\),

参数量为:\(1 \times 1 \times 3 \times 4 = 12\)。

我们发现,通过 Separable Convolution 这种分解的方法也可以拼凑出一个 [64 x 64 x 4] 的 feature map,

而这种方法的计算量为:\(110592 + 49152=159744\),而总的参数量为:\(27 + 12 = 39\)。

对比原先的 442368 (计算量) 和 108 (参数量),简直实惠了好多。

于是,你通过这种套路构造出了一个适合手机端运行的深度网络,并简化了全连接层的参数:

图中的 Conv dw 指的就是 Depthwise Convolution。由于是为手机设计的网络,因此你取了个形象的名字:Mobilenet。

不过,这个网络的精度会不会下降呢?你赶紧在 ImageNet 数据集上做了实验:

这个结果实在是太感人了,精度几乎和 GoogleNet 相当,但计算量却只有后者的三分之一,参数量也减少了三分之一(当然也可能是图像分类这个问题相对简单)。

为了方便对模型大小的进一步调整,你提供了两个额外的参数: \(\alpha\)、 \(\rho\)。\(\alpha\) 又称为 Width Multiplier,主要用来控制 feature map 的 channel 数目,因为在某些任务中,很多 feature map 的 channel 可能包含很少的信息,因此少一些,而有些情况可能需要更多的 channel。\(\alpha=1\) 时就是上文中提出的基准网络。\(\rho\) 则是图像的分辨率,由它控制输入图片的大小。

进阶:ShuffleNet v1

Separable Convolution 其实就是 MobileNet v1 的精华了,个人认为,MobileNet v1 能取得成功主要还是那些大网络在处理简单任务时存在大量的冗余,所以 MobileNet v1 用更少的参数量拼凑出同样大小的 feature map 时,性能并没有明显下降。

而 ShuffleNet v1 则是在此基础上进一步压榨卷积操作,它的重点放在了 Pointwise Convolution 上。Pointwise Convolution 的作用是把 feature map 的所有 channel 信息联系起来,但这种联系可能本身就存在冗余。举个例子,一个 [64 x 64 x 4] 的 feature map,通过 [1 x 1 x 4] 的卷积核后,可以得到 [64 x 64 x 1] 的输出,这个 [1 x 1 x 4] 的卷积核其实就是把原来 feature map 上每个位置的所有 channel 信息(一个 [1 x 1 x 4] 的通道向量)进行加权求和,得到下一层 feature map 上的一个点。不过,真的有必要融和整个通道向量的信息吗?如果只对两个通道的信息进行相加,得到的结果会比四个通道差吗?为了探究这个问题,炼丹师们把原来的 Pointwise Convolution 改造成了 Group Convolution,这个 Group Convolution 其实也不是什么新鲜玩意,当年 AlexNet 刚出来的时候,由于显存不足,就曾将卷积操作分为两组,用两张显卡来装 feature map,这种做法导致更少的参数量和计算量,而且在某些任务中并不会对性能产生很大影响。ShuffleNet v1 的炼丹师显然发现了这一点。

Group Convolution 的操作非常简单,还是举之前的例子:一个 [64 x 64 x 4] 的 feature map,要想进一步得到 [64 x 64 x 2] 的 feature map,直接用 Pointwise Convolution 处理的话,需要一个 [1 x 1 x 4 x 2] 的卷积张量。但用上 Group Convolution 后,我们可以这样操作,用一个 [1 x 1 x 2 x 1] 的卷积张量对原来 feature map 四层通道中的前面两层进行卷积操作,得到一个 [64 x 64 x 1] 的 feature map,之后,用另一个 [1 x 1 x 2 x 1] 的卷积张量继续对后面两层进行卷积操作,同样得到一个 [64 x 64 x 1] 的 feature map,这两块 feature map 拼在一起,最终得到一个 [64 x 64 x 2] 的 feature map。

仔细数数,原来 Pointwise Convolution 的计算量为:\(1 \times 1 \times 64 \times 64 \times 4 \times 2=32768\),参数量为:\(1 \times 1 \times 4 \times 2=8\),而现在拆成 Group Convolution 后,计算量为:\(1 \times 1 \times 64 \times 64 \times 2 \times 2=16384\),参数量为:\(1 \times 1 \times 2 \times 2=4\),计算量和参数量都减少了一半。

鸡贼的读者可能还发现,如果把 Group Convolution 做到极致,每个 Group 只有一个 channel 的话,就变成 Depthwise + Pointwise Convolution 了,哈哈,原来又是拼凑游戏,笑出声。

不过,仅仅用 Group Convolution,说性能不会影响很多人是不信的,毕竟本身就是 Pointwise Convolution,相邻点之间的信息已经忽略了,要是通道上的信息也忽略太多,难免会存在问题。所以,ShuffleNet v1 的 Shuffle 该登场了。炼丹师为了增强 Group Convolution 的鲁棒性,在对通道进行相加时,故意打乱了通道顺序。这样一来,在上面的例子中,本来是 1、2 通道结合得到一个新的点,就变成了 1、3 通道结合,2、4 通道结合了。

这也就是这篇论文的精华所在:

当然啦,估计是考虑到 Group Convolution 本身损失的信息有点严重,论文又特意加了 ResNet 中的短路连接,算是弥补了一点信息:

下图给出的是论文中关于 Shuffle 操作的实验:

Cls err 是 ImageNet 数据集上的错误分类率,数值越小证明结果越好,g 则表示 group 的数量。实验结果给出这样一个信息:当 group 的数量越多时,shuffle 的作用也越明显。这一点也很好理解,因为 group 越多,丢失的信息也越多,这时如果能把 channel 打散,那么不同组之间的 channel 信息就有了交流的通道,能在一定程度上增加鲁棒性。

总结

总的来说,MobileNet v1 作为第一个进行手机端优化的工作,其亮点主要是 Depthwise Convolution 和 Pointwise Convolution。ShuffleNet v1 则是在 MobileNet v1 的基础上加入了 Group Convolution,并通过 Shuffle 的方法提高鲁棒性,同时加入短路连接保持网络的表达能力。

参考

原文地址:https://www.cnblogs.com/jermmyhsu/p/9746064.html

时间: 2024-10-08 17:34:32

如何在手机上跑深度神经网络的相关文章

智能手机跑大规模神经网络的主要策略

计算机具有高储量的硬盘和强大的CPU和GPU.但是智能手机却没有,为了弥补这个缺陷,我们需要技巧来让智能手机高效地运行深度学习应用程序. 介绍 深度学习是一个令人难以置信的灵活且强大的技术,但运行的神经网络可以在计算方面需要非常大的电力,且对磁盘空间也有要求.这通常不是云空间能够解决的问题,一般都需要大硬盘服务器上运行驱动器和多个GPU模块. 不幸的是,在移动设备上运行神经网络并不容易.事实上,即使智能手机变得越来越强大,它们仍然具有有限的计算能力.电池寿命和可用磁盘空间,尤其是对于我们希望保持

用spark训练深度神经网络

SparkNet: Training Deep Network in Spark 这篇论文是 Berkeley 大学 Michael I. Jordan 组的 ICLR2016(under review) 的最新论文,有兴趣可以看看原文和源码:paper,github . 训练深度神经网络是一个非常耗时的过程,比如用卷积神经网络去训练一个目标识别任务需要好几天来训练.因此,充分利用集群的资源,加快训练速度成了一个非常重要的领域.不过,当前非常热门的批处理计算架构(例如:MapReduce 和 S

eclipse上如何在手机上运行项目

手机要能与电脑相连,当然要安驱动了.效果就是你插入手机,电脑显示驱动已识别.驱动安装的官方教程:http://developer.android.com/sdk/win-usb.html 设置android手机为USB调试模式 步骤: menu-> 设置 -> 应用程序 -> 开发 , 选择[USB调试] 首先打开集成开发环境 连接手机,启动USB调试模式点击确定 选择手机模式如图 接着你就会找到你的装置 双击即可在手机上运行你的软件了 没用真机时,用eclipse开发android程序

如何利用Python和深度神经网络锁定即将流失的客户?业绩过十万!

烦恼 作为一名数据分析师,你来到这家跨国银行工作已经半年了. 今天上午,老板把你叫到办公室,面色凝重. 你心里直打鼓,以为自己捅了什么篓子.幸好老板的话让你很快打消了顾虑. 客户主要分布在法国.德国和西班牙. 你手里掌握的信息,包括他们的年龄.性别.信用.办卡信息等.客户是否已流失的信息在最后一列(Exited). 请选择左侧的Python 3.6版本下载安装. 其次是新建文件夹,起名为demo-customer-churn-ann,并且从这个链接下载数据,放到该文件夹下. 点击界面右上方的Ne

深度神经网络可视化工具集锦

深度神经网络可视化工具集锦 雷锋网按:原文作者zhwhong,载于作者的个人博客,雷锋网(公众号:雷锋网)经授权发布.  TensorBoard:TensorFlow集成可视化工具 GitHub官方项目:https://github.com/tensorflow/tensorflow/tree/master/tensorflow/tensorboard TensorBoard 涉及到的运算,通常是在训练庞大的深度神经网络中出现的复杂而又难以理解的运算. 为了更方便 TensorFlow 程序的理

从图像到知识:深度神经网络实现图像理解的原理解析

摘要:本文将详细解析深度神经网络识别图形图像的基本原理.针对卷积神经网络,本文将详细探讨网络中每一层在图像识别中的原理和作用,例如卷积层(convolutional layer),采样层(pooling layer),全连接层(hidden layer),输出层(softmax output layer).针对递归神经网络,本文将解释它在在序列数据上表现出的强大能力.针对通用的深度神经网络模型,本文也将详细探讨网络的前馈和学习过程.卷积神经网络和递归神经网络的结合形成的深度学习模型甚至可以自动生

transform:rotate在手机上显示有锯齿的解决方案

transform:rotate 属于简单好用的效果,但在手机上显示时,会有比较明显锯齿. 解决方案也很简单, 利用外层容器的overflow:hidden 加上图片margin:-1px 就可以解决. 原理没去深究,理论上是矢量跟位图的处理不一样,这个方案也有个小问题 就是图片变小了 ^_^ 可以用手机看看demo http://labs.aoao.org.cn/demo/transform-rotate/ update: 大家反应这方案在电脑上反而会出问题. 我测试了个新的方案rotate3

通达OA 在手机上使用OA工作流审批你用过么?

通达的产品真的是不错,除了电脑能够访问,手机也有客户端可以安装,这样随时随地都可以访问OA查看邮件.新闻,通过工作流进行审批工作. 但是不知在手机客户端上用过工作流么?最近进行了一些手机客户端的测试,有些差异的地方: 1.手机上使用不了电脑上用的签章控件,手机上有专门的签章控件: 2.在手机上查看工作流时显示的控件与电脑上也有差异,控件的名称(title值)会直接显示,有些在电脑上通过设置大小等方式进行隐藏的控件也会显示出来.所以这是都需要跟着进行调整.控件的命名要求也就高一些,有些原来只能管理

深度学习实践系列(2)- 搭建notMNIST的深度神经网络

如果你希望系统性的了解神经网络,请参考零基础入门深度学习系列,下面我会粗略的介绍一下本文中实现神经网络需要了解的知识. 什么是深度神经网络? 神经网络包含三层:输入层(X).隐藏层和输出层:f(x) 每层之间每个节点都是完全连接的,其中包含权重(W).每层都存在一个偏移值(b). 每一层节点的计算方式如下: 其中g()代表激活函数,o()代表softmax输出函数. 使用Flow Graph的方式来表达如何正向推导神经网络,可以表达如下: x: 输入值 a(x):表示每个隐藏层的pre-acti