站点图标 AI技术聚合

MobileNet系列(万文长字详细讲解,一篇足以)

MobileNet系列(万文长字详细讲解,一篇足以)

前言

本篇讲一下CV相关的东西,MobileNet,想必大家已经很熟悉了,包括里面的一些模块,一些轻量型思想也是经常用到的。在这里我也是想着做一下总结,整理一下,也讲一讲自己的理解和看法。卷积神经网络CNN已经普遍应用在计算机视觉领域,并且已经取得了不错的效果。近年来CNN模型深度越来越深,模型复杂度也越来越高,如深度残差网络(ResNet)其层数已经多达152层。然而,在某些真实的应用场景如移动或者嵌入式设备,如此大而复杂的模型时难以被应用的。首先是模型过于庞大,面临着内存不足的问题,其次这些场景要求低延迟,或者说响应速度要快,想象一下自动驾驶汽车的行人检测系统如果速度很慢会发生什么可怕的事情。所以,研究小而高效的CNN模型在这些场景至关重要,至少目前是这样,尽管未来硬件也会越来越快。

目前的研究总结来看分为两个方向:

不管如何,其目标在保持模型性能(accuracy)的前提下降低模型大小(parameters size),同时提升模型速度(speed, low latency)。本文的主角MobileNet属于后者,其是Google最近提出的一种小巧而高效的CNN模型,其在accuracy和latency之间做了折中。

一、MobileNet V1详解

在V1中主要创新点是将普通卷积换成了深度可分离卷积,并引入了两个超参数使得可以根据资源来更加灵活的控制自己模型的大小。

那什么是深度分离卷积(Depthwise separable convolution)呢?

根据史料记载,可追溯到2012年的论文Simplifying ConvNets for Fast Learning,作者提出了可分离卷积的概念:

  Laurent Sifre博士2013年在谷歌实习期间,将可分离卷积拓展到了深度(depth),并且在他的博士论文Rigid-motion scattering for image classification中有详细的描写,感兴趣的同学可以去看看论文。其中可分离卷积主要有两种类型:空间可分离卷积和深度可分离卷积

空间可分离卷积

顾名思义,空间可分离就是将一个大的卷积核变成两个小的卷积核,比如将一个3*3的核分成一个3*1 和一个 1*3 的核:

 因为MobileNet并没有用到这块,所以在这里就不详细的讲了。

深度可分离卷积

深度级可分离卷积其实是一种可分解卷积操作(factorized convolutions)。其可以分解为两个更小的操作:深度卷积(depthwise  convolution) 和点卷积( pointwise convolution)。

对于一个标准卷积,输入一个12*12*3的一个输入特征图,经过 5*5*3的卷积核得到一个8*8*1的输出特征图。如果我们此时有256个特征图,我们将会得到一个8*8*256的输出特征图,如下图所示:

 对于深度卷积(其实就是组为1 的分组卷积)来说,将特征图通道全部进行分解,每个特征图都是单通道模式,并对每一个单独的通道特征图进行卷积操作。这样就会得到和原特征图一样通道数的生成特征图。假设输入12*12*3 的特征图,经过5*5*1*3的深度卷积之后,得到了8*8*3的输出特征图。输入和输出的维度是不变的3,这样就会有一个问题,通道数太少,特征图的维度太少,不能够有效的获得信息。

逐点卷积就是1*1卷积,主要作用就是对特征图进行升维和降维。在深度卷积的过程中,我们得到了8*8*3的输出特征图,我们用256个1*1*3的卷积核对输入特征图进行卷积操作,输出的特征图和标准的卷积操作一样都是8*8*256了。如下图:

 标准卷积与深度可分离卷积的过程对比如下:

 深度可分离卷积的优势

对于标准卷积来说,卷积核的尺寸是Dk*Dk*M,一共有N个,所以标准卷积的参数量是:

深度可分离卷积的参数量由深度卷积和逐点卷积两部分组成。深度卷积的卷积核尺寸Dk*Dk*M;逐点卷积的卷积核尺寸为1*1*M,一共有N个,所以深度可分离卷积的参数量是:

