本文我们描述了一种新的mobile结构称为MobileNetV2,改进了模型在多个tasks与benchmarks以及不同大小模型的SOTA。我们还描述了一个将这些mobile模型应用在目标检测中的新框架,称为SSDLite。此外,我们还介绍了如何通过改进DeepLabv3构建我们称为DeepLabv3的mobile语义分割模型。网络基于反转残差结构,shortcut位于thin bottleneck层之间。中间膨胀层使用轻量级的depthwise卷积作为非线性的来源来过滤特征。此外我们发现,将narrow层的非线性移除对于保持特征表达能力相当重要。我们展示这样可以提升模型表现,提供进行这样设计方式的思路。最后,我们的方法给输入输出提供了从昂贵的变化中解耦合的能力,为进一步分析提供了便利的框架。在ImageNet【1】分类任务,COCO检测任务【2】,VOC图片分割任务【3】上对我们方法的而评估。我们评估了准确率、通过MAdd表示的操作量、实际时延与参数个数之间的trade0ff。
神经网络使得机器智能的许多领域产生了革新,在图像识别任务上取得了超越人类的准确率。然而,产生这些准确率优化的驱动往往包含一个损耗:当前SOTA的网络往往需要远远超过mobile或者嵌入式设备能够提供的计算资源。
本文介绍了一种新的神经网络结构,专门针对移动端或者资源受限的场景。我们的模型通过显著降低操作次数并且在达到相同精度的同时降低显存需求改进了移动定制视觉模型的SOTA。
我们的主要贡献是一个先进的层模块:包含线性瓶颈结构的反转残差结构。模块的输入是低维压缩的特征表达,第一步扩展到高维空间,进行轻量级的depthwise卷积。得到的特征通过线性卷积投影回低维空间。官方实现作为TensorFlow-Slim模型库【4】的一部分。
模块可以使用任何现代框架中的标准操作复现,使用标准的benchmarks在多个性能点上打败了SOTA的模型。此外这样的卷积结构特别适用于移动模型设计,因为它可以在推理时用过从不产生大的中间tensors而显著减少显存占用。这减少了许多嵌入式硬件设计中对主存访问的需求,提供了少量超高速软件控制的缓存。
将深度神经网络结构的准准确率与性能表现达到动态平衡是最近这些年的一个研究热点。无论是多支团队提供的手工结构搜索还是训练算法改进都给早期的设计例如AlexNet【5】、VGGNet【6】、GoogleNet【7】与ResNet【8】带来了戏剧性的改进。当前在算法结构探索方面取得了许多进展,包括超参数优化【9,10,11】、多种网络裁剪方法【12,13,14,15,16,17】与关联学习【18,19】。有很多实质性的工作也致力于改进不同卷积块间的连接结构,例如ShuffleNet【20】或者引入稀疏性【21】或者其它内容【22】。
当前,文献【23,24,25,26】通过引入遗传算法,强化学习到结构搜索中打开了一个优化方法的新方向。这些方法有个缺点,得到的结果往往相当复杂。本文中,我们最求的目标是研究清楚神经网络时如何操作并且利用这个研究来引导最简单有效的网络设计。我们的方法需要与【23】中描述的结果及相关文献一样优秀。在这方面我们的方法与文献【20,22】提出的方法类似,允许进一步提升性能,公式提供对网络内部操作的大致了解。我们网络设计是基于MobileNetV1【27】。提出的网络保持了v1的简洁性,在不要求任何特殊操作的同时显著提升了准确率,在多重移动应用中的图像分类与检测任务中达到了SOTA的成绩。
深度可分离卷积是许多高效神经网络结构【27,28,20】关键的构建模块,我们在当前的工作也使用了这个模块。最基本的思路是将全卷积操作分离成两个不同的层总实现。第一层叫做depthwise卷积,通过应用每个输入通道卷积进行轻量级滤波。第二层是1×1卷积,称为pointwise卷积,通过计算输入通道的线性组合来响应生成特征。
标准卷积在输入tensor情况下花费,通过应用卷积核产生的输出tensor。标准卷积的计算量为。
深度可分离卷积引入进来是为了替代标准的卷积。实验表明他们可以达到正常卷积类似的效果,而花费仅为:
计算量是depthwise与1×1pointwise卷积之和。高效深度可分离卷积以系数降低传统卷积的计算量。MobileNetV2使用k=3(3×3深度可分离卷积),因此计算量比传统卷积要小8到9倍,仅仅在精度上有微小的损失【27】。
考虑到深度神经网络由n层组成,每个都包含一个的激活tensor。本节中我们将要讨论这些activate tensors的基本属性,我们将其作为一个包含像素,维度的容器。通俗来讲,对于真实样本输入集,我们认为一系列激活层(对于任意层)形成了“maniford of interest”。长期以来,人们一直认为神经网络中感兴趣的流形可以嵌入到低维子空间中。换句话说,当我们看所有深度卷积层的独立的d通道像素时,信息编码在那些实际上存在于某个流行的层中,并且依次嵌入在低维子空间中。
乍一看,这种情况可以通过简单的降低层的维度从而降低操作空间的维度来解决。这种思路成功的在MobileNetV1中通过width multiplier参数进行计算量与精确度的权衡,并且被嵌入到例如【20】这样的其他高效的网络模型设计中。根据这个思路,width mutiplier降低激活空间的维度,直至manifold of interest扩散到整个特征空间。然而,这种思路当神经网络中有例如ReLU这样的非线性结构的时候就行不通了。例如,将ReLU在一维空间中应用在一条直线的时候会产生一条射线,在空间中,会产生具有n个节点的分段曲线。
如果一个变换层ReLU(Bx)结果有非零成员S会比较容易从整体看出端倪,映射到S内部的点是通过输入的线性变化B得到的,这意味着受限于线性变换,部分输入空间对应着全出的输入维度。换句话说,深度网络只有在输出非零部分才有线性分类的能力。更正式的说明请参考补充材料。
换句话说,当ReLU分解通道的时候,不可避免的会造成通道信息的损失。然而,如果我们有许多通道,并且有一个结构在激活通道分流的时候信息任然保留在其他通道中。在补充材料中,我们证明了如果输入流程可以嵌入到激活空间的一个显著的低维子空间中,那么ReLU变换在保留信息的同事,将所需要的复杂性映入到可表达函数集合中。
总结来说,我们强调了两个特性,他们表面了manifold of interest对应该位于高维激活空间的地位子空间的要求:
1、如果manifold of interest在ReLU变换后任然保持非零值,那么对应线性变换。
2、ReLU可以在输入manifold分布在输入空间的低维子空间时保持完整的信息。
这两点思考给我们提供了优化现有网络结构的一些经验上的思路:假设manifold of interest是低维度的,那么我们可以通过在卷积模块中插入线性瓶颈结构层来捕获它。实验结果证明使用线性层相当重要,因为它可以防止非线性层损失了太多的信息。在第六节中,我们通过实现展示了瓶颈结构的非线性层实际上降低了一些性能,进一步验证了我们的假设。我们注意到类似报告【29】报告了非线性的改进,当线性从传统残差结构中移除会带来CIFAR数据集上性能的改进。
在本文的其他结构中我们将使用瓶颈卷积。我们将瓶颈输入尺寸与内部尺寸的比值称为膨胀比。
瓶颈结构模块与残差模块类似,每个模块包含一个输入紧接着截个瓶颈结构,最后是一个膨胀结构【8】。然而,受到瓶颈结构实际上包含了所有必要信息的启发,而膨胀层只是作为一个伴随tensor非线性变化的实现细节,我们在瓶颈结构件直接使用shortcut。图3直观的展示了设计上的区别。插入shortcut的动机与经典残差连接的一致:我们希望改进梯度在multiplier层间传播的能力。然而,反向传播的设计被认为更加的高效(细节见第五节),在我们的实验中表现也较好。
瓶颈卷积的运行时间与参数计数 基本的结构实现如表1所示。对于一个大小为h×w的模块来说,膨胀系数为t与kernel size为 k,输入通道为,输出通道为,所有的乘加需求量是。与(1)相比这个表达有一个额外的变量,实际上我们额外的进行1×1卷积,然而我们网络的特性使得我们可以使用更小的输入与输出维度。在表3中我们对比了不同分辨率下MobileNetV1,MobileNetV2与ShuffleNet的需求量。
我们架构的一个有趣特性是,它提供了构建块(瓶颈结构)输入输出域之间的自然分离,层变化这个非线性函数将输入转换成输出。前者可以看做是网络在每一层的容量,而后者可以看做是表达能力。这与传统卷积模块形成了鲜明的对比,传统卷积模块既有规则也可分离,在传统卷积模块中,表达量与容量是纠缠在一起的,是输出层深度的函数。
尤其是当内层深度为0时,由于shortcut连接,卷积是恒等函数。当膨胀比小于1时是一个经典的残差卷积模块【8,30】。然而对于我们来说膨胀比大于1是最有用的。
这一说明使得我们能够独立的研究网络的表达能力,我们认为,对这种分离的进一步探索有助于更好的理解网络特性。
现在我们讨论我们提出结构的细节。如前面的章节讨论的,基础模块是包含残差结构的瓶颈深度可分离卷积。图1中展示了这个模块的详细结构。MobileNetV2结构包含了初始化的32个卷积核的全卷积结构,与19个如表2中描述的残差瓶颈层。我们处于低精度计算鲁棒性考虑【27】选择ReLU6作为非线性层。我们一如既往的使用3×3卷积核大小因为这已经是现代神经网络的标配,并且在训练时使用dropout与batch normalization。
除了第一层外,我们使用常量膨胀率来设置网络。我们的实验显示膨胀率在5到10之间的时候可以产生理想的性能曲线,如果需要小网络就将膨胀率调小,如果需要更好一些的效果则将膨胀率调大。
我们所有的主要实验中都对输入张量的大小应用为6的膨胀系数。例如,对于将64通道的张量作为输入,128通道张量作为输出的瓶颈层来说,中间膨胀层为64×6=384通道。
超参的取舍 如文献【27】所述,我们为不同的性能表现定制不同的结构,通过输入样本的分辨率与width multiplier作为超参,可以更具预期的进度与表现的取舍进行调整。我们的主干网络(width multiplier 1,224*224)计算量消耗包括300万乘加运算,使用340万参数。我们研究了输入分辨率96到225及width multiplier从0.35到1.4的性能权衡。网络的计算量从7M乘加到585MMadds,整体的模型大小从1.7M到6.9M参数。
与【27】中实现一处小不同是对于multipliers小于1,我们对除了最后一个卷积层外的所有层使用width multiplier。这改进了小模型的表现。
反转残差瓶颈层适合于显存高效的实现,对于移动应用来说相当的重要。TensorFlow【31】或者Caffe【32】上一个标准的高效前向实现建立一个有向无环计算图G,由边缘表示操作与节点表示中间计算张量。计算是为了最小化存储在显存中的张量总数而设计的。在最一般的情况下,搜索所有可能的计算顺序,选择一个最小的:
这里是一系列连接任意节点的中间张量,表示张量A的尺寸,size(i)是在操作i过程中需要的内部存储的总数量。
对于只有一般并行结构的图(如残差连接),只有一个可行的计算顺序,因此可以简化计算图G推理所需的总量与内存边界。
或者换句话说,内存量就是所有操作组合中输入输出的最大总大小。下面我们会展示如果我们把瓶颈残差模块作为单一操作(将内部卷积作为一次性tensor),内存总量将会由瓶颈张量的尺寸主导(或者大的多),而非瓶颈结构内部的张量。
Bottleneck Residual Block 图3b中展示的瓶颈模块操作可以表示为三个操作的组合,这里A是线性变换,B也是一个到输出域的线性变换:。
对于我们的网络来说,,但是适用于任何单通道变换。假设输入域的尺寸是|x|,输出域的尺寸是|y|,计算F(X)的内存需求可以降低至。
该算法是基于内部张量τ可以表示为t张量的级联,每个大小为n/t,我们的函数可以表示为:
通过累加计算,我们只需要一个大小为n/t的中间块始终保存在内存中。当n=t时,我们最终只需要在内存中保持一个单通道的中间表达张量。我们使用这个技巧的两个约束条件分别是:(a)内部转换(包括非线性与深度)都是单通道的(b)连续的非每通道操作具有输入大小与输出大小显著的比例。对于大多数传统的网络结构,这样的技巧不会产生显著的改进。
我们注意到使用t-way split计算F(X)所需要的乘加数与t无关,然而在现有视线中我们发现用几个较小矩阵相乘的方法替换单个矩阵相乘会由于缓存的增加而损害性能。我们发现当t是2到5之间的小常数时这个方法最有帮助。这种方法显著的降低了内存的需求,但是同时还是可以使用由深度学习框架提供的高度优化的矩阵乘法与卷积操作提示效率。特殊的框架级优化是否可以带来进一步优化还需观察。