当前位置:   article > 正文

深度学习之轻量级神经网络 MobileNet,从V1到V3_relu 流形

relu 流形

AdaptiveAvgPool2dAdaptiveAvgPool2d原文连接:知乎
其实介绍MobileNetV1(以下简称V1)只有一句话,MobileNetV1就是把VGG中的标准卷积层换成深度可分离卷积就可以了。

MobileNet V1-cvpr2017

MobileNetV1-2017

深度可分离卷积

可分离卷积主要有两种类型:空间可分离卷积深度可分离卷积

空间可分离

空间可分离就是将一个大的卷积核变成两个小的卷积核,比如将一个3×3的核分成一个3×1和一个1×3的核:
在这里插入图片描述

深度可分离卷积

在这里插入图片描述
深度可分离卷积就是将普通卷积拆分成为一个深度卷积和一个逐点卷积
标准的卷积操作:
在这里插入图片描述
输入一个12×12×3的一个输入特征图,经过5×5×3的卷积核卷积得到一个8×8×1的输出特征图。如果此时我们有256个特征图,我们将会得到一个8×8×256的输出特征图。
深度卷积
在这里插入图片描述
与标准卷积网络不一样的是,我们将卷积核拆分成为单通道形式,在不改变输入特征图像的深度的情况下,对每一通道进行卷积操作,这样就得到了和输入特征图通道数一致的输出特征图。如上图:输入12×12×3的特征图,经过5×5×1×3的深度卷积之后,得到了8×8×3的输出特征图。输入和输出的维度是不变的3。这样就会有一个问题,通道数太少,特征图的维度太少,能获取到足够的有效信息吗?
逐点卷积
在这里插入图片描述
在深度卷积的过程中,我们得到了8×8×3的输出特征图,我们用256个1×1×3的卷积核对输入特征图进行卷积操作,输出的特征图和标准的卷积操作一样都是8×8×256了。
标准卷积的参数量
卷积核的尺寸是 D k × D k × M D_k×D_k×M Dk×Dk×M,一共有N个,所以标准卷积的参数量是: D k × D k × M × N D_k×D_k×M×N Dk×Dk×M×N
标准卷积的计算量
卷积核的尺寸是 D k × D k × M D_k×D_k×M Dk×Dk×M,一共有N个,每一个都要进行 D w × D h D_w×D_h Dw×Dh 次运算,所以标准卷积的计算量是: D k × D k × M × N × D w × D h D_k×D_k×M×N×D_w×D_h Dk×Dk×M×N×Dw×Dh
深度可分离卷积的参数量
深度可分离卷积的参数量由深度卷积和逐点卷积两部分组成:
深度卷积的卷积核尺寸 D k × D k × M D_k×D_k×M Dk×Dk×M;逐点卷积的卷积核尺寸为 1 × 1 × M 1×1×M 1×1×M,一共有N个,所以深度可分离卷积的参数量是: D k × D k × M + M × N D_k×D_k×M+M×N Dk×Dk×M+M×N
深度可分离卷积的计算量
深度可分离卷积的计算量也是由深度卷积和逐点卷积两部分组成:
深度卷积的卷积核尺寸 D k × D k × M D_k×D_k×M Dk×Dk×M,一共要做 D w × D h D_w×D_h Dw×Dh 次乘加运算;逐点卷积的卷积核尺寸为 1 × 1 × M 1×1×M 1×1×M,有N个,一共要做 D w × D h D_w×D_h Dw×Dh 次乘加运算,所以深度可分离卷积的计算量是:
D k × D k × M × D w × D h + M × N × D w × D h D_k×D_k×M×D_w×D_h+M×N×D_w×D_h Dk×Dk×M×Dw×Dh+M×N×Dw×Dh
总的来说:
在这里插入图片描述
可以参数数量和乘加操作的运算量均下降为原来的: 1 / N + 1 / D k 2 1/N + 1/D_k^2 1/N+1/Dk2
我们通常所使用的是3×3的卷积核,也就是会下降到原来的九分之一到八分之一

