MobileNetV2

MobileNetV2:MobileNetV2: Inverted Residuals and Linear Bottlenecks

摘要

在本文中,我们描述了一种新的移动架构MobileNetV2,它改进了移动模型在多个任务和基准以及不同模型大小范围内的最新性能。我们还描述了在我们称为SSDLite的新框架中将这些移动模型应用于对象检测的有效方法。此外,我们演示了如何通过DeepLabv3的简化形式构建移动语义分割模型,我们称之为移动DeepLabv3。

其基于倒置的残差结构,其中捷径连接位于薄瓶颈层之间。中间扩展层使用轻量级深度卷积来过滤作为非线性源的特征。此外,我们发现,为了保持表征力,去除窄层中的非线性是很重要的。我们证明这提高了性能,并提供了导致此设计的直觉。

最后,我们的方法允许将输入/输出域与转换的表现力分离,这为进一步分析提供了方便的框架。我们测量了我们在ImageNet[1]分类、COCO对象检测[2]和VOC图像分割[3]方面的性能。我们评估了精度和乘法相加(MAdd)测量的操作数之间的权衡,以及实际延迟和参数数。

1 介绍

神经网络已经彻底改变了机器智能的许多领域,为具有挑战性的图像识别任务提供了超人的准确性。然而,提高准确性的努力往往是有代价的:现代最先进的网络需要比许多移动和嵌入式应用更高的计算资源。

本文介绍了一种专门为移动和资源受限环境量身定制的新神经网络架构。我们的网络通过显著减少所需的操作和内存数量,同时保持相同的准确性,推动了移动定制计算机视觉模型的发展。

我们的主要贡献是一个新的层模块:具有线性瓶颈的倒置残差模块。该模块将低维压缩表征作为输入,首先将其扩展到高维,并使用轻量级深度卷积进行过滤。特征随后使用线性卷积被投影回低维表征。官方实现可作为[4]中TensorFlow Slim模型库的一部分提供。

该模块可以在任何现代框架中使用标准操作高效地实现,并允许我们的模型在使用标准基准测试的多个性能点上击败最新技术。此外,该卷积模块特别适用于移动设计,因为它允许通过从未完全实现大的中间张量来显著减少推理过程中所需的内存占用。这减少了在许多嵌入式硬件设计中对主存储器访问的需求,这些硬件设计提供了少量非常快速的软件控制高速缓存。

2 相关工作

近几年来,调整深度神经架构以在准确性和性能之间取得最佳平衡一直是一个活跃的研究领域。许多团队进行的人工体系结构搜索和训练算法的改进都导致了早期设计的显著改进,如AlexNet[5]、VGGNet[6]、GoogleLeNet[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]。它保持了其简单性,不需要任何特殊的算子,同时显著提高了其准确性,在移动应用程序的多个图像分类和检测任务上达到了最先进水平。

3 准备、讨论和直觉

3.1 深度可分离卷积

深度可分离卷积是许多高效神经网络架构的关键构建块[27,28,20],我们也在当前的工作中使用它们。基本思想是用将卷积分为两个独立层的因式分解版本来替换全卷积算子。第一层称为深度卷积,它通过对每个输入信道应用单个卷积滤波器来执行轻量级滤波。第二层是1×1卷积,称为逐点卷积,负责通过计算输入信道的线性组合来构建新特征。

标准卷积对于一个 h i × w i × d i h_i \times w_i \times d_i hi×wi×di的输入张量 L i L_i Li,应用卷积核 K ∈ R k × k × d i × d j K\in R {^{k\times k\times d_i\times d_j}} KRk×k×di×dj以产生 h i × w i × d j h_i \times w_i \times d_j hi×wi×dj输出张量 L j L_j Lj。标准卷积层有如计算代价: h i × w i × d i × d j × k × k h_i \times w_i \times d_i \times d_j \times k \times k hi×wi×di×dj×k×k

深度可分离卷积是标准卷积层的替代品。经验上,它们几乎与常规卷积一样有效,但只需花费:
h i × w i × d i × ( k 2 + d j ) (1) h_i \times w_i \times d_i \times (k^2+d_j) \tag{1} hi×wi×di×(k2+dj)(1)

这是深度卷积和 1 × 1 1\times1 1×1点卷积的总和。与传统层相比,深度可分离卷积有效地减少了几乎 k 2 k^2 k2倍的计算量。MobileNetV2使用k=3,因此计算成本比标准卷积的计算成本小8到9倍,但精度仅略有降低[27]。

在这里插入图片描述
图2. 可分离卷积块的演变。对角阴影纹理表示不包含非线性的层。最后一层(浅色)表示下一个块的开始。注:堆叠时,2d和2c为等效块。最佳观看颜色。

