一、前言
这篇论文是Google针对手机等嵌入式设备提出的一种轻量级的深层神经网络,取名为MobileNets。个人感觉论文所做工作偏向于模型压缩方面,核心思想就是卷积核的巧妙分解,可以有效减少网络参数。
论文地址:MobileNets: Efficient Convolutional Neural Networks for Mobile Vision Applications
民间实现:Caffe | Tensorflow_1 | Tensorflow_2
官方代码:mobilenet_v1.md
论文下载:请到文章结尾处下载。
二、摘要
我们提供一类称为MobileNets的高效模型,用于移动和嵌入式视觉应用。 MobileNets是基于一个流线型的架构,它使用深度可分离的卷积来构建轻量级的深层神经网络。我们引入两个简单的全局超参数,在延迟度和准确度之间有效地进行平衡。这两个超参数允许模型构建者根据问题的约束条件,为其应用选择合适大小的模型。我们进行了资源和精度权衡的广泛实验,与ImageNet分类上的其他流行的网络模型相比,MobileNets表现出很强的性能。最后,我们展示了MobileNets在广泛的应用场景中的有效性,包括物体检测,细粒度分类,人脸属性和大规模地理定位。
三、背景
随着深度学习的发展,卷积神经网络变得越来越普遍。当前发展的总体趋势是,通过更深和更复杂的网络来得到更高的精度,但是这种网络往往在模型大小和运行速度上没多大优势。一些嵌入式平台上的应用比如机器人和自动驾驶,它们的硬件资源有限,就十分需要一种轻量级、低延迟(同时精度尚可接受)的网络模型,这就是本文的主要工作。
毕竟消费类产品很多是嵌入式的终端产品,而且嵌入式芯片的计算性能并不很强。即使我们考虑云计算,也需要消耗大量的带宽资源和计算资源。因此,CNN的优化已成为深度学习产品能否在消费市场落脚生根的一个重要课题之一。所以,有不少学者着手研究CNN的网络优化,如韩松的SqueezeNet,Deep Compression,LeCun的SVD,Google的MobileNet以及这个孙剑的ShuffleNet等。
其实,网络压缩优化的方法有两个发展方向,一个是迁移学习,另一个是网络稀疏。迁移学习是指一种学习对另一种学习的影响,好比我们常说的举一反三行为,以减少模型对数据量的依赖。不过,它也可以通过knowledge distillation(知识蒸馏)实现大模型到小模型的迁移,这方面的工作有港中文汤晓鸥组的MobileID。他们运用模型压缩技术和domain knowledge,用小的网络去拟合大量的数据,并以大型teacher network的知识作为监督,训练了一个小而紧凑的student network打算将DeepID迁移到移动终端与嵌入式设备中。而另一方面,网络稀疏是现在比较主流的压缩优化方向,这方面的工作主要是以网络结构的剪枝和调整卷积方式为主。比如深度压缩,它先通过dropout,L1/L2-regularization等能产生权重稀疏性的方法训练体积和密度都很大的网络,然后把网络中贡献小(也就是被稀疏过的)的权重裁剪掉,相当于去除了一些冗余连接,最后对模型做一下fine-tune就得到他所说的30%压缩率的效果。但它在效率上的提高并不适合大多数的通用CPU,因为它的存储不连续,索引权重时容易发生Cache Miss,反而得不偿失。下面介绍的MobileNet在这方面更有优势,MobileNets主要关注优化延迟,同时兼顾模型大小,不像有些模型虽然参数少。
四、MoblieNets模型结构
MobileNet的主要工作是用depthwise sparable convolutions(深度级可分离卷积)替代过去的standard convolutions(标准卷积)来解决卷积网络的计算效率和参数量的问题。MobileNets模型基于是depthwise sparable convolutions(深度级可分离卷积),它可以将标准卷积分解成一个深度卷积和一个点卷积(1 × 1卷积核)。深度卷积将每个卷积核应用到每一个通道,而1 × 1卷积用来组合通道卷积的输出。
1、原理解释
下图说明了标准卷积如何进行分解的:
它将standard convolutions(标准卷积)分解为depthwise convolution(深度卷积)和pointwise convolution(逐点卷积),它默认一种假设,使用分解后的卷积效果和标准卷积效果是近似的。举个简单的例子说明,假设我们有一个输入图片,这个输入图片的维度是11 x 11 x 3,标准卷积为3 x 3 x 3 x 6(假设stride为2,padding为1),那么可以得到输出为6 × 6 × 16(6 = (11-3+2*1)/2+1)的输出结果。现在输入图片不变,先通过一个维度是3 × 3 × 1 × 3的深度卷积(输入是3通道,这里有3个卷积核分别作用在3个通道上),得到6 × 6 × 3的中间输出,然后再通过一个维度是1 × 1 × 3 ×16的1 ×1卷积,同样得到输出为6 × 6 × 16。
其实,它默认一个假设,就是常规卷积核在feature maps的channels维度映射中,存在一种类似线性组合的分解特性。我们用K表示一个常规卷积核,则:
其中,"⋅"表示一种特殊的矩阵乘法,其运算法则参考下面公式,b是一个m维矩阵”向量”(Matrix Spaces),它的每个元素(element)是一个s×s大小的2维卷积核:
Λ(b)表示bi为对角元素的对角阵,即:
而M是一个n×m的数值矩阵,n行数表示输出feature maps的维度(output channels number),m表示输入feature maps的维度(input channels number)。为了直观,我把上文中的公式K写成下面的形式:
其中,kij=μijbj是一个s×s的数值矩阵,表示4维常规卷积核中的一个2维小卷积核。 然后,我们利用上面的公式来分析模型计算量的压缩程度,常规卷积核K的计算量是:
而MobileNet的Separable卷积的计算量是:
则压缩率是:
我们很容易发现,这个结果跟原文计算量减少率是一样,因为MobileNet从本质上就是基于这种核分解假设而设计的。而且,从公式K中我们还能产生一些有趣的想法,如果M更稀疏的话,这个网络是否能进一步优化?答案是肯定的,文中引入的α因子,因为这相当于把M矩阵稀疏化成:
这里简单分析一下depthwise separable convolution在计算量上与标准卷积的差别。假定输入特征图大小是:
而输出特征图大小是:
其中,DF是特征图的width和height,这是假定两者是相同的。对于标准的卷积:
其计算量将是:
而对于depthwise convolution其计算量为:
pointwise convolution计算量是:
所以depthwise separable convolution总计算量是:
可以比较depthwise separable convolution和标准卷积如下:
一般情况下 N 比较大,那么如果采用3x3卷积核的话,depthwise separable convolution相较标准卷积可以降低大约9倍的计算量。其实,后面会有对比,计算量也会减少很多。这也正和我们上文所说的假设相一致了。
2、网络结构
前面讲述了depthwise separable convolution,这是MobileNet的基本组件,但是在真正应用中会加入Batch Normalization(BN),BN是啥?顾名思义,batch normalization嘛,就是“批规范化”咯。Google在ICML文中描述的非常清晰,即在每次SGD(随机梯度下降)时,通过mini-batch来对相应的activation做规范化操作,使得结果(输出信号各个维度)的均值为0,方差为1。
什么时候用BN呢?例如,在神经网络训练时遇到收敛速度很慢,或梯度爆炸等无法训练的状况时可以尝试BN来解决。另外,在一般使用情况下也可以加入BN来加快训练速度,提高模型精度。
除此之外,模型还使用ReLU激活函数,所以depthwise separable convolution的基本结构如下图所示:
而MobileNets网络是由很多上图所示的depthwise separable convolution组合而成的。其具体的网络结构如下图所示:
如上图所示,首先是一个3x3的标准卷积,然后后面就是堆积depthwise separable convolution,并且可以看到其中的部分depthwise convolution会通过strides=2(步长)进行down sampling(下采样)。然后采用average pooling(平均池化)将feature变成1x1,根据预测类别大小加上全连接层,最后是一个softmax层。如果单独计算depthwise convolution和pointwise convolution,整个网络有28层(这里Avg Pool和Softmax不计算在内)。
我们还可以分析整个网络的参数和计算量分布,如下图所示:
可以看到整个计算量基本集中在1x1卷积上,如果你熟悉卷积底层实现的话,你应该知道卷积一般通过一种im2col方式实现,其需要内存重组,但是当卷积核为1x1时,其实就不需要这种操作了,底层可以有更快的实现。对于参数也主要集中在1x1卷积,除此之外还有就是全连接层占了一部分参数。
MobileNet到底效果如何,这里与GoogleNet和VGG16做了对比,如下图所示:
相比VGG16,MobileNet的准确度稍微下降,但是优于GoogleNet。然而,从计算量和参数量上MobileNet具有绝对的优势。
3、MoblieNets瘦身
前面说的MobileNet的基准模型,但是有时候你需要更小的模型,那么就要对MobileNet瘦身了。这里引入了两个超参数:width multiplier(宽度乘数)和resolution multiplier(分辨率乘数)。
宽度乘数:
第一个参数width multiplier主要是按比例减少通道数,该参数记为α,其取值范围为(0,1],那么输入与输出通道数将变成αM和αN,对于depthwise separable convolution,其计算量变为:
其实,这相当于把M矩阵稀疏化成:
应用宽度乘数可以进一步减少计算量,大约有 α*α 的优化空间。
分辨率乘数:
第二个超参数是分辨率乘数 ρ ,比如原来输入特征图是224x224,可以减少为192x192。分辨率乘数用来改变输入数据层的分辨率,同样也能减少参数。在 α 和 ρ 共同作用下,MobileNets某一层的计算量为:
要说明的是,resolution multiplier仅仅影响计算量,但是不改变参数量。其中,ρ 是隐式参数,ρ 如果为{1,6/7,5/7,4/7},则对应输入分辨率为{224,192,160,128},ρ 参数的优化空间同样是 ρ2 左右。 从下图可以看出两个超参数在减少网络参数的上的作用:
4、实验分析
模型选择:
同样是MobileNets的架构,使用可分离卷积,精度值下降1%,而参数仅为1/7。
深且瘦(Narrow)的网络比浅且胖(Shallow)的网络准确率高3%:
模型收缩超参数:
α 超参数减小的时候,模型准确率随着模型的变瘦而下降:
ρ 超参数减小的时候,模型准确率随着模型的分辨率下降而下降:
引入两个参数会给肯定会降低MobileNet的性能,总结来看是在accuracy和computation,以及accuracy和model size之间做折中。
至于代码实现,已经在文章开头写明,这里不再献丑了。
参考资料:
http://blog.csdn.net/Jesse_Mx/article/details/70766871
http://blog.csdn.net/sun_28/article/details/78170878
https://www.zhihu.com/question/38102762
https://zhuanlan.zhihu.com/p/31551004
2018年9月27日 下午5:25 沙发
试试
2018年9月27日 下午5:26 板凳
速度有点慢
2018年9月27日 下午7:12 1层
@liujingyanghui 网站速度?
2018年10月12日 下午2:45 地板
网络结构倒数第五行 Conv dw/s2 3X3X1024 dw 7X7X1024 ,这一层是stride=2还是stride=1?
2018年10月12日 下午2:55 1层
@lg s2就是代表stride=2。
2018年10月12日 下午3:22 2层
@Jack Cui 如果stride=2,下一层的输入大小和这一层的输入大小一样?
2018年10月12日 下午3:23 3层
@lg 有padding啊,tensorflow的SAME了解下。
2018年10月12日 下午3:42 4层
@Jack Cui The TensorFlow Convolution example gives an overview about the difference between SAME and VALID :
For the SAME padding, the output height and width are computed as:
out_height = ceil(float(in_height) / float(strides[1]))
out_width = ceil(float(in_width) / float(strides[2]))
out_width = ceil(7/2) = ceil(3.5)=4 求教!
2018年10月12日 下午4:06 3层
@lg same的话,也是除以2。sorry,我的锅,看了下别人的源码。
https://ww4.sinaimg.cn/large/0072Lfvtly1fw5i4eah3dj308w099749.jpg
这样就就对了,stride应该是1,论文这里应该是写错了。
https://github.com/marvis/pytorch-mobilenet/blob/master/benchmark.py
2018年10月12日 下午4:12 3层
@lg 文中图片已修改。
2018年10月12日 下午5:19 4层
@Jack Cui 学习,受教
2019年4月10日 下午4:03 4楼
博主你好。请教一个问题。在分辨率乘数的超参中,这个缩减特征图是按照什么规则缩减?(比如割掉右上角的部分,或者整体缩放,等等。)
2019年4月10日 下午5:00 1层
@新爷 是整体缩放。
2020年11月15日 下午1:54 2层
@Jack Cui 请问,这个整体缩放是就按间隔取值还是做一下拟合按位置计算值呢?
2022年3月31日 下午5:55 5楼
很详细!谢谢博主