假设
输出为一个224×224×3的图像,VGG网络某层卷积输入的尺寸是112×112×64的特征图,卷积核为3×3×128,标准卷积的运算量是:
3×3×128×64×112×112 = 924844032
深度可分离卷积的运算量是:
3×3×64×112×112+128×64×112×112 = 109985792
这一层,MobileNetV1所采用的深度可分离卷积计算量与标准卷积计算量的比值为:
109985792 /924844032 = 0.1189
与我们所计算的九分之一到八分之一一致。

V1卷积层

在这里插入图片描述

上图左边是标准卷积层,右边是V1的卷积层,虚线处是不相同点。V1的卷积层,首先使用3×3的深度卷积提取特征,接着是一个BN层,随后是一个ReLU层,在之后就会逐点卷积,最后就是BN和ReLU了。这也很符合深度可分离卷积,将左边的标准卷积拆分成右边的一个深度卷积和一个逐点卷积。

ReLU6

在这里插入图片描述
上图左边是普通的ReLU,对于大于0的值不进行处理,右边是ReLU6,当输入的值大于6的时候,返回6,relu6“具有一个边界”。作者认为ReLU6作为非线性激活函数,在低精度计算下具有更强的鲁棒性。(这里所说的“低精度”,我看到有人说不是指的float16,而是指的定点运算(fixed-point arithmetic))

V1网络结构

在这里插入图片描述
MobileNet的网络结构如上图所示。首先是一个3x3的标准卷积,s2进行下采样。然后就是堆积深度可分离卷积,并且其中的部分深度卷积会利用s2进行下采样。然后采用平均池化层将feature变成1x1,根据预测类别大小加上全连接层,最后是一个softmax层。整个网络有28层,其中深度卷积层有13层。
在这里插入图片描述
作为轻量级网络的V1在计算量小于GoogleNet,参数量差不多是在一个数量级的基础上,在分类效果上比GoogleNet还要好,这就是要得益于深度可分离卷积了。VGG16的计算量参数量比V1大了30倍,但是结果也仅仅只高了1%不到。
整个计算量基本集中在1x1卷积上。对于参数也主要集中在1x1卷积,除此之外还有就是全连接层占了一部分参数。
在这里插入图片描述

MobileNet V2-CVPR2018

Inverted Residuals and Linear Bottlenecks
V1的block如下图所示:
在这里插入图片描述
首先利用3×3的深度可分离卷积提取特征,然后利用1×1的卷积来扩张通道。用这样的block堆叠起来的MobileNetV1既能较少不小的参数量、计算量,提高网络运算速度,又能的得到一个接近于标准卷积的还不错的结果,看起来是很美好的。
但是!
有人在实际使用的时候, 发现深度卷积部分的卷积核比较容易训废掉:训完之后发现深度卷积训出来的卷积核有不少是空的:
在这里插入图片描述
ReLU做了些啥?
将低维流形的ReLU变换embedded到高维空间
假设在2维空间有一组由m个点组成的螺旋线Xm数据(如input),利用随机矩阵T映射到n维空间上并进行ReLU运算,即:
在这里插入图片描述
在这里插入图片描述
就是对一个n维空间中的一个“东西”做ReLU运算,然后(利用T的逆矩阵T-1恢复)对比ReLU之后的结果与Input的结果相差有多大
在这里插入图片描述
当n = 2,3时,与Input相比有很大一部分的信息已经丢失了。而当n = 15到30,还是有相当多的地方被保留了下来。
也就是说,对低维度做ReLU运算,很容易造成信息的丢失。而在高维度进行ReLU运算的话,信息的丢失则会很少
这就解释了为什么深度卷积的卷积核有不少是空。发现了问题,我们就能更好地解决问题。针对这个问题,可以这样解决:既然是ReLU导致的信息损耗,将ReLU替换成线性激活函数

Linear bottleneck

把最后的那个ReLU6换成Linear。(至于为什么换最后一个ReLU6而不换第一个和第二个ReLU6,看到后面就知道了。)
在这里插入图片描述

Expansion layer

深度卷积本身没有改变通道的能力,来的是多少通道输出就是多少通道。如果来的通道很少的话,DW深度卷积只能在低维度上工作,这样效果并不会很好,所以我们要“扩张”通道。既然我们已经知道PW逐点卷积也就是1×1卷积可以用来升维和降维,那就可以在DW深度卷积之前使用PW卷积进行升维(升维倍数为t,t=6)再在一个更高维的空间中进行卷积操作来提取特征
在这里插入图片描述
也就是说,不管输入通道数是多少,经过第一个PW逐点卷积升维之后,深度卷积都是在相对的更高6倍维度上进行工作。
在这里插入图片描述

