紧凑网络结构设计:把卷积拆开

经典网络(AlexNet、VGG、Inception、ResNet、SENet 等)大多是为”刷精度”而生。但要真正落地——更小的运行内存、更低的时延、更大的吞吐——就需要专门设计的紧凑网络结构。这篇梳理几条主线的设计思路。

MobileNet:深度可分离卷积

MobileNet 几乎是紧凑网络设计的起点。顾名思义,它面向移动端部署,最大的贡献是把传统卷积拆成两步:深度可分离卷积(depthwise convolution)1×11\times1 卷积(pointwise convolution)

标准卷积、深度可分离卷积、1×1 卷积的滤波器
标准卷积 vs 深度可分离卷积 vs 1×1 卷积的滤波器。
MobileNet 的网络结构
MobileNet 的整体结构。

可以定量分析一下。设把 DF×DF×MD_F\times D_F\times M 的张量经卷积变成 DF×DF×ND_F\times D_F\times N,卷积核大小 DKD_K。标准卷积的 FLOPs 为:

FLOPsstd=DK×DK×M×N×DF×DF\text{FLOPs}_{\text{std}}=D_K \times D_K \times M \times N \times D_F \times D_F

拆成深度可分离 + 1×11\times1 之后:

FLOPsdw+pw=DK×DK×M×DF×DF+M×N×DF×DF\text{FLOPs}_{\text{dw+pw}}=D_K \times D_K \times M \times D_F \times D_F + M \times N \times D_F \times D_F

两者之比为:

FLOPsdw+pwFLOPsstd=1N+1DK×DK\frac{\text{FLOPs}_{\text{dw+pw}}}{\text{FLOPs}_{\text{std}}}=\frac{1}{N}+\frac{1}{D_K\times D_K}

最常用的是 3×33\times3 卷积(DK=3D_K=3),当输出通道 NN 较大时,这种拆分相比标准卷积最多能把 FLOPs 降到 19\tfrac{1}{9}。但要注意:FLOPs 降 9 倍不等于实测快 9 倍——推理框架对卷积通常用 im2col+GEMM 或 Winograd 实现,而深度可分离卷积并不能有效降低访存开销,所以实测提速其实很有限。参数量的分析同理,比值也是 1N+1DK2\tfrac{1}{N}+\tfrac{1}{D_K^2};参数量的减小比 FLOPs 更”实在”,因为存到磁盘时确实省空间,不像 FLOPs 受制于软件实现而难有实质加速。

ShuffleNet:分组 1×1 卷积 + channel shuffle

ShuffleNet 比 MobileNet 晚几个月,它进一步对 1×11\times1 卷积下手:除了沿用深度可分离的 3×33\times3 卷积,还把标准的 1×11\times1 卷积也分组,并在分组之后引入 channel shuffle,让各组通道的信息能在下一层融合。注意 channel shuffle 并不是真随机打乱——以 PyTorch 为例,它是用 reshape + permute 实现的。

ShuffleNet 中的 channel shuffle
channel shuffle:仅分组卷积时各组互不通信(a),shuffle 后通道信息得以跨组融合(c)。

整个 ShuffleNet 由多个 block 堆叠而成:

ShuffleNet 的 block
ShuffleNet 的 block:把 1×1 卷积换成分组卷积,并加上 channel shuffle。
ShuffleNet 的结构
ShuffleNet 的整体结构。

定量看:channel shuffle 本身不增减 FLOPs/参数量,但会改变特征图在内存中的布局,给下一层带来带 stride 的访存开销。而分组数为 GG1×11\times1 卷积,其 FLOPs 为 M×N×DF×DFG\tfrac{M\times N\times D_F\times D_F}{G}——相比标准 1×11\times1 卷积,FLOPs 和参数量都降为 1G\tfrac{1}{G}。固定网络总 FLOPs 时,分组越多就能用更多滤波器,要取得最高精度需要在二者间仔细权衡。

MobileNetV2:Inverted Residual

MobileNetV2 把 ResNet 的残差连接和 bottleneck 融进了 MobileNet,但用的是相反的 inverted bottleneck:先用 1×11\times1 卷积把通道数升上去,再做深度可分离卷积,最后用第二个 1×11\times1 卷积把通道降回输入的大小。

MobileNetV2 的 inverted residual block
ResNet 的 bottleneck(a)vs MobileNetV2 的 inverted bottleneck(b)。
MobileNetV2 的结构
MobileNetV2:t 为扩张率,c 为输出通道,n 为重复次数,s 为步长。

它没有再发明新的紧凑操作,而是把残差连接、bottleneck 这些提升拟合能力的手段融进紧凑网络,进一步提了精度。值得一提的是,MobileNetV2 后来成了很多结构搜索方法的 backbone(下面的 MobileNetV3、EfficientNet 都基于它)。