3.2 Linear Bottlenecks

考虑一个由n层Li组成的深度神经网络,每个Li层都有一个 h i × w i × d i h_i \times w_i \times d_i hi×wi×di维的激活张量。在本节中,我们将讨论这些激活张量的基本性质,我们将其视为具有 d i d_i di维的 h i × w i h_i \times w_i hi×wi“像素”的容器。非正式地,对于真实图像的输入集,我们称层激活集(对于任何层Li)形成“兴趣流形”。长期以来,人们一直认为神经网络中兴趣流形可以嵌入低维子空间。换句话说,当我们观察深度卷积层的所有单个d通道像素时,这些值中编码的信息实际上位于某个流形中,而流形又可嵌入到低维子空间中。

乍一看,这样的事实可以通过简单地降低层的维度从而降低操作空间的维度来捕捉和利用。MobileNetV1[27]成功地利用了这一点,通过宽度乘数参数在计算和精度之间进行了有效权衡,并将其纳入了其他网络的有效模型设计[20]。根据这种直觉,宽度乘数方法可以减少激活空间的维数,直到兴趣流形跨越整个空间。然而,当我们回忆起深度卷积神经网络实际上每坐标变换具有非线性(如ReLU)时,这种直觉就崩溃了。例如,应用于1D空间中的线的ReLU会产生“射线”,与 R n R^n Rn空间一样,它通常会产生具有n个关节的分段线性曲线。

很容易看出,一般来说,如果层变换ReLU(Bx)的结果具有非零体积 S S S,则通过输入的线性变换B获得映射到内部S的点,从而指示对应于全维输出的输入空间的部分限于线性变换。换句话说,深度网络仅在输出域的非零体积部分具有线性分类器的能力。我们参考补充材料以获得更正式的声明。

另一方面,当ReLU崩溃信道时,它不可避免地会丢失该信道中的信息。然而,如果我们有很多通道,并且激活流形中有一个结构,那么信息可能仍保留在其他通道中。在补充材料中,我们表明,如果输入流形可以嵌入激活空间的显著低维子空间中,则ReLU变换保留了信息,同时将所需的复杂性引入到可表达函数集中。

综上所述,我们强调了两个特性,这两个特性指示了兴趣流形应该位于高维激活空间的低维子空间中的要求:

  1. 如果兴趣流形在ReLU变换后保持非零体积,则它对应于线性变换。
  2. ReLU能够保留关于输入流形的完整信息,但仅当输入流形位于输入空间的低维子空间中时。

这两个见解为我们提供了优化现有神经架构的经验提示:假设兴趣流形是低维的,我们可以通过在卷积块中插入线性瓶颈层来实现这一点。实验证据表明,使用线性层至关重要,因为它可以防止非线性破坏太多信息。在第6节中,我们根据经验表明,在瓶颈中使用非线性层确实会损害性能几个百分点,进一步验证了我们的假设3。我们注意到,[29]中报告了类似的帮助非线性的报告,其中从传统残差块的输入中去除了非线性,从而提高了CIFAR数据集的性能。在本文的其余部分,我们将利用瓶颈卷积。我们将输入瓶颈的大小与内部大小之间的比率称为扩展比率。

3.3 倒置残差块

瓶颈块看起来类似于残差块,其中每个块包含一个输入,然后是几个瓶颈,然后是扩展[8]。然而,受瓶颈实际上包含所有必要信息的直觉启发,而扩展层仅作为伴随张量非线性变换的实现细节,我们直接在瓶颈之间使用捷径。

图3提供了设计差异的示意图。插入捷径的动机类似于经典残差连接:我们希望提高梯度在乘数层之间传播的能力。 然而,倒置设计的内存效率要高得多(详见第5节),而且在我们的实验中效果稍好。

在这里插入图片描述
图3.残差块和倒残差块的区别。对角阴影层不使用非线性。我们使用每个块的厚度来指示其通道的相对数量。请注意,经典残差如何连接具有大量通道的层,而反向残差连接瓶颈。最佳观看颜色。