Inverted residuals

回顾V1的网络结构,我们发现V1很像是一个直筒型的VGG网络。我们想像Resnet一样复用我们的特征,所以我们引入了shortcut结构,这样V2的block就是如下图形式:
在这里插入图片描述
在这里插入图片描述
可以发现,都采用了 1×1 -> 3 ×3 -> 1 × 1 的模式,以及都使用Shortcut结构。但是不同点呢:
ResNet 先降维 (0.25倍)、卷积、再升维。
MobileNetV2 则是 先升维 (6倍)、卷积、再降维。
刚好V2的block刚好与Resnet的block相反,作者将其命名为Inverted residuals
V2的block
在这里插入图片描述
在这里插入图片描述
左边是v1的block,没有Shortcut并且带最后的ReLU6。

右边是v2的加入了1×1升维,引入Shortcut并且去掉了最后的ReLU,改为Linear。步长为1时,先进行1×1卷积升维,再进行深度卷积提取特征,再通过Linear的逐点卷积降维。将input与output相加,形成残差结构。步长为2时,因为input与output的尺寸不符,因此不添加shortcut结构,其余均一致。

V2的网络结构

在这里插入图片描述
在这里插入图片描述

MobileNet V3-2019

MobileNetV3

MobileNetV3的相关技术

0.网络的架构基于NAS实现的MnasNet(效果比MobileNetV2好)
1.引入MobileNetV1的深度可分离卷积
2.引入MobileNetV2的具有线性瓶颈的倒残差结构
3.引入基于squeeze and excitation结构的轻量级注意力模型(SE)
4.使用了一种新的激活函数h-swish(x)
5.网络结构搜索中,结合两种技术:资源受限的NAS(platform-aware NAS)与NetAdapt
6.修改了MobileNetV2网络端部最后阶段

激活函数h-swish

swish
h-swish是基于swish的改进
在这里插入图片描述
swish论文的作者认为,Swish具备无上界有下界、平滑、非单调的特性。并且Swish在深层模型上的效果优于ReLU。仅仅使用Swish单元替换ReLU就能把MobileNet,NASNetA在 ImageNet上的top-1分类准确率提高0.9%,Inception-ResNet-v的分类准确率提高0.6%。
V3也利用swish当作为ReLU的替代时,它可以显著提高神经网络的精度。但是呢,作者认为这种非线性激活函数虽然提高了精度,但在嵌入式环境中,是有不少的成本的。原因就是在移动设备上计算sigmoid函数是非常不明智的选择。所以提出了h-swish.
h-swish
可以用一个近似函数来逼急这个swish,让swish变得硬(hard)。作者选择的是基于ReLU6,作者认为几乎所有的软件和硬件框架上都可以使用ReLU6的优化实现。其次,它能在特定模式下消除了由于近似sigmoid的不同实现而带来的潜在的数值精度损失。
在这里插入图片描述
下图是Sigmoid和swish的hard、soft形式:
在这里插入图片描述
可以简单的认为,hard形式是soft形式的低精度化。作者认为swish的表现和其他非线性相比,能够将过滤器的数量减少到16个的同时保持与使用ReLU或swish的32个过滤器相同的精度,这节省了3毫秒的时间和1000万MAdds的计算量。
并且同时,作者认为随着网络的深入,应用非线性激活函数的成本会降低,能够更好的减少参数量。作者发现swish的大多数好处都是通过在更深的层中使用它们实现的。因此,在V3的架构中,只在模型的后半部分使用h-swish(HS)。

网络结构搜索NAS

主要结合两种技术:资源受限的NAS(platform-aware NAS)与NetAdapt。
资源受限的NAS,用于在计算和参数量受限的前提下搜索网络来优化各个块(block),所以称之为模块级搜索(Block-wise Search)
NetAdapt,用于对各个模块确定之后网络层的微调每一层的卷积核数量,所以称之为层级搜索(Layer-wise Search)
最后一些层以及一些早期层计算代价比较高昂

对V2最后阶段的修改