卷积核的尺寸是Dk*Dk*M,一共有N个,每一个都要进行Dw*Dh次运算,所以标准卷积的计算量是:

深度可分离卷积的计算量也是由深度卷积和逐点卷积两部分组成。深度卷积的卷积核尺寸Dk×Dk×M,一共要做Dw×Dh次乘加运算;逐点卷积的卷积核尺寸为1×1×M,有N个,一共要做Dw×Dh次乘加运算,所以深度可分离卷积的计算量是:

可以看到深度可分离卷积在计算量和参数量上面都远小于普通卷积,这样可以大大减小网络的推理延迟,加快速度。

到这里深度可分离卷积已经讲完了,接下来看一下MobileNet V1是如何应用的。如下图所示(图中应该是RELU6,图上打错了)。左图是传统卷积,右图是深度可分离卷积。更多的ReLU6,增加了模型的非线性变化,增强了模型的泛化能力。

在这里大家应该可以明白上面那么block的基本意思了,接下来就讲一下为什么使用Relu6,这样的好处是什么,为什么不使用Relu。

 其实Relu6就是普通的Relu函数,但是对输入的最大输出值做了约束,即最大的输出值为6。ReLU6函数与其导函数如下图所示:

那么为什么使用Relu6而不是Relu呢?其实是为了在移动端float16/int8等低精度设备时,也能够又很好的数值分辨率。如果对Relu的值并没有加以什么限制,输出范围可以从0到无限大,这就使得激活值很大,分布在一个很大的范围内,而低精度的float16等嵌入式设备就无法很好的精确描述如此大的范围,从而带来精度损失。这是本文第一个创新点。

第二个创新点:虽然MobileNet网络结构和延迟已经比较小了,但是很多时候在特定应用下还是需要更小更快的模型,为此引入了宽度因子alpha ,为了控制模型大小,文章引入了分辨因子 rho。

宽度因子 alpha (Width Mutiplier)在每一层对网络的输入输出通道数进行缩减,输出通道数由 M 到 alpha*M,输出通道数由 N 到 alpha*N,变换后的计算量为:

通常alpha 在(0,  1] 之间,比较典型的值由1, 0.75, 0.5, 0.25。计算量和参数数量减少程度与未使用宽度因子之前提高了 1/alpha**2倍。

 分辨率因子 rho (resolution multiplier)用于控制输入和内部层表示,即用分辨率因子控制输入的分辨率,深度卷积和逐点卷积的计算量为:

通常 rho 在(0,  1] 之间,比较典型的输入分辨为 224, 192, 160, 128。计算量量减少程度与未使用宽度因子之前提高了 1/(alpha**2*rho*rho) 倍,参数量没有影响。通过两个超参,可以进一步缩减模型,文章中也给出了具体的实验结果,在这里我就贴图了。

在MobileNetV1中,深度卷积网络的每个输入信道都应用了单个滤波器。然后,逐点卷积应用 1*1 卷积网络来合并深度卷积的输出。这种标准卷积方法既能滤波,又能一步将输入合并成一组新的输出。在这之中,深度可分离卷积将其分为两次,一层用于滤波,另一层则用于合并。MobileNet的网络结构如下,一共由 28层构成(不包括AvgPool 和 FC 层,且把深度卷积和逐点卷积分开算),其除了第一层采用的是标准卷积核之外,剩下的卷积层都是用Depth Wise Separable  Convolution。

 二、MobileNet V2详解

MobileNet V2架构在 2018年初发布,MobileNet V2基于MobileNet V1的一些思想,并结合新的思想来优化。从架构上来看,MobileNet V2为架构增添了两个新模块:1,引入了层与层之间的线性瓶颈;2,瓶颈之间的快捷连接。MobileNetV2之中的核心思想是,瓶颈对模型的中间输入和输出进行编码,而内层则用于封装模型从较低级别概念(如:像素等)转换到较高级别描述符(如:图像类别等)的能力(看不懂没关系,后面还会仔细讲解的)。最后,与传统的剩余连接一样,快捷方式能够实现更快地训练速度和更高的准确率。