ShuffleNetV2:从访存开销出发的四条准则

ShuffleNetV2 在论文里重点讨论了一个常被忽略的指标——访存开销(MAC, Memory Access Cost),并据此提出四条紧凑网络设计准则。

准则一:尽量让卷积的输入输出通道数相同。1×11\times1 卷积为例,输入输出通道 c1,c2c_1,c_2、特征图 h×wh\times w,则 FLOPs=hwc1c2\text{FLOPs}=h\,w\,c_1\,c_2。固定 FLOPs 时,访存开销

MAC=hw(c1+c2)+c1c2  2hwFLOPs+FLOPshw\text{MAC}=h\,w\,(c_1+c_2)+c_1 c_2 \ \ge\ 2\sqrt{h\,w\cdot\text{FLOPs}}+\frac{\text{FLOPs}}{h\,w}

由均值不等式,MAC 有下限,且在 c1=c2c_1=c_2 时取到。实验也证实:同样 FLOPs 下,输入/输出通道比为 1:11:1 时实测最快(GPU 和 ARM 上结论一致)。

不同输入输出通道比的实际速度
准则一:同 FLOPs 下,输入/输出通道比 1:1 时最快。

准则二:分组数过多会增大 MAC。 分组数为 gg1×11\times1 卷积:

MAC=hw(c1+c2)+c1c2g=hwc1+FLOPsgc1+FLOPshw\text{MAC}=h\,w\,(c_1+c_2)+\frac{c_1 c_2}{g}=h\,w\,c_1+\frac{\text{FLOPs}\cdot g}{c_1}+\frac{\text{FLOPs}}{h\,w}

固定 FLOPs 时,MAC 随 gg 增大而增大。

不同分组数的实际速度
准则二:同 FLOPs 下,分组数越多越慢。

准则三:碎片(fragment)过多会降低并行度。 网络里串行/并行的小分支太多,会削弱并行计算的程度。但深层结构往往精度更高,所以要在精度和并行提速之间权衡。

串行与并行的结构
不同数量、串行/并行的碎片结构。
不同碎片数与连接方式的实际速度
准则三:同 FLOPs 下,碎片越少越快;同样碎片数,串行比并行快。

准则四:别忽略 element-wise 操作的开销。 一个操作的时间由 MAC 和 FLOPs 两部分组成。卷积的 FLOPs 远大于 MAC,但点加(element-wise add)、ReLU 这类 FLOPs 很小的操作里,MAC 才是主要开销,不能忽略。

去掉 ReLU 或残差连接的速度对比
准则四:ReLU 和残差连接这类 element-wise 操作也有可观开销。

据此,ShuffleNetV2 的 block 与 V1 几乎完全不同:不再用分组 1×11\times1 卷积,改用 channel split(既保残差连接,又不因分组卷积增 MAC,准则二);block 里的 Channel SplitConcatChannel Shuffle 还能融合成一个操作以减小 MAC(准则四)。

ShuffleNetV2 的 block
ShuffleNetV1(a、b)与 ShuffleNetV2(c、d)的 block 对比。
ShuffleNetV2 的整体结构
ShuffleNetV2 的整体结构。

MobileNetV3:h-swish

MobileNetV3 是在 MobileNetV2 基础上用自动化搜索(MnasNet + NetAdapt 压缩)得到的,主要改了卷积层数、卷积核大小、通道数,并在部分层用了 SE 模块。此外它把深层的激活函数从 ReLU 换成 hard-swish:

h-swish(x)=xReLU6(x+3)6\text{h-swish}(x)=x\,\frac{\text{ReLU6}(x+3)}{6}

原始的 swish 是 swish(x)=xσ(x)\text{swish}(x)=x\cdot\sigma(x),但 sigmoid 计算量大;hard-swish 用近似换来了几乎一样的效果、却便宜得多。

hard-swish 激活函数
hard-swish:用 ReLU6 近似 swish,避开 sigmoid 的大计算量。
MobileNetV3-small
MobileNetV3-small 的结构(另有 large 版本)。

EfficientNet:复合缩放

EfficientNet 与 MobileNetV3 几乎同时诞生,也基于 MnasNet 搜索而来,但搜索只用了简单的网格搜索。它的核心是一套网络缩放方法:既然一个紧凑网络能在很小的 FLOPs 下达到不错精度,那要更高精度,直接把它放大就好。缩放分三个维度:宽度、深度、输入分辨率。

神经网络的缩放
宽度 / 深度 / 分辨率三种缩放,以及它们的复合缩放。

每个维度的缩放倍数解耦成一个相对因子和一个整体因子 ϕ\phi:

