目录
SqueezeNet (AlexNet-level accuracy with 50x fewer parameters and < 0.5MB model size)
摘要
在最近阅读的一些论文中常常出现MobileNet,Xception等模块,下面将对几种轻量化卷积神经网络进行介绍,并给出论文连接,有需要的可以精度论文。
网络名称 | 公开日期 | 发布情况 | 作者团队 | 链接 |
SqueezeNet | 2016.02 | ICLR-2017 | UC Berkeley & Stanford University | https://arxiv.org/pdf/1602.07360.pdf |
MobileNet | 2016.04 | CVPR-2017 | https://arxiv.org/pdf/1704.04861.pdf | |
ShuffleNet | 2016.06 | CVPR-2017 | Face++ | https://arxiv.org/pdf/1707.01083.pdf |
Xception | 2016.10 | N/A |
|
https://arxiv.org/pdf/1610.02357.pdf |
随着网络性能的不断提高,尤其随着深度卷积网络的不断发展,使得网络效率问题成为另外一种考量标准。效率问题主要是在模型的存储问题和模型预测的速度问题。
模型压缩主要从两个方面:
- 从模型权重数值角度压缩
- 从网络架构角度压缩
对于效率问题,通常的方法是在已经训练好的模型上进行模型压缩,减少参数。轻量化的模型是在不影响模型效率的设计更加高效的网络模型。
- 已训练好的模型上做裁剪 (剪枝、权值共享、量化、神经网络二值化)
新的卷积计算方法(SqueezeNet MobileNet ShuffleNet Xception)
SqueezeNet
使用以下三个策略来减少SqueezeNet设计参数
1.将3x3卷积核替换为1x1卷积核
2.减小输入到3x3卷积核的输入通道数
3.尽可能将下采样放在网络后面的层中 (分辨率越大的特征图(延迟降采样)可以带来更高的分类精度,而这一观点从直觉上也可以很好理解,因为分辨率越大的输入能够提供的信息就越多.)
以上,前两个策略都是针对如何降低参数数量而设计的,最后一个旨在最大化网络精度。
网络提出fire module,由Squeeze层(只包含1x1卷积核)和一个expand卷积层(包含1x1和3x3卷积核)。结构如下所示:
squeeze层借鉴了inception的思想,利用1x1卷积核来降低输入到expand层中3x3卷积核的输入通道数。
SqueezeNet网络结构
SqueezeNet以卷积层(conv1)开始,接着使用8个Fire modules (fire2-9),最后以卷积层(conv10)结束。每个fire module中的filter数量逐渐增加,并且在conv1, fire4, fire8, 和 conv10这几层之后使用步长为2的max-pooling,即将池化层放在相对靠后的位置,这使用了以上的策略(3)
如上图,左边为原始的SqueezeNet,中间为包含simple bypass的改进版本,最右侧为使用complex bypass的改进版本。在下表中给出了更多的细节。
以下是网络设计中的一些要点:
(1)为了使 1∗1和 3∗3 filter输出的结果又相同的尺寸,在expand modules中,给3∗3 filter的原始输入添加一个像素的边界(zero-padding)。
(2)squeeze 和 expand layers中都是用ReLU作为**函数
(3)在fire9 module之后,使用Dropout,比例取50%
(4)注意到SqueezeNet中没有全连接层,这借鉴了Network in network的思想
(5)训练过程中,初始学习率设置为0.04,,在训练过程中线性降低学习率。更多的细节参见本项目在github中的配置文件。
(6)由于Caffee中不支持使用两个不同尺寸的filter,在expand layer中实际上是使用了两个单独的卷积层(1∗11∗1 filter 和 3∗33∗3 filter),最后将这两层的输出连接在一起,这在数值上等价于使用单层但是包含两个不同尺寸的filter。
在github上还有SqueezeNet在其他框架下的实现:MXNet、Chainer、Keras、Torch。
MobileNet
近期的一些论文中常常使用的结构,主要是使用深度可分离卷积来构建轻量化深度神经网络。
论文介绍了两个简单的全局超参数,可有效的在延迟和准确率之间做折中。这些超参数允许我们依据约束条件选择合适大小的模型MobileNet是基于深度可分离卷积的。通俗的来说,深度可分离卷积干的活是:把标准卷积分解成深度卷积(depthwise convolution)和逐点卷积(pointwise convolution)。这么做的好处是可以大幅度降低参数量和计算量。分解过程示意图如下:
论文中的一些细节可以参考轻量级网络--MobileNet论文解读
MobileNet中最为重要的就是标准卷积与深度可分卷积之间的差异,其中MobileNet的深度卷积与逐点卷积是整个模型最为重要的。对于深度可分卷积与标准卷积的一些说明如下:
标准卷积:是将输入的第m个通道对应的第n个卷积核的m通道,将各通道计算结果相加,得到输出结果的第n个通道。对于RGB的三通道图,我们将卷积核在三个通道上进行卷积,最后得到一个feature map。
深度可分卷积:输入中第m个通道,作用于第m个深度卷积核,产生输出特征内的第m个通道。对于RGB的三通道图,我们将卷积核分别在三个通道上进行卷积,最后得到三个feature map。
ShuffleNet
shuffle 具体来说是 channel shuffle,是将各部分的 feature map 的 channel 进行有序的打乱,构成新的 feature map,以解决 group convolution 带来的「信息流通不畅」问题。(MobileNet 是用 point-wise convolution 解决的这个问题)
新的架构利用两个操作:逐点群卷积(pointwise group convolution)和通道混洗(channel shuffle),
在小型网络中,昂贵的逐点卷积造成有限的通道之间充满约束,这会显著的损失精度。为了解决这个问题,一个直接的方法是应用通道稀疏连接,例如组卷积(group convolutions)。通过确保每个卷积操作仅在对应的输入通道组上,组卷积可以显著的降低计算损失。然而,如果多个组卷积堆叠在一起,会有一个副作用: 某个通道输出仅从一小部分输入通道中导出,如下图(a)所示,这样的属性降低了通道组之间的信息流通,降低了信息表示能力。
如果我们允许组卷积能够得到不同组的输入数据,即上图(b)所示效果,那么输入和输出通道会是全关联的。具体来说,对于上一层输出的通道,我们可做一个混洗(Shuffle)操作,如上图C所示,再分成几个组,feed到下一层。
对于这个混洗操作,有一个有效高雅(efficiently and elegantly)的实现:
对于一个卷积层分为g 组,
1.有g×n 个输出通道
2.reshape为(g,n)
3.再转置为(n,g)
4.平坦化,再分回g 组作为下一层的输入
混洗单元
图(a)是一个残差模块。对于主分支部分,我们可将其中标准卷积3×3 拆分成深度分离卷积(可参考我的MobileNet笔记)。我们将第一个1×1 卷积替换为逐点组卷积,再作通道混洗(即(b));
图(b)即ShuffleNet unit,主分支最后的1×1Conv 改为1×1GConv ,并在第一个 1*1 Gconv 之后增加一个 channel shuffle 操作。为了适配和恒等映射做通道融合。配合BN层和ReLU**函数构成基本单元;
图C在旁路增加了 AVG pool,目的是为了减小 feature map 的分辨率;因为分辨率小了,于是乎最后不采用 Add,而是 concat,从而「弥补」了分辨率减小而带来的信息损失。即是做降采样的ShuffleNet unit,这主要做了两点修改:
- 在辅分支加入步长为2的3×3平均池化
- 原本做元素相加的操作转为了通道级联,这扩大了通道维度,增加的计算成本却很少
归功于逐点群卷积和通道混洗,ShuffleNet unit可以高效的计算。相比于其他先进的单元,在相同设置下复杂度较低。
文中提到两次,对于小型网络,多多使用通道,会比较好。所以,以后若涉及小型网络,可考虑如何提升通道使用效率
ShuffleNet的整体架构:
Xception
下图 1 是 Inception module,图 2 是作者简化了的 inception module(就是只保留 1*1 的那条路)
假设出一个简化版 inception module 之后,再进一步假设,把第一部分的 3 个 1*1 卷积核统一起来,变成一个 1*1 的,后面的 3 个 3*3 的分别「负责」一部分通道,如图 3 所示; 最后提出「extreme」version of an Inception,module Xception ,先用 1*1 卷积核对各通道之间(cross-channel)进行卷积,如图 4 所示:
Xception 是借鉴 Rigid-Motion Scatteringfor Image Classification 的 Depth-wise convolution,是因为 Xception 与原版的 Depth-wise convolution 有两个不同之处
- 第一个:原版 Depth-wise convolution,先逐通道卷积,再 1*1 卷积; 而 Xception 是反过来,先 1*1 卷积,再逐通道卷积;
- 第二个:原版 Depth-wise convolution 的两个卷积之间是不带**函数的,而 Xception 在经过 1*1 卷积之后会带上一个 Relu 的非线性**函数;
Xception 结构如上图所示,共计 36 层分为 Entry flow;Middle flow;Exit flow。
Entry flow 包含 8 个 conv;Middle flow 包含 3*8 =24 个 conv;Exit flow 包含 4 个 conv,所以 Xception 共计 36 层。
Xception 是基于 Inception-V3,并结合了 depth-wise convolution,这样做的好处是提高网络效率,以及在同等参数量的情况下,在大规模数据集上,效果要优于 Inception-V3。这也提供了另外一种「轻量化」的思路:在硬件资源给定的情况下,尽可能的增加网络效率和性能,也可以理解为充分利用硬件资源。
总结
轻量化主要得益于 depth-wise convolution,因此大家可以考虑采用 depth-wise convolution 来设计自己的轻量化网络,但是要注意「信息流通不畅问题」。
解决「信息流通不畅」的问题,MobileNet 采用了 point-wise convolution,ShuffleNet 采用的是 channel shuffle。MobileNet 相较于 ShuffleNet 使用了更多的卷积,计算量和参数量上是劣势,但是增加了非线性层数,理论上特征更抽象,更高级了;ShuffleNet 则省去 point-wise convolution,采用 channel shuffle,简单明了,省去卷积步骤,减少了参数量。
网络名称 | 特点 |
SqueezeNet | 1*1卷积压缩feature map数量 |
MobileNet | 深度可分卷积 |
ShuffleNet | 深度可分卷积 |
Xception | 基于Inception-V3结合深度可分卷积 |