当前模型是基于V2模型中的倒残差结构和相应的变体(如下图)。使用1×1卷积来构建最后层,这样可以便于拓展到更高维的特征空间。这样做的好处是,在预测时,有更多更丰富的特征来满足预测,但是同时也引入了额外的计算成本与延时
在这里插入图片描述
所以,需要改进的地方就是要保留高维特征的前提下减小延时。首先,还是将1×1层放在到最终平均池之后。这样的话最后一组特征现在不是7x7(下图V2结构红框),而是以1x1计算(下图V3结构黄框)。
在这里插入图片描述
在这里插入图片描述
这样的好处是,在计算和延迟方面,特征的计算几乎是免费的。最终,重新设计完的结构如下:
在这里插入图片描述
在不会造成精度损失的同时,减少10ms耗时,提速15%,减小了30m的MAdd操作。

V3的block

V3的block结构如下所示:
在这里插入图片描述
与V2的block相比较:
在这里插入图片描述

MobileNetV3的网络结构

MobileNetV3定义了两个模型: MobileNetV3-Large和MobileNetV3-Small。V3-Large是针对高资源情况下的使用,相应的,V3-small就是针对低资源情况下的使用。两者都是基于之前的简单讨论的NAS。
MobileNetV3-Large
在这里插入图片描述
MobileNetV3-Small
在这里插入图片描述
只有在更深层次使用h-swish才能得到比较大的好处。所以在上面的网络模型中,不论大小,作者只在模型的后半部分使用h-swish。

为什么MobileNet会这么快?

直接从用时多少的角度去讨论下这个问题。
最重要的“耗时杀手”就是conv,卷积层。也就是说,想要提高网络的运行速度,就得到提高卷积层的计算效率
MobileNet的95%的计算都花费在了1×1的卷积上
在计算机操作卷积时,需要将其存入内存当中再操作(按照“行先序”):
在这里插入图片描述
这样一来,特征图y11,y12,y21,y22的计算如下所示:
在这里插入图片描述
按照卷积计算,实线标注出卷积计算中的访存过程(对应数据相乘),我们可以看到这一过程是非常散乱和混乱的。直接用卷积的计算方式是比较愚蠢的。
这时候就要用到im2col操作。

im2col

通过牺牲空间的手段(约扩增K×K倍),将特征图转换成庞大的矩阵来进行卷积计算。
在这里插入图片描述
其实思路非常简单:
把每一次循环所需要的数据都排列成列向量,然后逐一堆叠起来形成矩阵(按通道顺序在列方向上拼接矩阵)。
比如Ci×Wi×Hi大小的输入特征图,K×K大小的卷积核,输出大小为Co×Wo×Ho,
输入特征图将按需求被转换成(K∗K)×(Ci∗Wo∗Ho)的矩阵,卷积核将被转换成Co×(K∗K)的矩阵
在这里插入图片描述
然后调用GEMM(矩阵乘矩阵)库加速两矩阵相乘也就完成了卷积计算。由于按照计算需求排布了数据顺序,每次计算过程中总是能够依次访问特征图数据,极大地提高了计算卷积的速度。 (不光有GEMM,还有FFt(快速傅氏变换))
在这里插入图片描述
Im2col()以一种内存访问规则的方式排列数据,虽然Im2col操作增加了很多数据冗余,但使用Gemm的性能优势超过了这个数据冗余的劣势。
所以标准卷积运算大概就是这样的一个过程:
在这里插入图片描述
那我们现在回到1×1的卷积上来,有点特殊。按照我们之前所说的,1×1的卷积的原始储存结构和进行im2col的结构如下图所示:
在这里插入图片描述
可以看到矩阵是完全相同的。标准卷积运算和1×1卷积运算对比如下图:
在这里插入图片描述
也就是说,1x1卷积不需要im2col的过程,所以底层可以有更快的实现,拿起来就能直接算,大大节省了数据重排列的时间和空间。
当然,这些也不是那么绝对的,因为毕竟MobileNet速度快不快,与CONV1x1运算的优化程度密切相关。如果使用了定制化的硬件(比如用FPGA直接实现3x3的卷积运算单元),那么im2col就失去了意义而且反而增加了开销。
95%的1×1卷积和优化的网络结构就是MobileNet能如此快的原因了。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/385054
推荐阅读
相关标签
  

闽ICP备14008679号