MobileNet V1 的结构较为简单,另外,主要的问题还是在Depthwise Convolution 之中,Depthwise Convolution 确实降低了计算量,但是Depthwise部分的 Kernel 训练容易废掉,即卷积核大部分为零,作者认为最终是经过 ReLU 出现输出为 0的情况,并且论文中作者给出了解释。即Relu会对通道数比较低的特征图造成较大的信息损耗,而这些信息损耗就就容易造成大部分卷积核为0的情况出现。

具体来说当低维信息映射到高维,然后经过Relu映射回低维时,若映射到的维度相对较高,则信息变换回去的损失较小;若映射到的维度相对较低,则信息变换回去后损失很大,如下图所示:

图中可以看到,当原始输入维度数增加到 15 以后再加 ReLU,基本不会丢失太多的信息;但如果只把原始输入维度增加到 2~5维度后再加 ReLU,则会出现较为严重的信息丢失。因此,认为对低维度做ReLU运算,很容易造成信息的丢失。而在高维度进行ReLU运算的话,信息的丢失则会很少。另外一种解释是,高维信息变换回低维度信息时,相当于做了一次特征压缩,会损失一部分信息,而再进行过ReLU后,损失的部分就更大了。ReLU的特性使得对于负值输入,其输出为0,而且降维本身就是特征压缩的过程,这样就使得特征损失更为严重了作者为了这个问题,就将ReLU替换成线性激活函数。 

V2在DW卷积之前新加了一个PW卷积,这么做的原因是因为DW卷积由于本身的计算特性决定它自己没有改变通道数的能力,上一层给他多少通道,他就只能输出多少通道。所以如果上一层的通道数本身很少的话,DW也只能很委屈的低维空间提取特征,因此效果不是很好,现在V2为了改善这个问题,给每个 DW 之前都配备了一个PW,专门用来升维,定义升维系数为 t=6,这样不管输入通道数Cin 是多是少,经过第一个 PW 升维之后,DW都是在相对的更高维(t*Cin)是多是少,经过第一个 PW升维之后,DW 都是在相对的更高维(t*Cin)进行辛勤工作的。而且V2去掉了第二个PW的激活函数,论文作者称其为 Linear Bottleneck。这么做的渊源,是因为作者认为激活函数在高维空间能够有效的增加非线性,而在低维空间时则会破坏特征,不如线性的效果好。由于第二个PW的主要功能就是降维,因此按照上面的理论,降维之后就不宜再使用ReLU6了。这一操作也叫做Inverted Residuals和Linear Bottlenecks。

这个可以翻译成“倒残差模块”。什么意思呢?我们来对比一下残差模块和倒残差模块的区别。

  • 残差模块:输入首先经过1*1的卷积进行压缩,然后使用3*3的卷积进行特征提取,最后在用1*1的卷积把通道数变换回去。整个过程是“压缩-卷积-扩张”。这样做的目的是减少3*3模块的计算量,提高残差模块的计算效率。
  • 倒残差模块:输入首先经过1*1的卷积进行通道扩张,然后使用3*3的depthwise卷积,最后使用1*1的pointwise卷积将通道数压缩回去。整个过程是“扩张-卷积-压缩”。为什么这么做呢?因为depthwise卷积不能改变通道数,因此特征提取受限于输入的通道数,所以将通道数先提升上去。文中的扩展因子为6。