depth:d=αϕ,width:w=βϕ,resolution:r=γϕ\text{depth}:d=\alpha^{\phi},\quad \text{width}:w=\beta^{\phi},\quad \text{resolution}:r=\gamma^{\phi}
s.t.αβ2γ22,α,β,γ1\text{s.t.}\quad \alpha\cdot\beta^2\cdot\gamma^2\approx2,\quad \alpha,\beta,\gamma\ge1

约束 αβ2γ22\alpha\beta^2\gamma^2\approx2 的原因:FLOPs 随宽度、分辨率以平方增长,随深度线性增长,把 αβ2γ2\alpha\beta^2\gamma^2 约束成常数,就能让任意缩放都把 FLOPs 维持在可控水平。搜索时固定 ϕ=1\phi=1、用网格搜索找最佳 α,β,γ\alpha,\beta,\gamma,之后调 ϕ\phi 就能把网络缩放到任意 FLOPs。

复合缩放对比单维度缩放
复合缩放比只缩放单个维度,在同 FLOPs 下精度更高。
EfficientNet-B0 的网络结构
EfficientNet-B0(缩放的基础网络,由 MnasNet 搜索而来),向上有 B1–B7。

GhostNet:用廉价操作生成”幽灵”特征

GhostNet 同样走分解路线,但出发点很独特:可视化特征图会发现,很多通道的特征图彼此非常相似——那就没必要都用昂贵的标准卷积去算。

标准卷积的特征图之间有很多近似
标准卷积算出的特征图,有不少彼此高度相似。

于是 GhostNet 把标准卷积分两步:先用更少滤波器的标准卷积算出一部分输出,再用廉价操作(如线性变换/深度可分离卷积)在其基础上”生成”另一部分输出,最后 concat 到一起。

标准卷积与 Ghost module 的卷积
标准卷积(a)vs Ghost module(b):少量标准卷积 + 廉价操作生成剩余特征。

定量分析:卷积核 kk、输入通道 cc、输出 n×h×wn\times h\times w,标准卷积 FLOPs 为 nhwck2n\,h\,w\,c\,k^2。Ghost 模块若第一步算 mm 个通道、廉价操作用大小为 dd 的深度可分离卷积、令 s=nms=\tfrac{n}{m},则加速比

RFLOPs=nhwck2mhwck2+(nm)hwd2=ck21sck2+s1sd2sR_{\text{FLOPs}}=\frac{n\,h\,w\,c\,k^2}{m\,h\,w\,c\,k^2+(n-m)\,h\,w\,d^2}=\frac{c\,k^2}{\tfrac{1}{s}c\,k^2+\tfrac{s-1}{s}d^2}\approx s

(近似用到了 dkd\approx kscs\ll c。)参数量的压缩比同样约为 ss

GhostNet 中的 block
GhostNet 的 block:类似 MobileNetV2,中间对特征图先扩张再压缩。
GhostNet 的整体结构
GhostNet 的整体结构。

从 MobileNet 把卷积拆开,到 ShuffleNetV2 盯住访存、再到 GhostNet 复用相似特征——紧凑网络设计的主线,始终是在 FLOPs、访存与精度之间反复权衡。而 MobileNetV3、EfficientNet 已经把”人来设计”换成了”自动搜索”,这正是神经网络结构搜索(NAS)的方向。

参考资料

  • Howard, Andrew G., et al. MobileNets: Efficient Convolutional Neural Networks for Mobile Vision Applications. arXiv:1704.04861, 2017.
  • Zhang, Xiangyu, et al. ShuffleNet: An Extremely Efficient Convolutional Neural Network for Mobile Devices. CVPR, 2018.
  • Ma, Ningning, et al. ShuffleNet V2: Practical Guidelines for Efficient CNN Architecture Design. ECCV, 2018.
  • Sandler, Mark, et al. MobileNetV2: Inverted Residuals and Linear Bottlenecks. CVPR, 2018.
  • Howard, Andrew, et al. Searching for MobileNetV3. arXiv:1905.02244, 2019.
  • Tan, Mingxing, Le, Quoc V. EfficientNet: Rethinking Model Scaling for Convolutional Neural Networks. arXiv:1905.11946, 2019.
  • Han, Kai, et al. GhostNet: More Features from Cheap Operations. CVPR, 2020.
  • Tan, Mingxing, et al. MnasNet: Platform-Aware Neural Architecture Search for Mobile. CVPR, 2019.
  • Jia, Yangqing, et al. Caffe: Convolutional Architecture for Fast Feature Embedding. ACM MM, 2014.
  • Lavin, Andrew, Gray, Scott. Fast Algorithms for Convolutional Neural Networks (Winograd). CVPR, 2016.