瓶颈卷积的运行时间和参数量 基本实现结构如表1所示。对于尺寸为 h × w h\times w h×w的块,扩展因子 t t t和核尺寸k,输入通道数 d ′ d' d,输出通道数 d ′ ′ d'' d,需要的乘加总数为 h × w × d ′ × t ( d ′ + k 2 + d ′ ′ ) h\times w\times d'\times t(d'+k^2+d'') h×w×d×t(d+k2+d)。与(1)相比,这个表达式有一个额外的项,实际上我们有一个1×1的卷积,但是我们网络的性质允许我们使用更小的输入和输出维度。在表3中,我们比较了MobileNetV1、MobileNetV2和ShuffleNet之间每种分辨率所需的大小。

3.4 Information flow interpretation

我们架构的一个有趣的特性是,它在构建块的输入/输出域(瓶颈层)和层转换之间提供了自然的分离——这是一个将输入转换为输出的非线性函数。前者可以被视为每一层网络的容量,而后者则被视为表现力。这与传统的卷积块形成了对比,卷积块既有规则的,也有可分离的,其中表现力和容量都是纠结在一起的,并且是输出层深度的函数。

特别是,在我们的例子中,当内层深度为0时,由于快捷连接,底层卷积是恒等函数。当扩展比小于1时,这是经典的残差卷积块[8,30]。然而,出于我们的目的,我们表明扩展比大于1是最有用的。

这种解释允许我们将网络的表现力与其容量分开来研究,我们认为,有必要进一步探索这种分离,以更好地理解网络属性。

4 模型结构

现在我们详细描述我们的架构。如前一节所述,基本构造块是具有残差的瓶颈深度可分离卷积。 该块的详细结构如表1所示。MobileNetV2的体系结构包含具有32个滤波器的初始完全卷积层,随后是表2中描述的19个剩余瓶颈层。
在这里插入图片描述
表1.瓶颈残差块

我们使用ReLU6作为非线性,因为它在用于低精度计算时具有鲁棒性[27]。我们总是使用核大小3×3因为它是现代网络的标准,并在训练过程中使用dropout和批量归一化。

除了第一层,我们在整个网络中使用恒定的扩展速率。在我们的实验中,我们发现5到10之间的扩展速率会导致几乎相同的性能曲线,较小的网络在稍小的扩展速率下性能更好,较大的网络在较大的扩展速率时性能稍好。对于我们的所有主要实验,我们使用了应用于输入张量大小的扩展因子6。例如,对于采用64通道输入张量并产生128通道张量的瓶颈层,中间扩展层则为64·6=384通道。

权衡超参数 如[27]中所述,我们通过使用输入图像分辨率和宽度因子作为可调超参数,根据不同的性能点调整我们的架构,可以根据所需的精度/性能权衡进行调整。我们的主网络(宽度因子1,224×224)的计算成本为3亿乘加,使用340万个参数。我们探讨了性能权衡,输入分辨率为96到224,宽度乘数为0.35到1.4。网络计算成本从7乘加数到5.85亿MAdds不等,而模型大小在1.7M和6.9M参数之间变化。与[27]的一个较小的实现差异是,对于小于1的乘数,我们将宽度乘数应用于除最后一个卷积层之外的所有层。这提高了较小模型的性能。

在这里插入图片描述
表2.MobileNetV2:每行描述一个由1个或多个相同(模步幅)层组成的序列,重复 n n n次。同一序列中的所有层具有相同数量的输出通道 c c c每个序列的第一层有一个步幅 s s s,其他所有序列都使用步幅1。所有空间卷积都使用3×3核。扩展因子 t t t总是应用于输入大小,如表1所示。

在这里插入图片描述

表3.在不同架构的每个空间分辨率下需要具体化的通道/内存的最大数量(Kb)。我们假设16位浮点用于激活。对于ShuffleNet,我们使用 2 x , g = 3 2x,g=3 2xg=3,这与MobileNetV1和MobileNetV2的性能相匹配。对于MobileNetV2和ShuffleNet的第一层,我们可以使用第5节中描述的技巧来减少内存需求。尽管ShuffleNet在其他地方使用了瓶颈,但由于非瓶颈张量之间存在捷径,因此仍需要具体化非瓶颈张张量。

在这里插入图片描述
图4.不同架构的卷积块比较。ShuffleNet使用组卷积[20]和混洗,它还使用传统的残差方法,其中内部块比输出窄。ShuffleNet和NasNet的插图来自相关论文。

5 Implementation Notes

6 实验

6.1 ImageNet分类

训练设置 我们使用TensorFlow训练模型[31]。我们使用标准的RMSPropOptimizer,衰减和动量都设置为0.9。我们在每一层之后使用批标准化,标准权重衰减设置为0.00004。在MobileNetV1[27]设置之后,我们使用初始学习速率0.045,学习速率衰减速率0.98每个epoch。我们使用16个GPU异步工作线程,批大小为96。

结果 我们将我们的网络与MobileNetV1、ShuffleNet和NASNet-A模型进行了比较。一些选定模型的统计数据如表4所示,完整的性能图如图5所示。

在这里插入图片描述
图5.MobileNetV2与MobileNetV1、ShuffleNet和NAS的性能曲线。对于我们的网络,我们对所有分辨率使用0.35、0.5、0.75、1.0的乘数,对224使用额外的1.4。最佳彩色观看效果。

在这里插入图片描述
表4.ImageNet上的性能,不同网络的比较。作为操作的常见做法,我们计算乘法相加的总数。在最后一列中,我们报告了Google Pixel 1手机(使用TF Lite)单个大内核的运行时间(毫秒)。我们不报告ShuffleNet数字,因为还不支持有效的组卷积和混洗。

6.2 目标检测

我们评估并比较了MobileNetV2和MobileNetV1作为特征提取器[33]的性能,用于COCO数据集[2]上的单阶段检测器(SSD)[34]的改进版本的目标检测。我们还将YOLOv2[35]和原始SSD(以VGG-16[6]为基础网络)作为基线进行了比较。我们没有将性能与其他架构(如Faster RCNN[36]和RFCN[37])进行比较,因为我们的重点是移动/实时模型。

SSDLite: 在本文中,我们介绍了常规SSD的一种移动友好型变体。我们将SSD预测层中的所有常规卷积替换为可分离卷积(深度方向,然后是1×1投影)。这种设计符合MobileNets的总体设计,并且在计算效率上更高。我们称此修改版本为SSDLite。与常规SSD相比,SSDLite显著降低了参数计数和计算成本,如表5所示。

对于MobileNetV1,我们遵循[33]中的设置。对于MobileNetV2,SSDLite的第一层连接到第15层的扩展(输出步幅为16)。第二层和其余的SSDLite层附着在最后一层的顶部(输出步幅为32)。此设置与MobileNetV1一致,因为所有层都已连接到相同输出步幅的特征图。

在这里插入图片描述
表5.比较使用MobileNetV2配置的SSD和SSDLite之间的大小和计算成本,并对80个类进行预测。

在这里插入图片描述
表6.MobileNetV2+SSDLite和其他实时检测器在COCO数据集对象检测任务中的性能比较。MobileNetV2+SSDLite以显著更少的参数和更小的计算复杂度实现了具有竞争力的准确性。所有模型都在trainval35k上进行训练,并在test-dev上进行评估。SSD/YOLOv2数字来自[35]。使用TF-Lite引擎的内部版本,Google Pixel 1手机的大内核的运行时间被报告。

两个MobileNet模型都使用开源TensorFlow对象检测API进行了训练和评估[38]。两个模型的输入分辨率均为320×320。我们对mAP(COCO挑战度量)、参数数量和乘法相加数量进行了基准测试和比较。结果如表6所示。MobileNetV2 SSDLite不仅是最有效的模型,也是三种模型中最准确的。值得注意的是,MobileNetV2 SSDLite的效率提高了20倍,体积缩小了10倍,但在COCO数据集上仍优于YOLOv2。

6 结论

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
残差块(Residual Block)是深度学习中的一种重要的网络结构,用于解决深层神经网络训练过程中的梯度消失和梯度爆炸问题。在TensorFlow中,可以通过自定义层或使用现有的库来实现残差块。 一个典型的残差块由两个主要部分组成:主路径(Main Path)和跳跃连接(Skip Connection)。主路径是指一系列的卷积层、批归一化层和激活函数层,用于提取输入数据的特征。跳跃连接是指将输入数据直接添加到主路径的输出上,以便在后续层中传递原始输入的信息。 以下是一个简单的残差块的TensorFlow实现示例: ```python import tensorflow as tf class ResidualBlock(tf.keras.layers.Layer): def __init__(self, filters, strides=1): super(ResidualBlock, self).__init__() self.conv1 = tf.keras.layers.Conv2D(filters, kernel_size=3, strides=strides, padding='same') self.bn1 = tf.keras.layers.BatchNormalization() self.relu = tf.keras.layers.ReLU() self.conv2 = tf.keras.layers.Conv2D(filters, kernel_size=3, strides=1, padding='same') self.bn2 = tf.keras.layers.BatchNormalization() self.downsample = tf.keras.Sequential([ tf.keras.layers.Conv2D(filters, kernel_size=1, strides=strides), tf.keras.layers.BatchNormalization() ]) def call(self, inputs, training=False): residual = inputs x = self.conv1(inputs) x = self.bn1(x, training=training) x = self.relu(x) x = self.conv2(x) x = self.bn2(x, training=training) if inputs.shape[-1] != x.shape[-1]: residual = self.downsample(inputs) x += residual x = self.relu(x) return x ``` 在这个示例中,我们定义了一个继承自`tf.keras.layers.Layer`的`ResidualBlock`类。在`__init__`方法中,我们定义了残差块的各个层,包括卷积层、批归一化层和激活函数层。在`call`方法中,我们实现了残差块的前向传播逻辑,包括主路径和跳跃连接的计算。 使用残差块时,可以将多个残差块堆叠在一起构成深层网络。这样可以有效地解决梯度消失和梯度爆炸问题,并提高网络的性能和训练效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值