用下图表示再合适不过了。

 Mobilenet V2 的网络模块如下图所示,当 stride=1时,输入首先经过 1*1 卷积进行通道数的扩张,此时激活函数为 ReLU6;然后经过3*3的depthwise卷积,激活函数是ReLU6;接着经过1*1的pointwise卷积,将通道数压缩回去,激活函数是linear;最后使用shortcut,将两者进行相加。而当stride=2时,由于input和output的特征图的尺寸不一致,所以就没有shortcut了。

 三维图形:

 最后,给出V2的网络结构。其中,t 为扩张稀疏,c 为输出通道数,n 为该层重复的次数,s为步长。可以看出 V2 的网络比V1网络深了很多,V2有54层。

 三、MobileNet V3详解

  MobileNet V3 发表于2019年,Mobilenet-V3 提供了两个版本,分别为 MobileNet-V3 Large以及 MobileNet-V3 Small,分别适用于对资源要求不同的情况。V3结合了v1的深度可分离卷积、v2的Inverted Residuals和Linear Bottleneck、SE模块,利用NAS(神经结构搜索)来搜索网络的配置和参数。很巧的是我研究生期间做的工作就是NAS,所以写这一部分的时候真的是舒舒服服啊,虽然在这里不会讲太多关于NAS的东西,但是看到NAS还是倍感亲切呀⭐。

首先列举一下V3的一些床创新点,然后在根据这些点分别展开讲解。

修改初始卷积核的个数

 对于v2的输入层,通过3*3卷积将输入扩张成32维。作者发现,其实可以32再降低一点,所以这里改成了16,在保证了精度的前提下,降低了3ms的速度。关于这一点改变可以在最后给出的网络结构中看到

更改网络末端计算量大的层

在MobileNetV2中,在Avg Pooling之前,存在一个 1*1 的卷积层,目的是提高特征图的维度,更有利于结构的预测,但是这其实带来了一定的计算量了。所以这里作者做了修改,将其放在 avg Pooling 的后面,首先利于 avg Pooling 将特征图的大小由 7*7 降到了 1*1,降到 1*1 后,然后再利用 1*1 提高维度,这样就减少了 7*7 =49 倍的计算量。并且为了进一步的降低计算量,作者直接去掉了前面纺锤型卷积的 3*3 以及 1*1 卷积,进一步减少了计算量,就变成了如下图第二行所示的结构,作者将其中的 3*3 以及 1*1 去掉后,精度并没有得到损失,这里降低了大约 10ms的延迟,提高了15%的运算速度,且几乎没有任何精度损失。

 引入H-Swish激活函数

前面V2中在block最后一个逐点卷积之后换成了线性激活函数,之前的激活函数都是Relu6,但是作者发现Swish函数能够有效的提高网络的精度,但是因为Swish函数中包含Sigmoid函数这就使得计算量太大了,所以作者在这里提出了H-Swish激活函数。

Swish图像:

 (关于激活函数我还会再写一篇文章进行详细讲解的)Swish特点 

 h-swish:

这种非线性在保持精度的情况下带来了很多优势,首先ReLU6在众多软硬件框架中都可以实现,其次量化时避免了数值精度的损失,运行快。这一非线性改变将模型的延时增加了15%。但它带来的网络效应对于精度和延时具有正向促进,剩下的开销可以通过融合非线性与先前层来消除。

引入了SE模块

这里呢也是我着重想讲的一块,主要是其余讲解MobileNet的文章对这一块的东西并没有很详细的讲解,大多都是一带而过。对于CNN网络来说,其核心计算是卷积算子,其通过卷积核从输入特征图学习到新特征图。从本质上讲,卷积是对一个局部区域进行特征融合,这包括空间上(H和W维度)以及通道间(C维度)的特征融合。我们可以发现卷积实际上是对局部区域进行的特征融合。 这也导致了普通卷积神经网络的感受野不大,当然也可以设计出更多的通道特征来增加这个,但是这样做导致了计算量大大的增加。因此为了空间上融合更多特征融合,或者是提取多尺度空间信息。也提出了许多不同的方法如Inception网络的多分支结构。对于channel维度的特征融合,卷积操作基本上默认对输入特征图的所有channel进行融合。而SENet网络的创新点在于关注channel之间的关系,希望模型可以自动学习到不同channel特征的重要程度。为此,SENet提出了Squeeze-and-Excitation (SE)模块,如下图所示:

 其实这就是一个对于多通道而言的一个自注意力机制,通过给不同的通道赋予权重,使得特征图对有用的特征通道进行提升,而反过来抑制对当前任务用处不大的特征。具体的SE操作见下图。

 这个就是SE模块里面的所有操作,首先使用一个全局池化层将每个通道变成一个具体的数值,然后进行两个全连接层的学习,赋予权值。最后通过一个H-Sigmoid函数获取最终的权重,然后赋值给一开始的特征图。目前大多数的主流网络都是基于这两种类似的单元通过repeat方式叠加来构造的。由此可见,SE模块可以嵌入到现在几乎所有的网络结构中。通过在原始网络结构中的building block单元中嵌入SE模块,我们可以获得不同种类的SENet。如SE-BN-Inception,SE-ResNet等

