文章目录
-
- 1. LeNet(1998)
- 2. AlexNet(2012)
- 3. VGG(2014)
-
- 4. Inception Net(2014)
-
- 4.1 Inception V1(GoogLeNet)
- 4.2 Inception V2(2015)
- 4.3 Inception V3(2015)
-
- 4.3.1 关于四条设计神经网络的原则
- 4.3.2 关于如何分解大卷积核的卷积层
- 4.3.3 关于辅助分类器的作用
- 4.3.4 关于如何有效减少特征图尺寸
- 4.4 Inception Net V4(2016)
- 4.5 Xception(2016)
- 5. ResNet(2015)
-
- 5.1 残差结构
- 5.2 关于 Residual Network 中 Identity Mapping 的讨论
- 6. DenseNet(2016)
-
- 7. MobileNet(2017)
-
- 7.1 MobileNet V1(2017)
-
- 7.1.1 深度可分离卷积
- 7.1.2 MobileNet v1卷积层
- 7.1.3 V1 网络结构
- 7.1.4 缺点
- 7.2 MobileNet V2(2018)
-
- 7.2.1 ReLU做了些啥
- 7.2.2 Linear bottleneck
- 7.2.3 Expansion layer
- 7.2.4 Inverted residuals
- 7.2.5 V2的block
- 7.2.6 V2网络结构
- 7.3 MobileNet V3(2019)
-
- 7.3.1 MobileNetV3的相关技术
- 7.3.2 激活函数h-swish
- 7.3.3 网络结构搜索NAS
- 7.3.4 对V2最后阶段的修改
- 7.3.5 V3的block
- 7.3.6 MobileNetV3的网络结构
- 7.4 为什么MobileNet会这么快?
-
- 7.4.1 MobileNet资源分布
- 7.4.2 imcol
- 8. ShffuleNet(2017)
-
- 8.1 ShuffleNet V1
-
- 8.1.1 概论
- 8.1.2 Group convolution 和 Channel Shuffle
- 8.1.3 ShuffleNet Unit
- 8.1.4 网路结构
- 8.2 ShuffleNet V2(2018)
-
- 8.2 1 高效CNN网络设计的四个准则
- 8.2.2 ShuffleNet v1分析
- 8.2.3 ShuffleNet v2的设计
- 参考链接
1. LeNet(1998)
- 首次提出卷积神经网络,定义基本框架:卷积+池化+全连接
- 定义卷积层:局部连接(引入感受野),参数共享
- 池化进行下采样,减少计算量
- 使用Tanh为激活函数(tanh原点对称,比sigmoid收敛快(原因))
- 关于全连接层,直接将特征图(Featuremap)展开输入到全连接层,会导致 CNN 仅适用于指定尺度的图像上。LeCun 认为 CNN 应该尽可能适用与各种尺度的图像上,这一点也得到许多人的认同。对于分类(Classification)问题,利用全局平均池化(Global Average Pooling, GAP)操作代替特征图的拉伸,这样 CNN 便可以处理各种尺度的图像了。
一般来说,卷积和池化的核大小相等
卷积计算: S i z e o u t = ( S i z e i n − K e r n e l + 2 ∗ P a d d i n g ) / S t r i d e + 1 Size_{out}=(Size_{in}-Kernel+2*Padding)/Stride+1 Sizeout=(Sizein−Kernel+2∗Padding)/Stride+1
池化计算: S i z e o u t = ( S i z e − K e r n e l ) / S t r i d e + 1 Size_{out}=(Size-Kernel)/Stride+1 Sizeout=(Size−Kernel)/Stride+1
2. AlexNet(2012)
-
采用双GPU网路结构,从而可以设计出更“大”、更“深”的网络(相较于当时的算力来说)
-
采用 ReLU 代替 Tanh,稍微解决梯度消失问题(Gradient Vanishing Problem),加快网络收敛速度。(激活函数比较)
-
提出局部相应归一化(LRN, Local Response Normalization),据作者所言,该操作能减少指标 Top-1/Top-5 Error Rate 1.4%/1.2%。(关于 Normalization 的发展历程)
-
令 Pooling 操作中的 stride 小于池化核的大小,从而使相邻的池化区域存在重叠部分,这一操作称为 Overlapping Pooling。据作者所言,这一操作能减少指标 Top-1/Top-5 Error Rate 0.4%/0.3%,并且减少过拟合现象。
-
对训练数据进行随机裁剪(Random Crop),将训练图像由 256 × 256 裁剪为 224 × 224,并做随机的镜像翻转(Horizontal Reflection)。并在测试时,从图像的四个角以及中心进行裁剪,并进行镜像翻转,这样可以得到 10 个 Patch,将这些 Patch 的结果进行平均,从而得到最终预测结果。(类似于Bagging)
-
对训练图像做 PCA(主成分分析),利用服从 (0,0.1) 的高斯分布的随机变量对主成分进行扰动。作者指出,这一操作能减少指标 Top-1 Error Rate 1%。
-
利用 Dropout 避免网络过拟合。
3. VGG(2014)
包括:VGG-11/VGG-13/VGG-16/VGG-19
3.1 网络结构
- VGG 其实跟 AlexNet 有一定的相似之处,都是由五个卷积层与激活函数叠加的部分和三个全连接层组成,但是不同的是,VGG加“深”了前面由五个卷积层与激活函数叠加的部分,使得每部分并不是一个卷积层加一个激活函数组成,而是多个这样的组合组成一部分(有人习惯称这个为 Conv Layer Group),每个部分之间进行池化操作。
- 此外,VGG 与当时其他卷积神经网络不同,不采用感受野大的卷积核(如:7 × 7,5 × 5),反而采用感受野小的卷积核(3 × 3)。关于这样做的好处,作者指出有如下两点:减少网络参数量;由于参数量被大幅减小,于是可以用多个感受野小的卷积层替换掉之前一个感受野大的卷积层,从而增加网络的非线性表达能力。
- 从 VGG-16 开始,VGG 引进卷积核大小为 1 × 1 的卷积层,使得在不影响特征图大小的情况下,增加网络的非线性表达能力。
3.2 其他细节
- 作者提到曾使用局部响应归一化(LRN),但是并没有任何效果提升,反而还使得内存使用和计算时间增加。
- 在训练过程中,作者为避免随机初始化对训练带来负面影响,使用预训练模型,于是利用小的网络参数初始化大的网络参数(比如用以训练好的 VGG-11 去初始化部分 VGG-13 的网络参数)。
- 对训练图像进行预处理时,先做宽高等比缩放(原文用的词是 isotropically rescaled,即同质化缩放),使其最短边长度达到 S,接着再做随机裁剪。其中,关于 S 的设置,作者提出了两种训练方案:Single-Scale Training,Multi-Scale Training。
4. Inception Net(2014)
4.1 Inception V1(GoogLeNet)
- 与 VGG 不同,Inception 结构虽然也倾向于加“深”网络结构,从而提高模型的表达能力,并且抛弃全连接层(虽然 GoogLeNet 最后加了一层全连接层,但这是作者为了其他人能更方便的利用模型进行微调(Finetune)
- 作者在文中指出,提高模型表达能力的最直接的办法就是增加模型的“大小”,而这又会导致两个问题的产生:模型越大,其网络参数也就越大,就越容易产生过拟合现象,所以就需要更大的数据集,然而大型数据集的构建成本是很高昂的;模型越大,对于计算资源的需求就越大,这在现实任务中是难以接受的。而作者认为解决这两个问题的基本方法是将全连接层,甚至是卷积层改为稀疏的网络结构
- 作者所设计的 Inception Module 与常见的网络结构不同,打破了常规的卷积层串联的设计思路,选择将卷积核大小为 1 × 1,3 × 3,5 × 5 的卷积层和池化核大小为 3 × 3 的池化层进行并联,并将各自所得到的特征图进行 Concatenate 操作合并在一起,作为后续的输入。
- 之所以 Inception Module 由上图左侧发展被改进为上图右侧,是因为:作者希望模型中深层的 Inception Module 可以捕捉到 Higher Abstraction,所以作者认为深层的 Inception Module中的卷积层的空间集中度应该逐渐降低,以此捕捉更大面积的特征。故,作者令越深层的 Inception Module 中,卷积核大小为 3 × 3 和 5 × 5 这两个卷积层的输出通道数占比越多。但这又将导致计算量增加,所以为了解决这个问题,作者在原有 Inception Module 的基础上,利用卷积核大小为 1 × 1 的卷积层进行降维操作,从而减小计算量(这建立在一个假设之上:即使是低维的映射也可能包含关于相关图像区域的大量信息)。
- 由于 Inception Module 保持了输入输出的尺寸一致,故 GoogLeNet 可以由 Inception Module 进行模块化搭建。仔细观察 GoogLeNet 的结构,你会发现作者在 Inception Module (4a) 和 (4d) 设置了额外的辅助 Loss,用以增加向后传导的梯度,缓解梯度消失问题,同时增加额外的正则化操作。在文章中,作者指出这样操作的目的主要是使得模型中低层的特征也具备很好的区分能力。(文章中,这两个额外的 Loss 会乘上衰减系数 0.3,与最后的 Loss 相加,作为整个模型的 Loss)
4.2 Inception V2(2015)
2015 年,谷歌提出了 Batch Normalization 操作,将其添加在之前的 GoogLeNet,并修改了一定的结构与实验设置,得到了 Inception Net V2
- 将 Inception Module 中卷积核大小为 5 × 5 的卷积层用两个相连的卷积核大小为 3 × 3 的卷积层进行替换。作者指出,这一操作是的模型参数增加了 25%,计算成本提高了 30%。
- 将输出大小为 28 × 28 的 Inception Module 的个数由两个提升到三个,即增加 Inception Module (3c)。
- 在 Inception Module 中进行池化操作(有时为平均池化(Average Pooling),有时为最大池化(Max Pooling))
- 两个 Inception Module 之间不再进行池化操作,仅在 Inception Module (3c) 和 (4e) 前添加 stride-2 conv/pooling layer。
- 将网络第一层的卷积层替换为深度乘子为 8 的可分离卷积(参考卷积神经网络中的Separable Convolution 和 CNN中千奇百怪的卷积方式大汇总)
- 作者在文中指出,他们并不是直接简单的将 BN 添加到网络中的,还做了如下的改动:增大学习率,移除 Dropout,减小 L2 正则化项,加速学习率衰减,移除 LRN,更彻底的打乱训练数据,减少光学畸变 (数据增强)
4.3 Inception V3(2015)
论文中,作者首先四条设计神经网络的原则,接着提出如何分解大卷积核的卷积层,接着反思辅助分类器(Auxiliary Classifier)的作用,接着按照自己所提的第一条原则对常见的 Size Reduction 做了改进,最后将以上改进添加进之前的网络结构中。
4.3.1 关于四条设计神经网络的原则
- Avoid representational bottlenecks, especially early in the network.
- Higher dimensional representations are easier to process locally within a network.
- Spatial aggregation can be done over lower dimensional embeddings without much or any loss in representational power.
- Balance the width and depth of the network.
4.3.2 关于如何分解大卷积核的卷积层
- 利用连续的两层小卷积核的卷积层代替大卷积核的卷积层(添加在卷积层后的激活函数都为 ReLU 比 Linear+ReLU 好)
- 利用连续的两层非对称的卷积层(卷积核大小为 n × 1 和 1 × n)代替原有卷积层(卷积核大小为 n × n)(最好在模型的中间层使用(适用的FeatureMap大小范围为 12~20))
4.3.3 关于辅助分类器的作用
GoogLeNet 曾在 Inception Module (4a) 和 (4d) 设置了额外的辅助 Loss,即设置了辅助分类器,当时作者对其的理解是:使梯度更好的回传到低层,避免梯度消失问题,提高模型的收敛速度与最终表现。
但是作者通过实验发现:在训练初期,有无辅助分类器并无区别;在训练后期,有辅助分类器将提高模型的最终表现;此外,作者去掉 GoogLeNet 中较低的辅助分类器的分支,发现此举并不会导致模型性能有明显的降低。最后,作者认为:辅助分类器起到的作用更像是正则化。
4.3.4 关于如何有效减少特征图尺寸
- 在分类任务中,许多模型都会随着深度的整长不断通过池化操作缩小特征图尺寸,以此减小模型的“体积”。由于池化操作会导致特征图中的许多信息丢失,许多模型都习惯在特征图的宽与高缩小一半的同时,利用卷积核为 1 × 1 的卷积层使得特征图的通道数量翻倍(即 C × W × H -> 2C × W/2 × H/2),以此减少池化操作所带来的信息丢失。
- 这样操作有两种选择:先进行升维操作,再进行池化操作;先进行池化操作,再进行升维操作。作者指出,根据原则一,我们应先进行升维操作,再进行池化操作。
- 当然,这样做会导致计算量增加,于是作者提出了另一种做法,如下图所示:
4.4 Inception Net V4(2016)
在 Inception-v4 中,作者将 Inception 和 ResNet 结合在一起,推出了 Inception-ResNet-v1,Inception-ResNet-v2,Inception-v4。其中,Inception-v4 的总体结构如上图所示,各个模块细节如下图所示。
可以看得出来,Inception-v4 的结构设计非常复杂,需要大量的实验验证以及工程经验,一般只有大厂才有能力做这样的工作,这也是为什么最近 NAS 这么火的原因吧。
4.5 Xception(2016)
论文中,Google 利用 深度可分离卷积对 Inception V3 进行了改进,并结合 Residual Connection 设计了新的网络。
作者在文章开头便指出 Inception Module 背后的思路是通过一系列操作使得模型的学习更加简单有效(分别单独学习通道之间的关系和空间关系),这意味着 Inception Module 假设通道之间的关系和空间关系是可以被分离开的(这个假设的一个变体就是 width-wise correlation and height-wise correlation,即 Inception V3 里的卷积核大小为 7×1 和 1×7 的卷积层)。接着,作者由 Inception V3 中的 Inception Module 进行演变,得到极端版本的 Inception Module,与 Depthwise Separable Convulotion 思路一致,如下图所示:
作者指出 “extreme” version of Inception Module 与 Depthwise Separable Convolution 主要存在两点不同:
- Depthwise Convolution 和 Pointwise Convolution 的顺序不同。不过,作者认为这一点并不重要。
- 在 Inception Module 中,Depthwise Convolution 和 Pointwise Convolution 后都会接着 ReLU;而 Depthwise Separable Convolution 一般仅在 Pointwise Convolution 后接着 ReLU。作者认为这一点差异比较重要,并在后续的实验中进行了讨论(后面发现在 Pointwise Convolution 后接 ReLU/ELU,都不如中间不添加激活函数的表现效果)。
- 最后,作者提出了新的网络:Xception(结合了 Inception Module, Residual Connection, Depthwise Seperable Convolution),网络结构如下所示:
5. ResNet(2015)
5.1 残差结构
2015 年,Kaiming He 提出了 ResNet(拿到了 2016 年 CVPR Best Paper Award),不仅解决了神经网络中的退化问题(Degrade Problem,即相较于浅层神经网络,深层神经网络的深度到达一定深度后,拟合能力反而更差,训练/测试误差更高),还在同年的 ILSVRC 和 COCO 竞赛横扫竞争对手,分别拿下分类、定位、检测、分割任务的第一名。(个人觉得,ResNet真的属于现象级论文,所提出的残差结构大幅提高了神经网络的拟合能力)
- 提出了残差结构(Residual Block,如上图左侧所示),使得原本所要拟合的函数 H ( x ) H(x) H(x),改为 F ( x ) F(x) F(x) ,其中, H ( x ) = F ( x ) + x H(x)=F(x)+x H(x)=F(x)+x 。虽然在“多个非线性层可以拟合任意函数”这一假设下二者并无区别,但是 Kaiming 假设模型学习后者,将更容易进行优化与收敛。(在残差结构中,模型利用 Shortcut 进行 Identity Mapping,这样也解决了梯度消失现象)
- 由于 Residual Block 并不需要额外的参数以及计算量,Kaiming 在文中以此做了多组对照实验,证明该网络结构的有效性(所用的两个 ResNet 为 ResNet-18 和 ResNet-34)。但是,若要将模型的深度继续不断增加,需要对其进行改进:将原先的 Residual Block(上图右侧所示,也被称作 Basic Block) 改进为 Bottleneck Block,减少模型的参数与计算量。
- 对训练数据进行数据增强:从 [256,480] 随机采样,作为图像最短边长度,进行宽高等比缩放;随机裁剪 224 * 224,并进行随机镜像翻转;并对所有训练图像的每个像素值进行统计,并减去该平均值。
- 对测试数据使用 10-crop 测试方法。
- ResNet 在非线性层后,激活函数前使用 Batch Normalization。
5.2 关于 Residual Network 中 Identity Mapping 的讨论
论文中对 ResNet 中的 Identity Mapping 进行了详细的讨论(前向传导、后向传导的分析),并且设计并尝试了多种不同的 Shortcut Connection 设计(如上图所示),并在最后对激活函数做了讨论,从而提出了新的 Residual Block(为与原版结构区分,Kaiming 称其为 full pre-activateion Residual Block)。
移除了 Short Connection 中的 ReLU,并将 Residual Mapping 中的 BN 和 ReLU 提前至对应的神经网络层前。
6. DenseNet(2016)
DenseNet 即没从网络的深度入手,也没从网络的宽度入手,而是对每层的 FeatureMap 进行特征复用,以此缓解梯度消失问题,加强网络中特征的传递,有效对特征进行复用,并在提高网络的表现效果的同时减少了网络的参数量。
在 Dense Block 中,每层卷积层的输入为在该 Block 中之前所有卷积层所输出的 FeatureMap 的 concation 结果 (此处与 ResNet 不同,ResNet 中将结果进行 add )。作者在文中指出,ResNet 成功的关键点在于:‘they create short paths from early layers to later laters’;作者认为自己之所以提出的 Dense Block 这样的结果,就是为了保证层与层之间的信息能最大程度的保存。
6.1 网络结构
- DenseNet 与其他 CNN 类似,同样保留着 down-sampling layers 的设计,网络中包含四个 Dense Block 和四个 Transition Layer,分别处理不同 Size 的 FeatureMap / 对 FeatureMap 进行 Pooling 操作。
- 根据 Identity Mappings in Deep Residual Networks,作者在 Dense Block 中将 BN 和 ReLU 设置在卷积层前面。由于 Dense Block 的特征复用操作,越后面的卷积层,其输入的 Channel 越大。故作者在 DenseNet 中引用了 Bottleneck Layer,即:BN-ReLU-Conv(1×1)-BN-ReLU-Conv(3×3),以此避免计算量的快速增长。(文中记使用 Bottleneck Layer 的 DesnseNet 为 DenseNet-B)
- 作者还尝试在 Transition Layer 中对 FeatureMap 的 Channel 数量进行缩减,设输入的 FeatureMap 的 Channel 数为 m m m, θ \theta θ 为压缩因子,则输出的 FeatureMap 的 Channel 数为 θ m \theta m θm。(实验中,作者设置 θ = 0.5 \theta=0.5 θ=0.5;,并记使用 Bottleneck Layer 以及设置 Transition Layer 的 θ < 1 \theta< 1 θ<1的 DesnseNet 为 DenseNet-BC)
- 为保持特征复用的实现(即同意 DenseNet 中的所有 FeatureMap 大小一致),作者令 Dense Block 中的卷积层的卷积核大小为 3 × 3,padding 为 1,且采用 zero-padding。
7. MobileNet(2017)
7.1 MobileNet V1(2017)
MobileNetV1就是把VGG中的标准卷积层换成深度可分离卷积就可以了。
可分离卷积分为:空间可分离卷积和深度可分离卷积。
空间可分离:将一个大的卷积核变成两个小的卷积核,比如将一个3×3的核分成一个3×1和一个1×3的核。
7.1.1 深度可分离卷积
- 标准卷积:
输入一个12×12×3的一个输入特征图,经过5×5×3的卷积核卷积得到一个8×8×1的输出特征图。如果此时我们有256个特征图,我们将会得到一个8×8×256的输出特征图。
- 深度卷积:
与标准卷积网络不一样的是,我们将卷积核拆分成为但单通道形式,在不改变输入特征图像的深度的情况下,对每一通道进行卷积操作,这样就得到了和输入特征图通道数一致的输出特征图。如上图:输入12×12×3的特征图,经过5×5×1×3的深度卷积之后,得到了8×8×3的输出特征图。输入个输出的维度是不变的3。这样就会有一个问题,通道数太少,特征图的维度太少,能获取到足够的有效信息吗?
- 逐点卷积:逐点卷积就是1×1卷积。主要作用就是对特征图进行升维和降维,如下图:
在深度卷积的过程中,我们得到了8×8×3的输出特征图,我们用256个1×1×3的卷积核对输入特征图进行卷积操作,输出的特征图和标准的卷积操作一样都是8×8×256了。
- 标准卷积与深度可分离卷积的过程对比:
- 参数量和计算量:.
7.1.2 MobileNet v1卷积层
- 上图左边是标准卷积层,右边是V1的卷积层,虚线处是不相同点。V1的卷积层,首先使用3×3的深度卷积提取特征,接着是一个BN层,随后是一个ReLU层,在之后就会逐点卷积,最后就是BN和ReLU了。这也很符合深度可分离卷积,将左边的标准卷积拆分成右边的一个深度卷积和一个逐点卷积。
- 左边是普通的ReLU,对于大于0的值不进行处理,右边是ReLU6,当输入的值大于6的时候,返回6,relu6“具有一个边界”。作者认为ReLU6作为非线性激活函数,在低精度计算下具有更强的鲁棒性。(这里所说的“低精度”,我看到有人说不是指的float16,而是指的定点运算(fixed-point arithmetic))
7.1.3 V1 网络结构
MobileNet的网络结构如上图所示。首先是一个3x3的标准卷积,s2进行下采样。然后就是堆积深度可分离卷积,并且其中的部分深度卷积会利用s2进行下采样。然后采用平均池化层将feature变成1x1,根据预测类别大小加上全连接层,最后是一个softmax层。整个网络有28层,其中深度卷积层有13层。
7.1.4 缺点
有人在实际使用的时候, 发现深度卷积部分的卷积核比较容易训废掉:训完之后发现深度卷积训出来的卷积核有不少是空的:
7.2 MobileNet V2(2018)
解决V1的遗留问题,ReLU
7.2.1 ReLU做了些啥
这是将低维流形的ReLU变换embedded到高维空间中的的例子,就是对一个n维空间中的一个“东西”做ReLU运算,然后(利用T的逆矩阵T-1恢复)对比ReLU之后的结果与Input的结果相差有多大。
当n = 2,3时,与Input相比有很大一部分的信息已经丢失了。而当n = 15到30,还是有相当多的地方被保留了下来。
也就是说,对低维度做ReLU运算,很容易造成信息的丢失。而在高维度进行ReLU运算的话,信息的丢失则会很少。
这就解释了为什么深度卷积的卷积核有不少是空。发现了问题,我们就能更好地解决问题。针对这个问题,可以这样解决:既然是ReLU导致的信息损耗,将ReLU替换成线性激活函数。
7.2.2 Linear bottleneck
我们当然不能把所有的激活层都换成线性的啊,所以我们就把最后的那个ReLU6换成Linear。
7.2.3 Expansion layer
现在还有个问题是,深度卷积本身没有改变通道的能力,来的是多少通道输出就是多少通道。如果来的通道很少的话,DW深度卷积只能在低维度上工作,这样效果并不会很好,所以我们要“扩张”通道。既然我们已经知道PW逐点卷积也就是1×1卷积可以用来升维和降维,那就可以在DW深度卷积之前使用PW卷积进行升维(升维倍数为t,t=6),再在一个更高维的空间中进行卷积操作来提取特征:
也就是说,不管输入通道数是多少,经过第一个PW逐点卷积升维之后,深度卷积都是在相对的更高6倍维度上进行工作。
7.2.4 Inverted residuals
- 回顾V1的网络结构,我们发现V1很像是一个直筒型的VGG网络。我们想像Resnet一样复用我们的特征,所以我们引入了shortcut结构,这样V2的block就是如下图形式:
- ResNet和V2:可以发现,都采用了 1×1 -> 3 ×3 -> 1 × 1 的模式,以及都使用Shortcut结构。但是不同点呢?ResNet 先降维 (0.25倍)、卷积、再升维。MobileNetV2 则是 先升维 (6倍)、卷积、再降维。
7.2.5 V2的block
- V1 vs V2
左边是v1的block,没有Shortcut并且带最后的ReLU6。
右边是v2的加入了1×1升维,引入Shortcut并且去掉了最后的ReLU,改为Linear。步长为1时,先进行1×1卷积升维,再进行深度卷积提取特征,再通过Linear的逐点卷积降维。将input与output相加,形成残差结构。步长为2时,因为input与output的尺寸不符,因此不添加shortcut结构,其余均一致。
- 然V2的层数比V1的要多很多,但是FLOPs,参数以及CPU耗时都是比V1要好的。
7.2.6 V2网络结构
7.3 MobileNet V3(2019)
MobileNetV3,是谷歌在2019年3月21日提出的网络架构。首先,引入眼帘的是这篇文章的标题,“searching”一词就把V3的论文的核心观点展示了出来——用神经结构搜索(NAS)来完成V3。
7.3.1 MobileNetV3的相关技术
1.网络的架构基于NAS实现的MnasNet(效果比MobileNetV2好)
1.引入MobileNetV1的深度可分离卷积
2.引入MobileNetV2的具有线性瓶颈的倒残差结构
3.引入基于squeeze and excitation结构的轻量级注意力模型(SE)
4.使用了一种新的激活函数h-swish(x)
5.网络结构搜索中,结合两种技术:资源受限的NAS(platform-aware NAS)与NetAdapt
6.修改了MobileNetV2网络端部最后阶段
7.3.2 激活函数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的不同实现而带来的潜在的数值精度损失。
我们可以简单的认为,hard形式是soft形式的低精度化。作者认为swish的表现和其他非线性相比,能够将过滤器的数量减少到16个的同时保持与使用ReLU或swish的32个过滤器相同的精度,这节省了3毫秒的时间和1000万MAdds的计算量。
并且同时,作者认为随着网络的深入,应用非线性激活函数的成本会降低,能够更好的减少参数量。作者发现swish的大多数好处都是通过在更深的层中使用它们实现的。因此,在V3的架构中,只在模型的后半部分使用h-swish(HS)。
7.3.3 网络结构搜索NAS
主要结合两种技术:资源受限的NAS(platform-aware NAS)与NetAdapt。
资源受限的NAS,用于在计算和参数量受限的前提下搜索网络来优化各个块(block),所以称之为模块级搜索(Block-wise Search) 。
NetAdapt,用于对各个模块确定之后网络层的微调每一层的卷积核数量,所以称之为层级搜索(Layer-wise Search)。
一旦通过体系结构搜索找到模型,我们就会发现最后一些层以及一些早期层计算代价比较高昂。于是作者决定对这些架构进行一些修改,以减少这些慢层(slow layers)的延迟,同时保持准确性。这些修改显然超出了当前搜索的范围。
7.3.4 对V2最后阶段的修改
作者认为,当前模型是基于V2模型中的倒残差结构和相应的变体(如下图)。使用1×1卷积来构建最后层,这样可以便于拓展到更高维的特征空间。这样做的好处是,在预测时,有更多更丰富的特征来满足预测,但是同时也引入了额外的计算成本与延时。
所以,需要改进的地方就是要保留高维特征的前提下减小延时。首先,还是将1×1层放在到最终平均池之后。这样的话最后一组特征现在不是7x7(下图V2结构红框),而是以1x1计算(下图V3结构黄框)。
这样的好处是,在计算和延迟方面,特征的计算几乎是免费的。最终,重新设计完的结构如下:
7.3.5 V3的block
与V2的block相比较:
7.3.6 MobileNetV3的网络结构
MobileNetV3定义了两个模型: MobileNetV3-Large和MobileNetV3-Small。V3-Large是针对高资源情况下的使用,相应的,V3-small就是针对低资源情况下的使用。两者都是基于之前的简单讨论的NAS
- MobileNetV3-Large.
- MobileNetV3-Small.
就像之前所说的:只有在更深层次使用h-swish才能得到比较大的好处。所以在上面的网络模型中,不论大小,作者只在模型的后半部分使用h-swish。
7.4 为什么MobileNet会这么快?
- 从结构方面进行了讨论
- 用时多少的角度去讨论:
不管是在GPU还是在CPU运行,最重要的“耗时杀手”就是conv,卷积层。也就是说,想要提高网络的运行速度,就得到提高卷积层的计算效率。
7.4.1 MobileNet资源分布
MobileNet的95%的计算都花费在了1×1的卷积上
在计算机操作时,需要将其存入内存当中再操作(按照“行先序”):
这样一来,特征图y11,y12,y21,y22的计算如下所示:
按照卷积计算,实线标注出卷积计算中的访存过程(对应数据相乘),我们可以看到这一过程是非常散乱和混乱的。直接用卷积的计算方式是比较愚蠢的。
这时候就要用到im2col操作。
7.4.2 imcol
一句话来介绍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就失去了意义而且反而增加了开销。
回到之前的MobileNet的资源分布,95%的1×1卷积和优化的网络结构就是MobileNet能如此快的原因了。
8. ShffuleNet(2017)
目前移动端CNN模型主要设计思路主要是两个方面:模型结构设计和模型压缩。ShuffleNet和MobileNet一样属于前者,都是通过设计更高效的网络结构来实现模型变小和变快,而不是对一个训练好的大模型做压缩或者迁移。
8.1 ShuffleNet V1
8.1.1 概论
-
问题: 为算力有限的嵌入式场景下专门设计一个高效的神经网络架构。
-
解决方法:
2.1 使用了两个新的操作:pointwise group convolution(组卷积)和channel shuffle。
2.2 据这两个操作构建了ShuffleUnit,整个ShuffleNet都是由ShuffleUnit组成。
-
效果:
3.1 在ImageNet分类和MS COCO目标检测任务上取得了比其他轻量化模型更高的准确率,如MobileNet v1。
3.2 在ARM设备上,ShuffleNet的速度比AlexNet快了13倍。
-
存在问题:
4.1 超参数如组卷积的组数以及通道压缩比率等需要根据实际情况决定,不同任务下需要自行调整。
4.2 网络实时性并不能单纯以浮点计算量来衡量,还存在memory access cost(MAC)等因素的干扰,并不能仅仅根据计算量就认为ShuffleNet是最快的。
8.1.2 Group convolution 和 Channel Shuffle
-
在小型网络中,逐点卷积(pointwise convolution)不仅会占用较多计算资源并且还会让通道之间具有过多复杂的约束,这会显著地降低网络性能。在较大的模型中使用pointwise convolution也许相对好一些,然而小模型并不需要过多复杂的约束,否则容易导致模型难以收敛,并且容易陷入过拟合。
-
使用group convolution的网络有很多,如Xception,MobileNet,ResNeXt等。其中Xception和MobileNet采用了depthwise convolution,这是一种比较特殊的group convolution,此时分组数恰好等于通道数,意味着每个组只有一个特征图。是这些网络存在一个很大的弊端是采用了密集的1x1 pointwise convolution
-
这个问题可以解决:对1x1卷积采用channel sparse connection 即分组操作,那样计算量就可以降下来了,但这就涉及到另外一个问题,即不同组之间缺乏信息交流,降低网络的特征提取能力,因此提出Channel Shuffle的方法解决。
-
为达到特征通信目的,我们不采用dense pointwise convolution,考虑其他的思路:channel shuffle。如图b,其含义就是对group convolution之后的特征图进行“重组”,这样可以保证接下了采用的group convolution其输入来自不同的组,因此信息可以在不同组之间流转。图c进一步的展示了这一过程并随机,其实是“均匀地打乱”。
左图是普通的group卷积,卷积核只有相应的输入通道进行作用,不同通道之间信息没有交流。如果组数等于通道数,就可以理解成mobilenet中的depthwise convolution。(b)图是将通道进行重新打乱排列,使得不同通道信息之间能相互交流。©图是(b)图的等价,使用了channle shuffle进行通道重新排列。如果group卷积能够获得不同group中的输入数据,输入特征和输出特征就能很好的关联起来。通过channle shuffle操作,能构建更加强有力的网络结构。
5.通道洗牌具体操作:假设分组特征图的尺寸大小为 h × w × c 1 , ( c 1 = g × n ) h\times w\times c_1,(c_1=g\times n) h×w×c1,(c1=g×n):
- 将特征图展开成 g × n × w × h g\times n\times w\times h g×n×w×h的四维矩阵(为了简单理解,我们把 w × h w\times h w×h降到一维,表示为 s s s)
- 沿着尺寸为 g × n × s g\times n\times s g×n×s的矩阵的 g g g轴和 n n n轴进行转置
- 将 g g g轴和 n n n轴进行平铺后得到洗牌之后的特征图
- 进行组内 1 × 1 1\times1 1×1卷积
8.1.3 ShuffleNet Unit
先看一下其基本单元ShuffleNet Unit。如图所示,(a)图是ResNeXT的残差模块,经过 1 × 1 1 \times1 1×1的卷积来降低通道数,然后使用 3 × 3 3\times3 3×3的group卷积,最后使用 1 × 1 1\times1 1×1的卷积将通道数提升回原来。(b)图是作者提出的ShuffleNet Unit,与残差模块类似,将残差模块中的 1 × 1 1 \times1 1×1卷积换成 1 × 1 1 \times1 1×1的group卷积,并加入了channel shuffle操作。值得注意的是, 3 × 3 3\times3 3×3的group卷积后,没有接激活函数。©图是步长为2的情况,基本类似,但最后是concat操作,而不是add,这样做的目的是在很小的计算成本下,更容易扩大通道数。
接下来分析FLOPs的变化:假设输入特征图大小为 c × h × w c\times h\times w c×h×w,bottlenet的通道数为 m m m, g g g是分组数
- ResNet的FLOPs为 h w c m + 9 h w m 2 + h w m c = 9 h w m 2 + 2 h w m c hwcm +9hwm^2+hwmc=9hwm^2+2hwmc hwcm+9hwm2+hwmc=9hwm2+2hwmc
- ResNeX的FLOPs为 h w c m + 9 h w ( m / g ) 2 g + h w c m = 9 h w m 2 / g + 2 h w c m hwcm +9hw(m/g)^2g+hwcm=9hwm^2/g+2hwcm hwcm+9hw(m/g)2g+hwcm=9hwm2/g+2hwcm
- ShuffleNet的FLOPs为 h w ( c / g ) ( m / g ) g + 9 h w m + h w ( c / g ) ( m / g ) g = 9 h w m + 2 h w m c / g hw(c/g)(m/g)g+9hwm+hw(c/g)(m/g)g=9hwm+2hwmc/g hw(c/g)(m/g)g+9hwm+hw(c/g)(m/g)g=9hwm+2hwmc/g
可以看出,ShuffleNet相对的FLOPs较小。换而言之,在相同的计算资源限制下,ShuffleNet能使用更宽的特征图。这个对轻量化网络来说,是非常重要的。因为轻量化网络通常由于特征图宽度不足而无法更好处理信息。
8.1.4 网路结构
为了评估pointwise group convolution的重要性,作者在上面的网络中使用了不同的g值(通道数会变化的情况),结果如Table.1所示。利用看出,当g>1时,性能会比g=1的情况好(g=1的网络类似于Xception)。所以,小网络会因为分组而得到准确率上的提升。作者认为这是因为更大的特征图宽度对特征的编码起到更多作用。但也值得注意的是,g值越大并不一定越好,网络可能会饱和或者准确率出现恶化。
最后作者在ARM平台上测试了ShuffleNet的真实速度,发现,尽管g=4或者g=8有更高的准确率,但效率却不是最高的。最终采用g=3来折中准确率和最终运行速度。作者还尝试了加入SE模块,但速度大大变慢了。
8.2 ShuffleNet V2(2018)
在上面的文章中我们统一使用FLOPs作为评估一个模型的性能指标,但是在ShuffleNet v2的论文中作者指出这个指标是间接的,因为一个模型实际的运行时间除了要把计算操作算进去之外,还有例如内存读写,GPU并行性,文件IO等也应该考虑进去。最直接的方案还应该回归到最原始的策略,即直接在同一个硬件上观察每个模型的运行时间。如图所示,在整个模型的计算周期中,FLOPs耗时仅占50%左右,如果我们能优化另外50%,我们就能够在不损失计算量的前提下进一步提高模型的效率。
在ShuffleNet v2中,作者从内存访问代价(Memory Access Cost,MAC)和GPU并行性的方向分析了网络应该怎么设计才能进一步减少运行时间,直接的提高模型的效率。
8.2 1 高效CNN网络设计的四个准则
- 当输入、输出channels数目相同时,conv计算所需的MAC(memory access cost)最为节省。
- 过多的Group convolution会加大MAC开销。
- 网络结构整体的碎片化会减少其可并行优化的程序。
- Element-wise操作会消耗较多的时间,不可小视。(Element-wise操作是一种典型的memory access密集操作。)
8.2.2 ShuffleNet v1分析
在ShuffleNet v1的操作中充满了对上述章节介绍过的四个设计准则的违反。首先它使用了bottleneck 1x1 group conv与module最后的1x1 group conv pointwise模块,使得input channels数目与output channels数目差别较大,违反了上述规则一与规则二;其次由于它整体网络结构中过多的group conv操作的使用从而违反了上述规则三;最后类似于Residual模块中的大量Element-wise sum的使用则进而违反了上述规则四。
8.2.3 ShuffleNet v2的设计
ShuffleNet v2中弃用了1x1的group convolution操作,而直接使用了input/output channels数目相同的1x1普通conv。它更是提出了一种ChannelSplit新的类型操作,将module的输入channels分为两部分,一部分直接向下传递,另外一部分则进行真正的向后计算。到了module的末尾,直接将两分支上的output channels数目级连起来,从而规避了原来ShuffleNet v1中Element-wise sum的操作。然后我们再对最终输出的output feature maps进行RandomShuffle操作,从而使得各channels之间的信息相互交通。
跟ShuffleNet v1一样,它也提供了一种需要downsampling的模块变形。为了保证在下采样的时候增加整体输出channels数目,它取消了模块最开始时的RandomSplit操作,从而将信处向下分别处理后再拼结,使得最终outptu channels数目实现翻倍。
说了一大通,更是直接看下图吧。下图中的a/b为原ShuffleNet v1中具有的两种模块结构。图c/d则为ShuffleNet v2中的模块设计。
下表为ShuffleNet v2的整体网络结构。它亦具有MobileNet系列模型中所使用过的缩减系数来控制accuracy与efficiency之间的平衡。
参考链接
https://zhuanlan.zhihu.com/p/76275427
https://mp.weixin.qq.com/s/ooK2aAC_TAPFmK9dPLF-Fw
https://zhuanlan.zhihu.com/p/70703846
https://blog.csdn.net/hongbin_xu/article/details/84304135
https://www.jianshu.com/p/29f4ec483b96
https://www.jianshu.com/p/71e32918ea0a
https://www.bbsmax.com/A/gVdngMGNzW/
https://www.cnblogs.com/dengshunge/p/11407104.html
https://senliuy.gitbooks.io/advanced-deep-learning/content/di-yi-zhang-ff1a-jing-dian-wang-luo/shuffnet-v1-and-shufflenet-v2.html