在V3中的三维图如下所示:

 在v2的 bottleneck 结构中引入SE模块,并且放在了 depthwise filter 之后,SE模块是一种轻量级的通道注意力模块,因为SE结构会消耗一定的时间,所以在depthwise之后,经过池化层,然后第一个fc层,通道数缩小4倍,再经过第二个fc层,通道数变换回去(扩大4倍),然后与depthwise进行按位相加,这样作者发现,即提高了精度,同时还没有增加时间消耗。

MobileNet V3 网络结构

MobileNet V3 首先使用 MnasNet 进行粗略结构的搜索,然后使用强化学习从一组离散的选择中选择最优配置。之后,MobileNet V3再使用 NatAdapt 对体系结构进行微调,这体现了  NetAdapt 的补充功能,它能够以较小的降幅对未充分利用的激活通道进行调整。

(1)资源受限的NAS(platform-aware NAS):计算和参数量受限的前提下搜索网络的各个模块,所以称之为模块级的搜索(Block-wise Search)。

(2)NetAdapt:用于对各个模块确定之后网络层的微调。

        对于模型结构的探索和优化来说,网络搜索是强大的工具。研究人员首先使用了神经网络搜索功能来构建全局的网络结构,随后利用了NetAdapt算法来对每层的核数量进行优化。对于全局的网络结构搜索,研究人员使用了与Mnasnet中相同的,基于RNN的控制器和分级的搜索空间,并针对特定的硬件平台进行精度-延时平衡优化,在目标延时(~80ms)范围内进行搜索。随后利用NetAdapt方法来对每一层按照序列的方式进行调优。在尽量优化模型延时的同时保持精度,减小扩充层和每一层中瓶颈的大小。

  除此之外,MobileNet 的另一个新颖的想法是在核心架构中加入一种名为“Squeeze-and-Excitation” 的神经网络(简称 SENet,也是ImageNet 2017 图像分类冠军)。该神经网络的核心思想是通过显式的建模网络卷积特征通道之间的互相依赖关系,来提高网络所产生表示的质量。具体而言,就是通过学习来自动获得到每个特征的重要程度,然后依照这一结果去提升有用的特征并抑制对当前任务用处不大的特征。

  为此,开发者提出了一种允许网络进行特征重新校准的机制。通过该机制,网络可以学习使用全局信息来选择地强调信息性特征,并抑制不太有用的特征。而在MobileNet V3的例子中,该架构扩展了 MobilenetV2 ,将 SENet 作为搜索空间的一部分,最终得到了更稳定的架构。

  Mobilenet V3 还有一个有趣的优化,则是重新设计了体系结构中一些运行成本较高的层。第二代 MobilenetV2 中的一些层是模型准确性的基础,但也引入了潜在变量。通过合并一些基本的优化功能。MobileNet V3 在能够不牺牲准确率的情况下,删除了 MobilenetV2 体系结构中三个运行成本较高的层。

   V3的结构如下图,作者提供了两个版本的V3,分别是large和small,对应与高资源和低资源的情况,两者都是NAS进行搜索出来的。

 讲到这里,这个系列基本就算完事了,万文长字啊,不敢说全网最全,但是我能想到的基本都在这里了,也是翻遍了很多优秀的博客进一步总结出来的,有啥不对的希望大家能够及时指出,谢谢!!!

参考:卷积神经网络学习笔记——轻量化网络MobileNet系列(V1,V2,V3)

文章出处登录后可见!

已经登录?立即刷新
退出移动版