Skip to content

轻量化网络设计

yubo105139 edited this page Dec 5, 2024 · 1 revision

[TOC]

轻量化网络设计

将从以下几个方面介绍轻量化网络设计的相关内容:

  • 模型性能分析
  • 人工设计轻量化神经网络模型
  • 网络模型压缩方法
    • 剪枝
    • 量化
    • 低秩分解
    • 权值共享
    • 知识蒸馏
    • 自动机器学习(AutoML)与网络架构搜索(NAS)

模型性能分析指标

​ 实测是最准确的性能评估方式,但是通过理论指标来估计模型能够达到的性能上界能够更好的指导我们对模型的设计.

模型的复杂度

时间复杂度

即模型的运算次数,常用的计算量统计指标是FLOPs,也就是浮点运算次数(FLoating-point OPerations)。

空间复杂度

空间复杂度(访存量),严格来讲包括两部分:总参数量 + 各层输出特征图。

  • 参数量:模型所有带参数的层的权重参数总量
  • 特征图:模型在实时运行过程中每层所计算出的输出特征图大小

## 计算平台的两个指标

在设计轻量化网络时,要考虑计算平台的算力和带宽。

算力:也称为计算平台的性能上限,指的是一个计算平台倾尽全力每秒钟所能完成的浮点运算数。单位是 FLOPS or FLOP/s

带宽 :也即计算平台的带宽上限,指的是一个计算平台倾尽全力每秒所能完成的内存交换量。单位是Byte/s

**计算强度上限:**以上两个指标算力除以带宽即可得到计算平台的计算强度上限。它描述的是在这个计算平台上,单位内存交换最多用来进行多少次计算。单位是FLOPs/Byte

:这里所说的“内存”是广义上的内存。对于CPU计算平台而言指的就是真正的内存;而对于GPU计算平台指的则是显存。

​ 在算力足够的GPU平台上,有的轻量化网络不会带来任何速度上的提升(有时甚至是下降的),然而在计算能力有限的平台上,轻量化网络能让速度提升三倍以上。(算力足够时, 假设模型FLOPs值很大, 其耗时也很小, 即使轻量化设计使FLOPs有一定的下降,对模型的速度影响并不大, 而模型的内存访问等操作的变动还可能使模型速度下降)

模型的参数量计算

​ 参数量是模型中的参数的总和,跟模型在磁盘中所需的空间大小直接相关。对于 CNN 来说参数主要由 Conv/FC 层的 Weight 构成,当然其他的一些算子也有参数,不过一般忽略不计了。

​ 参数量往往是被算作访存量的一部分,因此参数量不直接影响模型推理性能。但是参数量一方面会影响内存占用,另一方面也会影响程序初始化的时间。参数量会直接影响软件包的大小。当软件包大小有限制时, 需要在模型设计时减少参数量, 通过压缩模型的方式降低软件包大小。

卷积的参数量计算

输入尺寸为$hwc_{in}$的特征图,经过尺寸为$k_hk_wc_{in}$的卷积核, 生成尺寸为$H,W,c_{out}$的特征图。

对于该卷积层,其parameter的个数(即W和b的权重个数)为: $$ params = (k_hk_wc_{in})*c_{out}+c_{out} $$

全连接的参数量计算

对于某个全连接层,输入的数据为$N_{in}$个节点, 输出的数据为$N_{out}$个节点。则: $$ params=N_{in}*N_{out}+N_{out} $$

模型计算量的计算

FLOPs(FLoating point OPerations)

计算量:指的是输入单个样本(对于CNN而言就是一张图像),模型进行一次完整的前向传播所发生的浮点运算个数,也即模型的时间复杂度。单位FLOPs

通常论文中使用的单位是GFLOPs,1 GFLOPs = 10^9 FLOPs,即:10亿次浮点运算。

MACC(MADD):multiply-accumulate operations:先乘起来再加起来的运算次数。

Attention:

FLOPs:注意s小写,是floating point operations的缩写(s表复数),意指浮点运算数,理解为计算量。可以用来衡量算法/模型的复杂度。

FLOPS:注意全大写,是floating point operations per second的缩写,意指每秒浮点运算次数,理解为计算速度。是一个衡量硬件性能的指标。

FLOPs的计算

​ 对于一个卷积层,假设卷积核大小为$kk$,$c_{in}$为输入的feature map通道数,$c_{out}$为输出的feature map通道数,输出的feature map尺寸为$HW$ 。卷积层计算为:$w*x+b$

  1. 对于输出 feature map 上的某个unit:进行了$kkc_{in}$次乘法, $kkc_{in}-1$次加法。

  2. 对于通道数为$c_{out}$,尺寸为H×W的feature map,unit的总数为:$HWc_{out}$

  3. 则卷积计算的$w*x$部分,总共包含

    乘法次数:$kkc_{in}(HW*c_{out})$

    加法次数:$(kkc_{in}-1)(HW*c_{out})$

  4. 考虑$w*x+b$的偏置项b, feature map上的每个unit进行了1次偏置加法运算,该卷积层总共包含:

    加法次数:$1*(HWc_{out})$

  5. 将以上计算累加,得到:

    $FLOPs = kkc_{in}HWc_{out}+kkc_{in}HWc_{out}$

计算结果的乘法和加法的运算次数相等,可计作:$kkc_{in}HWc_{out}$次MACC, 或者$2kkc_{in}HW*c_{out}$次FLOPs

FLOPs计算举例

image-20210607151956627

y = w[0]*x[0] + w[1]*x[1] + w[2]*x[2] + ... + w[n8]*x[8]

记w[0]*x[0] +… 为一次乘加,即1MACC。所以对于上式而言共有9次乘加,即9MACCs

该式子执行了9次乘法、9-1次加法,所以其计算量一共是9+(9-1)=17次FLOPs。

总结

参数量: $params=c_{out}(kkc_{in}+1)$ FLOPs: $FLOPs=HWc_{out}(kkc_{in}+1)$

即: $FLOPs=HWparas$

  • 对于某个卷积层,其FLOPs的计算为:该层参数的数目*输出特征图的二维尺寸。

  • 近似来看1MACC ≈ 2FLOPs。

模型的访存量计算

**访存量:**指模型计算时所需访问存储单元的字节大小,反映了模型对存储单元带宽的需求。访存量一般用Bytes(或者 KB/MB/GB)来表示,即模型计算到底需要存/取多少 Bytes 的数据。和计算量一样,模型整体访存量等于模型各个算子的访存量之和。

另一种解释:访存量指的是输入单个样本,模型完成一次前向传播过程中所发生的内存交换总量,也即模型的空间复杂度。在理想情况下(即不考虑片上缓存),模型的访存量就是模型各层权重参数的内存占用(Kernel Mem)与每层所输出的特征图的内存占用(Output Mem)之和。单位是Byte

对于 Eltwise Sum 来讲,两个大小均为 (N, C, H, W) 的 Tensor 相加,访存量是 (2 + 1) x N x C x H x W x sizeof(data_type),其中 2 代表读两个 Tensor,1 代表写一个 Tensor;

而对于一个输入特征图为(N,IC,IH,IW), 输出特征图为(N,OC,OH,OW),卷积核大小为(KH,KW) 卷积操作来说,访存量公式为: $$ MACs_{Conv} = MACs_{Input}+MACs_{Weight}+MACs_{Output} $$

$$ MACs_{Conv} = (N *IC * IH * IW+OC * IC * KH * KW + N * OC * OH * OW) * sizeof(data_type) $$

由于参数数据类型通常为float32 ,因此需要乘以四。

模型的计算强度计算

​ 模型的计算强度也称之为计算密度,由计算量除以访存量就可以得到,它表示此模型在计算过程中,每Byte内存交换到底用于进行多少次浮点运算。或理解为一个程序在单位访存量下所需的计算量。单位是FLOPs/Byte。模计算强度越大,其内存使用效率越高。

计算密集型和访存密集型算子

​ 当模型的计算强度较小时,程序访存多而计算少,性能受内存带宽限制,称为访存密集型程序。反之如果计算密度较大,程序性能受硬件最大计算峰值(即算力)的限制,称为计算密集型程序。

​ 对于访存密集型算子,推理时间跟访存量呈线性关系,而对于计算密集型算子,推理时间跟计算量呈线性关系

​ 网络中的算子可以根据计算密度进行分类。一般来讲,Conv、FC、Deconv 算子属于计算密集型算子;ReLU、EltWise Add、Concat LeakyReLU、ReflectionPad等属于访存密集型算子。

同样的模型在不同平台上性质可能会发生改变,需要具体情况具体分析。不同的硬件平台峰值算力和内存带宽不同,导致同一个模型在平台 1 上可能是计算密集的,在平台 2 上可能就变成了访存密集的。比如Depthwise Conv 在很多设备上都属于访存密集型算子。

算子的计算密度越大,越有可能提升硬件的计算效率,充分发挥硬件性能

关于element-wise逐元素操作?

其不存在数据复用, 因此其属于访存密集型算子。

解释:

与element-wise相对应的,其实是矩阵乘法操作,矩阵乘法操作的特点是“数据复用”。假设一个100*1的矩阵与1*100的矩阵相乘,总共10000次乘法,总共的数据量只有2*100。因为每一个元素都要参与100次乘法,大量的数据存在复用;而换做element-wise操作,10000次乘法就是10000维的向量与另一个10000维的向量进行点乘,10000次乘法互相独立,不存在任何数据复用。

而在网络层面,普通卷积操作都可以看作“矩阵乘法”,存在着数据复用。在上面提到的3x3普通卷积中,一个3*3*100的feature blob会跟所有的卷积核相乘,每一个3*3*100的卷积核又会与所有的feature blob相乘。而ReLU这样的激活函数,ResNet block中的shortcut等等,都是elment-wise操作,逐元素求取sigmoid/逐元素相加。这些过程中每次操作之间是不存在数据复用的。而depthwise卷积也有这样的特点,可以称作“channel-wise”或者说“kernel-wise”。depthwise卷积中每一个channel对应着不同的卷积核和feature blob,每次卷积操作之间不牵涉“数据复用”,因此从这个角度,可以说depthwise卷积某种程度上说也是一种“element-wise”操作。

模型性能分析举例

以 VGG16 为例与mobileNet对比进行分析

  • 第一个Conv的计算:

    KernelMem (卷积核的参数量): 3*3*3*64 = 1728

​ OutputMem(输出特征图的参数量): 224*224*64=3211264

​ FLOPs(浮点运算数): 3*3*3*64*224*224 = 86704128

(表格里将乘加作为一次, 应该计算的是MACC)

  • 最后一行uint数据类型进行存储, 每个参数占4个字节, 所以

    KernelMem_total = 138344128*4 Bytes = 138344128*4 /1024/1024 MB = 527MB

    OutputMen_total =15262696*4Bytes = 15262696*4 /1024/1024 MB = 58MB

    访存量 = 527MB + 58MB= 585MB。

  • 将每一层的FLOPs求和, 得到一次前向传播的计算量为:15 GFLOPs。

  • 计算强度= 计算量/访存量 = (15470264320FLOPS/585MB ) 约25 FLOPs/Byte

preview

相较与VGG16, MobileNet 的计算量只有大约 0.5 GFLOPs(VGG16 则是 15 GFLOPs),其访存量也只有 74 MB(VGG16 则是约 600 MB)。这样看上去确实轻量了很多,虽然计算量和访存量都下降了,但是计算量下降的更厉害,因此 MobileNet 的计算强度只有 7 FLOPs/Byte。

对于1080Ti的计算平台:

  • 1080Ti 的算力 $\pi = 11.3 TFLOP/s$
  • 1080Ti 的带宽 $\beta = 484 GB/s$
  • 因此 1080Ti 计算平台的最大计算强度 $I_{max}\approx24$
  • VGG16 的计算强度 $I_V \approx 25$
  • MobileNet 的计算强度 $I_M \approx 7$

虽然 MobileNet 进行前向传播的计算量只有 VGG的 1/30,但是由于计算平台的带宽限制,它不能像 VGG 那样完全利用 1080Ti 这个计算平台的全部算力,因此它在 1080Ti 上每秒钟可以进行的浮点运算数只能达到 VGG 的 30%,因此理论上的运行速度大约是 VGG 的十倍(实际上会因为各方面其他因素的限制而使得差别更小)。

模型1需要进行 10次浮点计算, 需要10byte的内存交换; 
模型2需要进行 10次浮点计算, 需要1byte的内存交换。
假设平台带宽为 1, 每秒只能交换1 byte。 平台算力为10, 每秒能完成10次浮点运算。 平台计算强度上限为  10 /1 = 10 FLOPs/Byte。

对于模型1,  模型的计算强度为 10/100 = 0.1FLOPs/Byte。 每交换1byte内存,只能完成0.1次浮点运算。
对于模型2,  模型的计算强度为 10/1 = 10FLOPs/Byte。  每交换1byte内存,能完成10次浮点运算。
那么在该平台上 , 模型2 只需要 1秒可以完成所需的10次浮点计算。
而 模型1 受到带宽限制,使得其1秒只能交换1byte 内存, 又受到访存量过大的限制,1byte的交换只完成了0.1次浮点计算, 其共需要 10/0.1 = 100s 来完成 10次浮点计算。

影响模型推理性能的其他因素

硬件限制对性能上界的影响:

硬件会因为种种原因, 导致算力或内存带宽在实际使用时达不到理论峰值。可以对硬件进行micro-benchmark,以获取硬件的真实性能上限。

系统环境对性能的影响:

操作系统在多核间的调度损失、操作系统的内存管理带来的损失、操作系统本身占用的运算资源等等。会对模型性能上界产生一定影响.

必须关注工程测试环境和实际部署系统环境的差异。

软件实现对性能的影响:

对于深度学习模型推理而言,推理框架对模型性能的影响主要体现在:是否充分利用了硬件的流水线资源、是否高效利用了硬件中的缓存、是否采用了时间复杂度更低的算法、是否解决了操作系统带来的性能损失、是否进行了正确高效的图优化等等。

​ 因此,在评估或分析深度学习推理性能时,简单的计算量/访存量指标是完全不够的,只能做个性能上界参考。实际能达到的性能其实还要关注很多很多因素,例如算子的访存模式、数据排布、是否能够进行图融合、是否有精度可接受的低时间复杂度算法、算法并行度是否充足、各种运算的比例等等因素。

面向推理速度的模型设计建议

  • 对于低算力平台(CPU、低端 GPU 等),模型很容易受限于硬件计算能力,因此可以采用计算量低的网络来降低推理时间。

  • 对于高算力平台(GPU、DSP 等),一味降低计算量来降低推理时间就并不可取了,往往更需要关注访存量。单纯降低计算量,很容易导致网络落到硬件的访存密集区,导致推理时间与计算量不成线性关系,反而跟访存量呈强相关(而这类硬件往往内存弱于计算)。相对于低计算密度网络而言,高计算密度网络有可能因为硬件效率更高,耗时不变乃至于更短。

  • 面向推理性能设计网络结构时,尽量采用经典结构,大部分框架会对这类结构进行图优化,能够有效减少计算量与访存量。例如 Conv->BN->ReLU 就会融合成一个算子,但 Conv->ReLU->BN 就无法直接融合 BN 层

  • 算子的参数尽量使用常用配置,如 Conv 尽量使用 3x3_s1/s2、1x1___s1/s2 等,软件会对这些特殊参数做特殊优化。

  • CNN 网络 channel 数尽量选择 4/8/16/32 的幂次,很多框架的很多算子实现在这样的 channel 数下效果更好(具体用多少不同平台不同框架不太一样)。

  • 框架除了计算耗时外,也处理网络拓扑、内存池、线程池等开销,这些开销跟网络层数成正比。因此相比于“大而浅”的网络,“小而深”的网络这部分开销更大。一般情况下这部分开销占比不大。但在网络算子非常碎、层数非常多的时候,这部分开销有可能会影响多线程的扩展性,乃至于成为不可忽视的耗时因素。

ref:

CNN 模型flops和参数量计算

Roofline Model与深度学习模型的性能分析

深度学习模型大小与模型推理速度的探讨

为什么有些模型 FLOPs 很低,推理速度却很慢?

人工设计轻量化神经网络模型

​ 人工设计轻量级神经网络通过合理地减少卷积核的数量,减少目标特征的通道数,结合设计更高效的卷积操作等方式,从而构造更加有效的神经网络结构,可以在保持神经网络性能的前提下,显著地减少网络的参数和计算量,实现在便携式设备上训练和应用深度神经网络.

轻量化网络组件

分组卷积(Grouped Convolution)

将输入特征通道被为G组,对于每个分组的通道独立地执行卷积。

preview

img

​ 分组卷积按照通道数分为g组,每组的特征图尺寸为$HWc_1/g$,对应的卷积核尺寸为$h_1w_1c_1/g$, 对应的输出特征图尺寸为$HWc_2/g$,g组结果拼接得到最终的输出尺寸$HWc_2$。

参数量对比

标准卷积参数量 = $h_1w_1c_1*c_2+c_2$

分组卷积参数量=$(h_1w_1c_1/gc_2/g+c_2/g)g$ = $h_1w_1c_1c_21/g+c_2$

分组卷积的参数量约是标准卷积的1/g。

通道混洗(hannel shuffle)

分组卷积导致模型的信息流限制在各个group内,组与组之间没有信息交换,这会影响模型的表示能力。因此,需要引入group之间信息交换的机制,即Channel Shuffle操作。

Channel shuffle是ShuffleNet提出的,通过张量的reshape 和transpose,实现改变通道之间顺序。

channel shuffle的实现

$c = g*c_g$, 其中c为通道数, g为分组,c_g为分组通道数。

(b,c,h,w) reshape 得到(b,g,c_g,h,w),转置得到(b,c_g,g,h, w) ,再重塑为(b, c, h, w)

import torch

def channel_shuffle(x, groups):
    batchsize, num_channels, height, width = x.data.size()
    channels_per_group = num_channels // groups
    # reshape
    x = x.view(batchsize, groups,
               channels_per_group, height, width)
    # transpose
    x = torch.transpose(x, 1, 2).contiguous()
    # flatten
    x = x.view(batchsize, -1, height, width)
    return x

深度可分离卷积(deepwise convolution)

设计思想

​ 将标准的卷积操作因式分解成一个depthwise convolution和一个1*1的pointwise convolution操作。一个卷积层分成两个卷积层,其中前一个卷积层的每个卷积核都只跟输入的每个channel进行卷积,后一个卷积层则负责整合,即将上一层卷积的结果进行合并。 如下图:

image-20210607180818655

for understand:

image-20210929165009500

image-20210929165059634

假设输入为$D_wD_wM$特征图,需要通过卷积运算得到输出为$D_fD_fN$的特征图。

depthwise convolution:

输入的图片是$D_wD_wM$($D_w$是图片大小,M是输入的通道数), 那么有M个$D_kD_k$的卷积核,分别去跟M个通道进行卷积,输出$DfDf*M$的结果。其中每个通道只被一个卷积核卷积。

​ 该阶段的输出通道数与输入通道数相同。对输入层的每个通道独立进行卷积运算,没有有效的利用不同通道在相同空间位置上的feature信息。

pointwise convolution:

对$DfDfM$进行卷积合并,有$11N$的卷积,进行合并常规的卷积,输出$DfDfN$的结果。

​ 该阶段使用1*1卷积,控制了输出的特征图通道数,并完成了跨通道的信息交互。

参数量对比

标准卷积参数量:

$D_kD_kM*N$

深度可分离卷积参数量(深度卷积参数量+逐点卷积参数量):

$(D_kD_k1)M+(11M)N=D_kD_kM+M*N$

​ 深度卷积参数量参数量是标准卷积的1/N, 相当于g=N的分组卷积,然后再使用逐点卷积将g组结果使用1*1conv进行拼接。

分解卷积运算总结

下图展示了不同的卷积在空间维度和通道通道维度,输入特征图和输出特征图之间的依赖关系。

preview

轻量化网络模型

SqueezeNet

(ICLR2017)SqueezeNet: AlexNet-level accuracy with 50x fewer parameters and <0.5MB model size

论文链接:http://arxiv.org/abs/1602.07360 代码链接:https://github.com/DeepScale/SqueezeNet

核心:

与AlexNet相比,相同准确率下,SqueezeNet仅需要1/50的参数量,量化后,最多可以缩小到1/510的参数量。

先在Squeeze层使用1∗1卷积进行了降维操作,压缩了参数量。之后的expand层使用1*1 和3*3尺寸的卷积来提取特征,相当于进一步压缩了参数两,然后将两个输出连接到一起,又将维度升高。但是3∗3∗16的卷积模依旧参数较多,远超1∗1卷积的参数,所以作者又针对3∗3∗16卷积进行了剪枝操作以减少参数数量。

网络结构

SqueezeNet使用Fire module基本模块堆积成。Fire模块主要包含两层卷积操作:一是采用1x1卷积核的squeeze层;二是混合使用1x1和3x3卷积核的expand层。

每一个Fire module有3个维度的超参数:squeeze convolution layer中1∗1 filter的个数,expand layer中1∗1filter的个数,expand layer中3∗3 filter的个数。

image-20210609164732690

​ 下图中,最左边为原始的SqueezeNet,中间为包含simple bypass的改进版本,最右侧为使用complex bypass的改进版本

image-20210609165105967

SqueezeNet的详细设计如下表:

image-20210929161058906

​ 针对fire2模块的计算,55x55x96 feature map输入---> 16个 1x1x96卷积---> 64个1x1x16卷积 和 64个 3x3x16卷积--->得到 55∗55∗64和 55x55x64和55x55x64大小相同的两个feature map---> 连接得到55x55x128大小的featuremap

网络实现的一些细节:

3x3卷积的参数依然很多,对其进行了剪枝操作

为了使 1∗1 和 3∗3filter输出的结果有相同的尺寸,在expand modules中,给3∗3 filter的原始输入添加一个像素的边界(zero-padding)。

squeeze 和 expand layers中都是用ReLU作为激活函数

在fire9 module之后,使用Dropout,比例取50%

没有全连接层

实验:

对比了一些超参数的影响。包括fire module 的24个超参数,fire module 个数,3∗3卷积占比的影响,压缩比(squeeze layer中filter个数除以Fire module中filter总个数)等。

SqueezeNext

(ICLR2017)SqueezeNext: Hardware-Aware Neural Network Design

paper:https://arxiv.org/abs/1803.10615

code(Pytorch):https://github.com/osmr/imgclsmob

核心:

用一个Low Rank Filters 来取代模型压缩里的低秩近似操作, 使用两个K*1的卷积核替换掉一个K*K的卷积核.

网络主要设计:

Low Rank Filters :

为去除冗余,并且减少权值参数.采用两个K*1的卷积核替换掉一个K*K的卷积核(decompose the K convolutions into two separable convolutions of size 1 × K and K × 1,)

Bottleneck Module:

采用SqueezeNet的squeeze层进行输入维度的压缩,每个block的开头使用连续两个squeeze层,每层降低1/2维度。

Fully Connected Layers:

在全连接层之前再用一个bottleneck layer,进而减小模型参数量.

如下图从左到右分别为 原始ResNet block, Squeeze Block 和SqueezeNext Block

image-20210929161618570

SqueezeNext的详细的块设计.

image-20210929162554085

文中做了一系列模拟硬件推理性能的实验来逐步改进网络结构,对比了不同结构版本的SqueezeNext. 有待于进一步细看.

MobileNet v1 v2 v3

mobileNet v1

(2017Google)MobileNets: Efficient Convolutional Neural Networks for Mobile Vision Applications

pape: https://arxiv.org/abs/1704.04861

其设计核心在于使用深度可分离卷积。

论文实验:

1.深度可分离卷积和标准卷积的对比;

2.控制模型大小的两个超参数:宽度因子(控制输入和输出的通道数)和分辨率因子(控制输入和内部层表示)的影响;

3.与其他模型对比如VGG16,SqueezeNet等;

4.在其他任务场景的表现;

mobileNet v2

(CVPR 2018)MobileNetV2: Inverted Residuals and Linear Bottlenecks

paper:https://128.84.21.199/pdf/1801.04381.pdf

mobilev1 v2 对比

image-20210608105310169

MobileNet v1 MobileNet v2
image-20210609110832545 image-20210609110841725

设计核心:

  1. 和v1一样采用DW+PW来提特征。

  2. 相比v1,在 DW 卷积之前新加了一个 PW 卷积。

    DW 卷积由于本身没有改变通道数的能力,如果上一层输入通道数很小,DW也只能在低维空间提特征,所以在每个 DW 之前都配备了一个 PW,专门用来升维,并定义升维系数为6。

  3. 去掉了第二个 PW 后的激活函数。

    作者认为激活函数在高维空间能够有效的增加非线性,而在低维空间时则会破坏特征,不如线性的效果好。由于第二个 PW 的主要功能就是降维,因此按照上面的理论,降维之后就不宜再使用 ReLU6 了。

  4. 使用Inverter Residual Block结构。

    和resnet同样采用了1x1-->3x3-->1x1 的模式,以及shorcut操作,但是resnet先降维0.25倍,卷积再升维度。而mobilenetv2则是先升维 (6倍)、卷积、再降维。由沙漏形变成纺锤形,所以称之为倒置的resnet块结构。

mobileNet v3

(ICCV2019)Searching for MobileNetV3

paper:https://arxiv.org/abs/1905.02244

MobileNetV3 是神经架构搜索得到的模型,其内部使用的模块继承自:

  1. MobileNetV1 模型引入的深度可分离卷积(depthwise separable convolutions)
  2. MobileNetV2 模型引入的具有线性瓶颈的倒残差结构(the inverted residual with linear bottleneck);
  3. MnasNet 模型引入的基于SE(squeeze and excitation)结构的轻量级注意力模型。

MobileNetV3-Large在ImageNet分类上的准确度与MobileNetV2相比提高了3.2%,同时延迟降低了15%。 MobileNetV3-large 用于目标检测,在COCO数据集上检测精度与MobileNetV2大致相同,但速度提高了25%。

ShuffleNet v1 v2

shuffleNet v1

(CPVR2018)ShuffleNet: An Extremely Efficient Convolutional Neural Network for Mobile Devices

paper:https://arxiv.org/pdf/1707.01083.pdf

核心:针对深度可分离卷积的Pointwise卷积上的性能瓶颈(逐点卷积计算量可观),提出了分组Pointwise卷积。又针对组间通道信息沟通的问题,提出了channel shuffle操作。

下图为几种网络单元的对照,包括moblinet ,shuffleNet ,shuffleNet降采样。

image-20210608175258779

shuffleNet v1结构特点:

  • 较于mobileNetv2,前后两个1x1的卷积替换为两个1x1的分组卷积。g的值确保能够被通道数整除,保证reshape操作的有效执行。
  • 第一个卷积后进行channel shuffle操作
  • 去掉了DW卷积之后的ReLU激活,目的是为了减少ReLU激活造成的信息损耗

​ 对比ResNet,ResNeXt,ShuffleNet v1的FLOPs,即执行一个单元需要的计算量。假设输入尺寸为$whc$,输出通道数为$m$。

$F_{ResNet} = hwcm + 33hwmm + hwcm = hw(2cm+9m^2)$

$F_{ResNeXt} = hwcm + 33hwm/gm/g*g+hwcm = hw(2cm+9m^2/g)$

$F_{ShuffleNetv1} = hwc/gm/gg+33hwm+hwc/gm/gg = hw(2cm/g+9m)$

其FLOPs的关系为: $$ F_{Resnet} > F_{ResneTx}>F_{ShuffleNetv1} $$

shuffleNet v2

(ECCV2018)ShuffleNet V2: Practical Guidelines for Efficient CNN Architecture Design

paper:https://arxiv.org/pdf/1807.11164.pdf

核心:提出高效模型的设计准则,基于这些设计准则提出了shuffleNetv2网络结构。

模型的性能不应只考虑FLOPs,还需考虑内存读写,GPU并行性,文件IO等。

image-20210609150108144

上图说明,在 GPUARM 两个平台上,具有相同 FLOPs 的模型运行速度也会相差很多。因此只用 FLOPs 来衡量计算复杂度是不充分的,也会导致得不到最优的网络设计。

image-20210609150618057

​ 上图对不同模型在不同平台上的运行时间组成进行了统计,虽然以 FLOPs 度量的卷积占据了大部分的时间,但其余操作也消耗了很多运行时间,比如数据输入输出、通道打乱和逐元素的一些操作(张量相加、激活函数)。因此,FLOPs 不是实际运行时间的一个准确估计。

​ 作者从内存访问代价(Memory Access Cost,MAC)和GPU并行性的方向分析了网络应该怎么设计才能进一步减少运行时间,直接的提高模型的效率。

高效模型设计准则

  1. 当输入通道数和输出通道数相同时,MAC最小。使用输入通道和输出通道相同的卷积操作;

    实验:基准的网络由 10 个卷积 block 组成,每个块有两层卷积,第一个卷积层输入通道数为c1,输出通道数为 c2,第二层与第一层相反,然后固定总的 FLOPs 调整 c1:c2 的值测试实际的运行速度.

  2. MAC与分组数量g成正比。谨慎使用分组卷积;

    实验:通过叠加 10 个分组点卷积层设计了实验,在保证计算代价(FLOPs)相同的情况下采用不同的分组组数测试模型的运行时间

  3. 网络的分支数量降低并行能力。减少网络分支数;

    block 中的每一个卷积或者池化操作称之为一个 fragmented operator。这种 fragmented structure(碎片化/支路结构)能够提升模型的准确性,但是其会降低效率,因为这种结构 GPU对并行性强的设备不友好。而且它还引入了额外的开销,如内核启动和同步。

    实验:评估了一系列具有不同碎片化程度的网络块,实验的每个构建块由 1 到 4 个 顺序或并行结构的1x1 卷积层组成。每个 block 重复堆叠 10 次,比较运行速度。

  4. Element-wise操作是非常耗时的。减少element-wise操作。

    实验将"bottleneck"单元重复堆叠10次,通过移除ReLU和short-cut Operation来对比,逐元素操作对模型速度的影响。逐元素算子包括 ReLUAddTensorAddBias等,但shortocut不算逐元素算子。

由以上准则判断,ShuffleNet v1严重依赖分组卷积;MobileNet v2利用了反转瓶颈结构依赖通道变化;

shuffleNet v2 网络

下图中a,b为shuffleNet v1 ,c,d为shuffleNet v2

image-20210609114009887

shuffleNet v2的网络结构特征

  • 使用了一个Channel Split,将输入的c个特征通道分为两组 ,论文中设为平均分为两组,相当于通道分组,但是控制了分组数量。
  • 1x1卷积没有像v1使用分组卷积
  • 左分支进行了直接映射, 右分支包含三个通道数一样的卷积。
  • 去除了add操作,使用connat 进行通道拼接。

网络精度的分析。ShuffleNet v2不仅高效而且精度也高。有两个主要理由:

一是高效的卷积 block结构允许我们使用更多的特征通道数,网络容量较大。

二是不进行下采样时时,一半的特征图直接经过当前卷积 block 并进入下一个卷积 block,这类似于 DenseNet和 CondenseNet 的feature reuse结构,且特征的重用随着特征距离越远呈现指数级下降,因为距离越近的Feature Map之间的特征重用越重要。

精辟的ref:https://zhuanlan.zhihu.com/p/42288448

ChannelNet

(NeurIPS 2018)ChannelNets:Compact and Efficient Convolutional Neural Networks via Channel-Wise Convolutions

论文地址:http://arxiv.org/abs/1809.01330

论文代码:http://github.com/HongyangGao/ChannelNets

核心:

基于分组卷积的一种改进, 提出channel-wise卷积的概念,将输入输出的维度连接进行稀疏化而非全连接,区别于分组卷积的严格分组,让卷积在channel维度上进行滑动,能够更好地保留channel间的信息交流。

基于channel-wise卷积的思想,论文进一步提出了channel-wise深度可分离卷积,并基于该结构替换网络最后的全连接层+全局池化的操作,搭建了ChannelNets。

网络设计:

下图中,(a)是深度可分卷积,(b)是将深度可分卷积中的1x1卷积替换为分组1x1卷积,(c)是本文提出的分组逐通道卷积(以融合各组信息),(d)是本文提出的深度可分逐通道卷积,其在深度卷积后面接一个channel-wise卷积用以融合特征来降低参数量和计算量

image-20210929165732133

​ ChannelNet根据MobileNet的基础结构进行构建,设计了如下图(a)分组模块(GM)和(b)分组channel-wise模块(GCWM)。由于GM模块存在信息阻隔的问题,所以在GM模块前面使用GCWM来生成包含全局信息的分组特征。

image-20210929170840145

相较于原始mobileNet , 可以看到 1*1卷积被 1*1 组卷积替代,添加了skip connection; 而GCWM模块则多了一个分组逐通道卷积, 以融合来自不同组的信息.

ChannelNet包含3个版本:

  • ChannelNet-v1替换了部分深度可分离卷积为GM和GCWM,分组数为2,共包含约370万参数。
  • ChannelNet-v2替换最后的深度可分离卷积为深度可分离channel-wise卷积,大约节省100万参数,占ChannelNet-v1的25%参数。
  • ChannelNet-v3替换最后的池化层加全连接层为上述的Convolutional Classification Layer,大约节省了100万(1024x1000-7x7x25)参数。

实验与MobileNet, shuffleNet对比了, 但是进一步的v2v3设计只和MobileNet对比了.

IGC系列

ref:https://copyfuture.com/blogs-details/20210527120210647d

该系列主要是基于分组卷积做改进.

(ICCV2017)Interleaved Group Convolutions for Deep Neural Networks

paper:https://arxiv.org/abs/1707.02725

主要设计:

分为主分组卷积和次分组卷积,主分组卷积负责对输入特征图进行分组特征提取,而次组卷积负责对主分组卷积的输出进行融合.主分组卷积和次分组卷积后分别补充了两个排序模块来保证channel间的信息交流。

结构如下:

image-20210929173112981

(CVPR2018)IGCV2: Interleaved Structured Sparse Convolutional Neural Networks

paper:https://arxiv.org/abs/1804.06202

IGCV1通过主次两个分组卷积来对原卷积进行分解, 因为主分组卷积和次分组卷积在分组数上是互补的,导致次卷积的分组数一般较小,每个分组的维度较大,次卷积核较为稠密。IGCV2在IGCV1基础上进一步稀疏化,使用多个稀疏卷积代替原本较为稠密的次卷积.

(BMVC 2018)IGCV3: Interleaved Low-Rank Group Convolutions for Efficient Deep Neural Networks

paper:https://arxiv.org/abs/1806.00178

引入低秩分组卷积来代替原本的分组卷积.

ESPNetV1和V2

(ECCV2018)ESPNet: Efficient Spatial Pyramid of Dilated Convolutions for Semantic Segmentation

paper: https://arxiv.org/abs/1803.06815v2

code: https://github.com/sacmehta/ESPNet

ref:https://blog.csdn.net/sinat_37532065/article/details/85723068

(CVPR2019)ESPNetv2: A Light-weight, Power Efficient, and General Purpose Convolutional Neural Network

paper:https://arxiv.org/pdf/1811.11431.pdf code:https://github.com/sacmehta/espnetv2

ref:https://blog.csdn.net/weixin_43624538/article/details/94578886

AdderNet

(CVPR2020)AdderNet: Do We Really Need Multiplications in Deep Learning?

论文链接:https://arxiv.org/pdf/1912.13200.pdf

源码:https://github.com/huawei-noah/AdderNet

创新点:

将深度神经网络中,特别是卷积神经网络中的乘法,转换为更简单的加法运算,以便减少计算成本。采用了 L1 正则距离,用于计算滤波器和输入特征之间的距离,并作为输出的反馈。构建了一种特殊的反向传播方法,并发现这种几乎完全采用加法的神经网络能够有效收敛,速度与精度都非常优秀。

WeightNet

(ECCV2020megvii)WeightNet: Revisiting the Design Space of Weight Networks

论文:https://arxiv.org/pdf/2007.11823.pdf

代码:https://github.com/megvii-model/WeightNet

https://www.cnblogs.com/gaopursuit/p/13497401.html

GhostNet

(华为CVPR2020)GhostNet: More Features from Cheap Operations

paper:https://arxiv.org/pdf/1911.11907.pdf

code:https://github.com/huawei-noah/CV-Backbones

核心:使用更小的代价生成特征图,并从生成的特征图中进一步挖掘Ghost feature maps;提出了一个plug-and-play的Ghost module。

​ 作者在分析输出的特征图的时候发现了许多成对的相似的特征图,并认为一些特征图可以通过其他特征图经过简单的变换得到。强调存在冗余的特征图。 image-20210610102945983

提出方法:

1.GhostNet先使用正常卷积计算,但是得到channel较少的特征图(减少卷积核数量)

2.利用cheap operation(诸如3*3的卷积)得到更多的特征图,并且是逐个特征图的进行卷积。

3.最后将不同的特征图concat到一起,组合成新的output.

image-20210610093813510

网络结构:

image-20210610094801849

结构与ResNet的是类似,并且与mobilenet v2一样在第二个module之后不采用ReLU激活函数。

Ghost Net结构与MobileNet-V3类似,并且在一些层使用了SE结构.

实验:

1.Ghost模块具有两个超参数,$s$用于生成$m=n/s$ 个内在特征图,以及用于计算幻影特征图的线性运算的$d*d$(即深度卷积核的大小),控制变量测试了这两个参数的影响,s2=,d=3最优。

2.对VGG-16和ResNet-56进行ghost module的即插即用实验,具体做法是,对于VGG-16和ResNet-56,其中的所有卷积替换为Ghost module,精度不怎么变化的条件下,参数和FLOPs均减少一半左右

3.搭建的GhostNet网络在分类和目标检测上的表现与其他SOA的对比。

RepVGG

CVPR2021 paper: RepVGG: Making VGG-style ConvNets Great Again

code:https://github.com/DingXiaoH/RepVGG

image-20210610172517179

  1. 训练一个多分支模型

  2. 将多分支模型等价转换为单路模型

  3. 部署单路模型

同时利用多分支模型训练时的优势(性能高)和单路模型推理时的好处(速度快、省内存)。

RepVGG是为GPU和专用硬件设计的高效模型,追求高速度、省内存,较少关注参数量和理论计算量。在低算力设备上,可能不如MobileNet和ShuffleNet系列适用。

基于任务的轻量化网络模型

ClassSR

(cvpr2021)ClassSR: A General Framework to Accelerate Super-Resolution Networks by Data Characteristic

也是一种轻量化模型的思路. 通过将输入图像根据超分难度分成不同区域, 再利用不同大小的模型进行超分,实现了推理加速。算是一个比较简单且有效的加速方案,可以在任何底层视觉任务中尝试。

image-20210812102904746

Lite-HRNet

(CVPR2021)Lite-HRNet: A Lightweight High-Resolution Network

(人体姿态估计,语义分割)

代码:https://github.com/HRNet/Lite-HRNet 论文:https://arxiv.org/abs/2104.0640

直接在HRNet上使用shuffle block,对比其表现。为了让网络更高效,替换shuffle blocks中的pointwise1*1卷积,引入了一个轻量级的单元conditional channel weighting uint。

ThunderNet

(ICCV2019 megvii)ThunderNet:Towards Real-time Generic Object Detection

轻量级实时目标检测网络

论文地址:https://arxiv.org/pdf/1903.11752.pdf 源码地址:https://github.com/mohhao/TF-Keras-ThunderNet

在Shufflenet v2和Lighthead r-cnn基础上,提出了一种新的SNet主干,进一步压缩 RPN和检测头,并设计了独特的CEM和SAM模块,在轻量化和精度上均有出色的表现。

PeleeNet

(ICLR2018)Pelee: A Real-Time Object Detection System on Mobile Devices

轻量化目标检测网络

论文:https://arxiv.org/pdf/1804.06882.pdf

code:https://github.com/Robert-JunWang/Pelee

遵循 DenseNet 的创新连接模式和一些关键设计原则,是一种基于Densenet的轻量化网络变体(variant)。以PeleeNet为主干(backbone)的SSD目标检测网络,具备轻量化的特点,非常适合移动端的部署。

BiSeNet和DFANet

低计算量的实时语义分割

(ECCV2018 megvii)BiSeNet: Bilateral Segmentation Network for Real-time Semantic Segmentation

论文:https://arxiv.org/abs/1808.00897

(CVPR2019 megvii) DFANet:Deep Feature Aggregation for Real-Time Semantic Segmentation

论文链接:https://share.weiyun.com/5NgHbWH

ResNet和ResNeXt

ResNet

(CVPR2016)Deep Residual Learning for Image Recognition

paper:https://arxiv.org/pdf/1512.03385.pdf

核心思想:残差学习来解决深度网络退化问题

​ 假设输入为x, 其学习到的特征为H(x), 如果学习其残差, 即学习到 F(x) = H(x)-x ,得到残差后,其学习到的特征即为H(x)=F(x)+x , 而残差需要学习的内容较少更易学习,且即使残差为0,输入输出也是恒等映射网络性能至少不会下降。

resnet由building block或bottleneck组成。

building block bottleneck
image-20210608141136921 image-20210608140748430
比传统的卷积结构多了一个short-cut支路,用于传递低层的信息使得网络能够训练地很深 先通过一个1x1的卷积减少通道数,使得中间卷积的通道数减少为1/4,中间普通卷积,再通过1x1卷积恢复通道数。

实验对比了普通网络和resnet网络不同深度的网络退化情况。

ResNeXt

(CVPR2017)Aggregated Residual Transformations for Deep Neural Networks

paper:https://sci-hub.ru/10.1109/cvpr.2017.634

核心思想:结合了ResNet的shortcut和inception的split-transform-merge结构。

​ 用一种平行堆叠相同拓扑结构的blocks代替原来 ResNet 的三层卷积的block,在不明显增加参数量级的情况下提升了模型的准确率,同时由于拓扑结构相同,超参数也减少了,便于模型移植。

下图左边为resnet,右边为resneXt。

image-20210608151226108

下图对比了ResNeXt组件与等价的inception-resnet 和分组卷积的结构差异。

image-20210608150659222

ResNeXt网络结构特点:

  • 相较于inception,其分支的拓扑结构相同,而Inception不同分支的不同拓扑结构,需人工去设置大量超参数。此外inception先进行拼接再使用1x1卷积,而resNeXt先进行1x1卷积再进行拼接。
  • 其结构本质上是一种分组卷积,通过设置Cardinality基数来控制组的数量。

论文实验

仅改变ResNet中block进行对比,相较于ResNet其计算量差不多,而训练误差和测试误差都降低。

证明了Cardinality的增加比增加网络深度和宽度更有效。

控制变量证明了residual connection的有效性,也证明了aggregated transformations的有效性。

SENet

(2017ImageNet winner paper)Squeeze-and-Excitation Network

paper:https://arxiv.org/pdf/1709.01507.pdf

核心:SENet网络的创新点在于关注channel之间的关系,希望模型可以自动学习到不同channel特征的重要程度。SEblock可以看作给不同通道的feature map赋不同的权重。可以很方便的嵌入到现在的网络结构,比如ResNet、Inception、ShuffleNet,实现精度的提升。

网络结构:

image-20210609180033061

  • Sequeeze:对 HxWxC 的特征图进行global average pooling,得到1x1xC大小的特征图,这个特征图可以理解为具有全局感受野。

  • Excitation :采用包含两个全连接层的bottleneck结构,其中第一个FC层起到降维的作用,降维系数为r是个超参数,然后采用ReLU激活。再使用第二个FC层恢复原始的维度, 最后将学习到的各个channel的激活值(sigmoid激活,值0~1)作为各个channel的权重

  • 特征重标定:使用Excitation 得到的结果作为权重,乘到输入特征上。

嵌入inception 和ResNet:

image-20210610090549905

​ 使用两个FC中间又使用ReLU的作用:1)具有更多的非线性,可以更好地拟合通道间复杂的相关性;2)减少了参数量和计算量。

shuffleNetv2 中嵌入了SENet组件进行实验,模型在更少FLOPs,且精度优于其他SOA模型。

GhostNet也嵌入了SENet组件。

ref:https://zhuanlan.zhihu.com/p/65459972

网络模型压缩

CNN模型压缩是从压缩模型参数的角度降低模型的计算量。

网络剪枝(Network Pruning)

​ 网络剪枝简单来说就是去除模型参数中冗余和不重要的参数,减小网络模型大小.

剪枝粒度的划分

根据剪枝的修剪粒度进行划分可分为如下图五种剪枝方法:

image-20210927153916180

  • Fine-grained中 这种细粒度的剪枝方法以非结构化的方式去除参数,即卷积核中任何不重要的参数都可以剪枝.由于对剪枝模式没有额外的限制,参数可以被高度稀疏地剪枝。

  • Filter-level修剪方法修剪卷积过滤器或通道.

  • Vector-level修剪卷积核中的向量,Kernel-level方法修剪滤波器中的二维卷积核. 由于大多数修剪 方法侧重于细粒度剪枝或过滤器级剪枝,向量级和内核级的工作很少.

  • Group-level 剪枝中 每个filter的稀疏模式相同

衡量模型参数重要性

衡量模型参数重要性, 然后将不重要的部分去除。

  • 按参数(或特征输出)绝对值大小来评估重要性

    2016年经典论文《Pruning Filters for Efficient ConvNets》中把权重的绝对值作为衡量其重要性的手段。但训练出来的权重如果不稀疏不利于pruning怎么办,常用的办法是在训练时loss中加regularizer,尤其是L1 regularizer,从而使得权重稀疏化。对structured pruning来说,我们想获得结构化的稀疏权重,因此常用group LASSO来得到结构化的稀疏权重,如2015-16年的论文《Learning Structured Sparsity in Deep Neural Networks》和《Sparse Convolutional Neural Networks》等。

    2017年论文《Learning Efficient Convolutional Networks Through Network Slimming》通过一种巧妙的方法,基于BN(Batch Normalization)层的广泛使用,在BN层加入channel-wise scaling factor 并对之加L1 regularizer使之稀疏,然后裁剪scaling factor值小的部分对应权重。

    另外,重要性评估也可以针对activation(激活值,即激活函数的输出),当然就算是针对activation最后也会体现在权重的裁剪上。一般来说,像Relu这样的激活函数会倾向产生稀疏的activation;而权重相对而言不太容易是稀疏的(当前,如前所说,我们可以通过regularizer这种外力使它变得稀疏)。从这种意义上说,activation更适合pruning。如2016年论文《Network Trimming: A Data-Driven Neuron Pruning Approach towards Efficient Deep Architectures》中提出采用Average Percentage of Zeros,即APoZ来衡量activation的重要性。它定义为activation中为0的比例。

  • 考虑参数裁剪对loss的影响

    《Optimal brain damage》与《Second order derivatives for network pruning: Optimal Brain Surgeon》分别提出OBD和OBS方法,它们基于损失函数相对于权重的二阶导数(对权重向量来说即Hessian矩阵)来衡量网络中权重的重要程度,然后对其进行裁剪。

    2016年论文《Pruning Convolutional Neural Networks for Resource Efficient Transfer Learning》也是基于Taylor expansion,但采用的是目标函数相对于activation的展开式中一阶项的绝对值作为pruning的criteria。这样就避免了二阶项(即Hessian矩阵)的计算。

    2018年论文《SNIP: Single-shot Network Pruning based on Connection Sensitivity》将归一化的目标函数相对于参数的导数绝对值作为重要性的衡量指标。

  • 最小化裁剪后网络对于特征输出的重建误差

    它的intuition是如果对当前层进行裁剪,然后如果它对后面输出还没啥影响,那说明裁掉的是不太重要的信息。典型的如2017年论文《ThiNet: A Filter Level Pruning Method for Deep Neural Network Compression》和《Channel pruning for accelerating very deep neural networks》都是通过最小化特征重建误差(Feature reconstruction error)来确定哪些channel需要裁剪。前者采用贪心法,后者用的LASSO regression。2017年论文《NISP: Pruning Networks using Neuron Importance Score Propagation》提出只考虑后面一两层啥的不够,于是提出NISP(Neuron importance score propagation)算法通过最小化分类网络倒数第二层的重建误差,并将重要性信息反向传播到前面以决定哪些channel需要裁剪。2018年论文《Discrimination-aware Channel Pruning for Deep Neural Networks》提出一种比较有意思的变体。它提出DCP(Discrimination-aware channel pruning)方法一方面在中间层添加额外的discrimination-aware loss(用以强化中间层的判别能力),另一方面也考虑特征重建误差的loss,综合两方面loss对于参数的梯度信息,决定哪些为需要被裁剪的channel。

  • 其他准则的权重排序

    如2018年的论文《Filter Pruning via Geometric Median for Deep Convolutional Neural Networks Acceleration》讨论了magnitude-based方法的前提与局限(即需要其范数值方差大,且最小值接近于0)。它提出了 FPGM(Filter Pruning via Geometric Median)方法。其基本思想是基于geometric median来去除冗余的参数。

Sparsity Ratio

这里的sparsity ratio定义为层中为0参数所占比例,有些文章中也称为pruning rate等.

如何确定sparsity ratio?

按ICLR 2019论文《Rethinking the Value of Network Pruning》中的说法可分为预定义(predifined)和自动(automatic)两种方式.

  • Predefined方法由人工指定每一层的比例进行裁剪,因此目标结构是提前确定。

    从某种意义上来说,著名的MobileNet《MobileNets: Efficient Convolutional Neural Networks for Mobile Vision Applications》中提出的multiplier参数也是一种predefined的network pruning方法。只是它比较简单粗暴,将相同的裁剪比例用于所有层,且裁剪后权重不重用。2019年在《EfficientNet: Rethinking Model Scaling for Convolutional Neural Networks》中提出的EfficientNet将这种参数调节更进一步,提出compound scaling method将width, depth, resolution按特定比例一起调节。但它们调节参数都是针对网络中所有层的,粒度比较粗。

    ​ 但是网络中不同层对于pruning的敏感(sensitivity)程度是不一样的,只有根据层的属性为每层设置最适合的sparsity ratio才是最优的,这种为每层专设的称为local sparsity,相对的针对网络中所有层的,粒度比较粗的那种就称为global sparsity。

    ​ 2015和2016年经典论文《Learning both Weights and Connections for Efficient Neural Networks》和《Pruning Filters for Efficient ConvNets》中对网络中各层的敏感度进行了分析,发现卷积层比全连接层对pruning更敏感(直觉上,由于卷积层中的参数共享,所以参数量会比全连接层少得多),另外不同的卷积层之间敏感度也不一样,如第一层卷积对pruning就相对更敏感,ResNet中每个stage中第一个和最后一个residual block比中间block更敏感等。这里就引申出一个重要问题,就是如何确定每一层的最优的sparsity ratio。在predefined这类方式中,一种就是通过前面的提到的根据每一层对pruning的敏感度确定每一层的sparsity ratio.

  • automatic方法会根据所有的layer信息(即全局信息)由pruning算法确定每层裁剪比例,因此目标结构一开始并不确定。

    automatic方法需要pruning算法从全局信息中自动得到每层裁剪多少。上面提到过的论文《Learning Efficient Convolutional Networks through Network Slimming》就属于此类。另外,2019年论文《Play and Prune: Adaptive Filter Pruning for Deep Model Compression》将pruning问题建模成min-max优化问题,然后通过两个模块交替迭代分别进行裁剪和通过调节pruning rate控制精度损失。2018年论文《ADC: Automated Deep Compression and Acceleration with Reinforcement Learning》提出ADC(Automated deep compression)方法,根据不同需求(如保证精度还是限制计算量),利用强化学习来学习每一层最优的sparsity ratio。2018年论文《“Learning-Compression” Algorithms for Neural Net Pruning》提出Learning和Compression两步交替优化的pruning方法,在Compression操作中,通过将原参数向约束表示的可行集投影来自动找到每层的最优sparsity ratio。因为此类方法不需要计算量较大的sensitivity analysis,也减少了超参数的引入。因此,近年来,这类方法的研究越来越多。

refs:

2018:Recent Advances in Efficient Computation of Deep Convolutional Neural Networks

很详细的剪枝相关方法的总结

pytorch中实现的torch.nn.utils.prune 剪枝库, 可以根据需要进行weight 剪枝, 同时也可以自定义剪枝策略.该库的使用教程地址:https://pytorch.org/tutorials/intermediate/pruning_tutorial.html

关于神经网络剪枝的相关资源整合:https://github.com/he-y/Awesome-Pruning

参数量化(Parameter Quantization )

​ 参数量化的压缩方法: 通过减少表示每个权重的比特数的方法来压缩神经网络。

​ 低精度的模型不易训练, 高精度的模型会带来较大的存储压力, 通过量化的方式对模型进行压缩,原始的权重只需要更少的bit位存储,既减少访存又减少计算量,虽然量化会损失精度, 这相当于给网络引入了噪声,但是神经网络一般对噪声是不太敏感. 控制好量化方法,可以得到对模型精度影响很小的轻量模型.

​ 对原始高精度的网络权值进行一个定点的表示,比如用一个低比特,如INT8,甚至是一个binary或者ternary权值, 这种方法也称作定点权重量化方法.

​ 目前工业界用的最多的方案是 INT8 量化, FP32 浮点数张量在推理阶段使用INT8张量取代 , 而训练阶段仍然使用 FP32。

定点数和浮点数

**浮点数:**实数以指数形式存放在存储单元中。类似于科学计数法a×10^n

把存储字长分成若干部分,分别表示符号位, 指数位和尾数位。

小数点位置随指数的不同,在一定范围内可以自由浮动。

image-20210928104946344

**定点数:**约定小数点隐含在某一个固定的位置

比如: 用1位来表达正负位, 再划出4位来表示整数部分,剩下的27位表示小数部分。

固定的小数点位置决定了固定位数的整数部分和小数部分,不利于同时表达特别大或特别小的数

image-20210928104934976

浮点数具有具有比定点数更高的动态表达范围,更高的精度。

INT8量化原理

参考:8-BIT INFERENCE WITH TENSORRT

FLOAT32是怎样量化成INT8的??

值域范围 可取数值数量
FLOAT32 $[(2-2^{-23})*2^{127}, (2^{-23} - 2)*2^{127}]$ $2^{32}$
INT8 $[-128,127]$ $2^8$

值域范围详细计算参考:float32和int32同样占32位的存储方式的区别

INT8的量化相当于原来使用32bit来表示一个tensor,现在使用8bit来表示一个tensor,还要求精度不能下降太多。

通常使用线性映射(或称线性量化,linear quantization) 来将FP32转换为 INT8.映射前后的关系满足下式: $$ FP32Tensor(T) = scale_factor(sf) * 8bitTensor(t) + FP32_bias(b) $$ nivida的试验表示去掉bias对精度影响不大,因此去掉偏置,也就是 $$ T=sf∗t $$ sf是每一层上每一个tensor的换算系数或称比例因子(scaling factor),因此现在的问题就变成了如何确定比例因子。

​ 如果按照下图,简单的将一个layer下的激活值的 -|max| 和 |max| FP32 value 映射到-127 和 127 ,中间值按照线性关系进行映射。则称这种映射关系为不饱和的(No saturation ), 试验结果显示这样做会导致比较大的精度损失。因为这样按照最大绝对值对称取域值的方法会使得当值得正负分布不均匀的时候,是有一部分是空缺的,也就是一部分值域被浪费了,可能导致数值在转换后被密集的压缩在一个很小的范围内.

image-20210928150300887

于是采用了以下映射方法, 不是将 ±|max| 映射到 ±127,取一个阈值 |T| ,将 ±|T| 映射为±127,这里 |T|<|max|。

超出阈值的值直接被映射为127,-127. 这里称这种映射关系为饱和的(Saturate), 因为只要阈值选取取得当,就能将分布散乱的较大的激活值舍弃掉,也就有可能使精度损失不至于降低太多。

image-20210928150327775

接下来需要找出这个阈值T, 使得映射到INT8后得到的新的分布尽可能的接近原始FP32表示的分布.

我们使用KL散度Kullback–Leibler divergence,简称KLD)这个衡量指标来衡量不同的 INT8 分布与原来的FP3F2分布之间的差异程度.

KL散度越小代表 INT8编码后的信息损失越少。

如何使用KL散度映射到最佳INT8分布?

  • 首先得有一个以FP32精度训练好的模型。

  • 从验证集选取一个子集作为校准集(Calibration Dataset )校准集应该具有代表性,多样性,最好是验证集的一个子集,不应该只是分类类别的一小部分。激活值分布就是从校准集中得到的。

  • 首先在 校准集上 进行 FP32 inference 推理;

  • 对于网络的每一层(遍历):

    • 收集这一层的激活值,并做直方图(histograms ),分成几个组别(bins)(官方给的一个说明使用的是2048组),分组是为了下面遍历 |T| 时,减少遍历次数;
    • 对于不同的阈值|T|进行遍历,因为这里 |T|的取值肯定在 第128-2047 组之间,所以就选取每组的中间值进行遍历;选取使得 KL_divergence(ref_distr, quant_distr) 取得最小值的 |T|。
  • 返回一系列 |T|值,每一层都有一个 |T|。创建 CalibrationTable

通过上述步骤, 得到选取的阈值T, 从而得到FLOAT32到INT8的线性映射转换.

​ 按照量化阶段的不同,一般将量化分为 quantization aware training(QAT) 和 post-training quantization(PTQ)。QAT 需要在训练阶段就对量化误差进行建模,这种方法一般能够获得较低的精度损失。PTQ 直接对普通训练后的模型进行量化,过程简单,不需要在训练阶段考虑量化问题,因此,在实际的生产环境中对部署人员的要求也较低,但是在精度上一般要稍微逊色于 QAT.

ref:

https://zhuanlan.zhihu.com/p/149659607?from_voters_page=true

https://zhuanlan.zhihu.com/p/58182172

https://zhuanlan.zhihu.com/p/370668166

二进制权重神经网络

​ 二值化网络可以视为量化方法的一种极端情况:所有的权重参数取值只能为 $\pm 1$ ,也就是使用 1bit来存储WeightFeature。在普通神经网络中,一个参数是由单精度浮点数来表示的,参数的二值化能将存储开销降低为原来的 1/32

​ 第一篇真正意义上将神经网络中的权重值和激活函数值同时做到二值化的是 Courbariaux 等人 2016 年发表的名为《Binarynet: Training deep neural networks with weights and activations constrained to +1 or -1》的一篇论文。这篇论文第一次给出了关于如何对网络进行二值化和如何训练二值化神经网络的方法

​ 直接使用二进制权重训练 CNN的相关工作如: BinaryConnect 、BinaryNet 和 XNOR 。

二值网络的模块

​ CNN 网络一个典型的模块是由卷积(Conv)->批标准化(BNorm)->激活(Activ)->池化(Pool)这样的顺序操作组成的。对于二值化神经网络,设计出的模块是由批标准化(BNorm)->二值化激活(BinActiv)->二值化卷积(BinConv)->池化(Pool)的顺序操作完成。这样做的原因是批标准化以后,保证了输入均值为 0,然后进行二值化激活,保证了数据为 -1 或者 +1,然后进行二值化卷积,这样能最大程度上减少特征信息的损失.

二值网络的梯度下降

  1. 权重 weight 初始化为浮点
  2. 前向传播 Forward Pass:
  • 利用决定化方式(sign(x)函数)把 Weight 量化为 +1/-1, 以0为阈值
  • 利用量化后的 Weight (只有+1/-1)来计算前向传播,由二值权重与输入进行卷积运算(实际上只涉及加法),获得卷积层输出。
  • 反向传播 Backward Pass:
  • 把梯度更新到浮点的 Weight 上(根据放松后的符号函数,计算相应梯度值,并根据该梯度的值对单精度的权重进行参数更新)
  • 训练结束: 把 Weight 永久性转化为 +1/-1, 以便 inference 使用

ref:

模型量化总结

神经网络量化基本原理

Quantization and Training of Neural Networks for Efficient Integer-Arithmetic-Only Inference

低秩近似(Low-rank Approximation)

​ 卷积神经网络的权重矩阵往往稠密且巨大,从而计算开销大,有一种办法是**采用低秩近似的技术将该稠密矩阵由若干个小规模矩阵近似重构出来,使得小矩阵的组合在表达能力上与原始卷积层基本一致,**这种方法归类为低秩近似算法。

​ 高维矩阵的运算往往会涉及使用低秩分解来做加速和压缩, 低秩分解方法主要有:

  • SVD分解
  • CP分解(Canonical Polyadic Decomposition)
  • Tucker分解
  • Tensor-train 分解
  • BTD(BlockTerm Decomposition)

​ 以上方法均是针对张量的分解方法, 这里的张量通常是指多维数组,或者说是多维向量空间中的元素。一阶张量称为向量,二阶张量称为矩阵,三阶或者更高阶张量则称为高阶张量或者直接称为张量。

​ 一个卷积核通常包含四个维度w,h,c,n, 已经提出的基于低秩的方法区别在于如何重新排列四个维度,以及对哪个维度施加低秩约束。根据滤波器分解成的分量有多少可以分为:二分量分解、三分量分解和四分量分解

​ SVD 是二分量低秩矩阵分解方法, 它将权重张量分解为了两个分量. 通过合并维度 w、h 和 c,滤波器变为大小为 (w ∗ h ∗ c) × n 的二维矩阵,可以在其上进行 SVD 分解方法。然后将滤波器使用两个滤波器组替换:一个由 d 个形状为 w × h × c 的滤波器组成,另一个由 n 个形状为 1 × 1 × d 的滤波器组成。 这里,d 表示分解的秩,即 n 个过滤器是前 d 个过滤器的线性组合。

秩(rank)

通过矩阵初等变换把A化为阶梯型矩阵,若该阶梯型矩阵有r个非零行,那A的秩rank(A)就等于r。 如果矩阵的各行或列是线性无关的,矩阵就是满秩的,也就是秩等于行数.

低秩(low)

如果X是一个m行n列的数值矩阵,rank(X)是X的秩,假如rank (X)远小于m和n,则我们称X是低秩矩阵。低秩矩阵每行或每列都可以用其他的行或列线性表出,可见它包含大量的冗余信息。利用这种冗余信息,可以对缺失数据进行恢复,也可以对数据进行特征提取。

  • 现在越来越多网络中采用1×1的卷积,而这种小的卷积使用矩阵分解的方法很难实现网络加速和压缩,使得Low-Rank不再流行.

  • 低秩逼近的方法用于全连接层效果较好,但是对运行时间提升空间不是很大。一般能达到1.5倍。将低秩逼近的压缩算法用于卷积层时,会出现误差累积的效果,对最后精度损失影像较大,需要对网络进行逐层的微调,费时费力。

ref:

Recent Advances in Efficient Computation of Deep Convolutional Neural Networks

权值共享(Weight Sharing)

卷积核的权值共享

​ 一个卷积层可以有多个不同的卷积核, 而每个卷积核对应一个滤波后映射得到的新图像, 同一个新图像中每个像素都来自完全相同的卷积核.

网络模型压缩的权值共享

​ 通过让多个连接共享相同的权重来限制我们需要存储的有效权重的数量,然后微调这些共享的权重, 压缩模型的基础上保证模型精度.

​ 假设有一层有四个神经元输入, 四个神经元输出, 那么 此时的权重是一个4*4的矩阵, 如下图中, 权重被量化为 4 类(用 4 种颜色表示),同一个类中的所有权重共享相同的值。每个类别只需要保存一个聚类中心的权值,和对应的聚类索引(index)数据量大幅度减少. 权重更新期间,所有梯度也都按颜色分组并相加,结合学习率使用上次迭代的共享质心进行更新。

image-20210926154724987

如何计算其压缩率? 对于给定的聚成的k个类, 只需要log2(k) 位来编码索引。 通常,对于具有 n 个连接且每个连接用 b 位表示的网络,如果其有k个共享权重, 那么其压缩率计算为:

image-20210926162753134

如上面的例子, 4x4个连接, 需要存储4x4个 权重值, 存储每个权重需要32bits, 但是上述使用了4个共享权重, 那么其压缩率为$(1632)/(16log(4)+ 4*32)=3.2 $

以上的这个权值共享的压缩方法也会被分到参数量化的压缩方法下, 称作k均值标量量化法.

ref:

ICLR2016:Deep Compression: Compressing Deep Neural Networks with Pruning, Trained Quantization and Huffman Coding

知识蒸馏(Knowledge Distillation)

知识蒸馏的作用

​ 知识蒸馏就是把一个大模型或者多个模型ensemble学到的知识迁移到另一个轻量级的单模型上,最主要的目的是为了方便线上部署, 在获得媲美大模型的精度的情况下,还能满足线上推理速度的时延要求。

知识蒸馏的定义

​ 知识蒸馏的模型压缩方法是在teacher-student框架中,将复杂、学习能力强的网络学到的特征表示“知识蒸馏”出来(将大模型学习出来的知识作为先验),传递给参数量小、学习能力弱的网络。从而得到一个速度快,能力强的网络。

知识蒸馏的提出

​ Hinton提出知识蒸馏基于这样一个观察:一个训练好的模型在测试时,给出的预测结果并不是one-hot形式(某一类为1,其余类全0)的,对于某一张测试图像,即使模型分类正确,在错误的类别上模型仍然会给出一些值较小但非零的概率。Hinton认为这些小而非零的值包含类与类之间的相似度关系.

​ 例如:经过训练后的原模型,其softmax分布包含有一定的知识——真实标签只能告诉我们,某个图像样本是一辆宝马,不是一辆垃圾车,也不是一颗萝卜;而经过训练的softmax可能会告诉我们,它最可能是一辆宝马,不大可能是一辆垃圾车,但绝不可能是一颗萝卜.

​ 这种类间关系是模型在训练过程中基于数据集自动学会的,能够提供比人工标注的one-hot标签更丰富的信息,用一个训好的大模型的输出来监督另一个小模型,其结果比只用人工标签更好。

为什么叫蒸馏?

在一般的softmax函数中,自然指数$e$先拉大logits之间的差距,然后作归一化,最终得到的分布是一个arg max的近似 ,其输出是一个接近one-hot的向量,其中一个值很大,其他的都很小。 这样的输出更类似one-hot这样的硬标签, 为了使得输出更软一些, 引入了"温度"这个概念, 提出了一个广义softmax函数: $$ y_i = \frac{exp(z_i/T)}{\sum_j{exp(z_j/T)}} $$ 其中$T$是温度. 当$T$ 趋向于0时, softmax输出将收敛为一个one-hot向量.

​ 在训练一个学生网络模型时,可以先让$T$升高, 使得softmax产生的分布足够软,让其softmax输出接近于教师网络;在训练结束以后再恢复低温使用正常的温度$T=1$来预测, 从而将教师模型中的知识提取出来, 其过程类似与化学中根据沸点分离不同组分的蒸馏过程, 因此将该方法称为蒸馏.

image-20210926110246740

知识蒸馏方法的归纳

通常可归纳为:学生网络学习教师网络的什么?怎样去学习?

  • 学习教师网络的输出

    学习教师网络的输出作为soft_target

  • 学习教师网络的特征或特征相关关系

    • 直接学习教师网络的输出特征:FitNet
    • 学习特征时使用的学习方法:学习注意力, 互信息, 特征相似性,有选择的选取特征。
  • others

自动机器学习AutoML)与网络架构搜索(NAS)

​ 手工设计高效的网络模型需要相关领域的专家知识,需要人工在推理速度,大小与准确率之间权衡,因此人工压缩难以得到最优的压缩策略.

AutoML

机器学习的应用需要大量的人工干预,这些人工干预表现在:特征提取、模型选择、参数调节等机器学习的各个方面。AutoML试图将这些与特征、模型、优化、评价有关的重要步骤进行自动化地学习,使得机器学习模型无需人工干预即可被应用。

AutoML的核心任务:

  • Better performance
  • No human assistance
  • Lower computation budgets

AutoML的主要问题可以由三部分构成:特征工程、模型选择、算法选择。

  • 自动特征工程. 自动地发掘并构造相关的特征,使得模型可以有最优的表现。
  • 模型选择. 自动选择出一个最合适的模型,并且能够设定好它的最优参数。
  • 算法选择. 自动地选择出一个优化算法,以便能够达到效率和精度的平衡。

ref:

Taking Human out of Learning Applications: A Survey on Automated Machine Learning

AMC: AutoML for Model Compression and Acceleration on Mobile Devices

NAS(Neural Architecture Search)

​ Neural Architecture Search (NAS) 实现神经网络可以设计神经网络,代表机器学习的未来方向。NAS是AutoML的子领域,在超参数优化和元学习等领域高度重叠。NAS根据维度可分为三类:搜索空间、搜索策略和性能评估策略.

  • 搜索空间

    搜索空间原则上定义了网络架构。

  • 搜索策略

    搜索策略定义了使用怎样的算法可以快速、准确找到最优的网络结构参数配置。

  • 性能评估策略 因为深度学习模型的效果非常依赖于训练数据的规模,通常意义上的训练集、测试集和验证集规模实现验证模型的性能会非常耗时,所以需要一些策略去做近似的评估

NAS流程

image-20210929095852283

NAS搜索空间

搜索空间,顾名思义,代表一组可供搜索的神经网络架构。

​ 搜索空间根据网络类型可以划分为链式架构空间、多分支架构空间、cell/block构建的搜索空间。根据搜索空间覆盖范围可分为 macro(整个网络架构进行搜索)和 micro(仅搜索cell,根据cell扩展搜索空间)。

1、链式架构空间。

链式架构空间的每一层输出都是下一层的输入。搜索空间包括以下参数:

(1)网络最大层数n。

(2)每一层的运算类型:池化、连接、卷积(depthwise separable convolutions,dilated convolutions、deconvolution)等类型。

(3)运算相关的超参数:滤波器的大小、个数、 strides等。

(4)激活函数: tanh,relu,identity,sigmoid等。

2、多分支架构空间

VGG19等模型已经证明直筒的链式结构容易造成梯度弥散,卷积网络无法使层数更深。ResNet和DenseNet等引入的跳跃连接和密集连接,使得更深的网络成为可能。目前很多论文的实验数据也证实多分支架构空间可以实现更高精度(代价是搜索空间呈指数级别增加)。

image-20210929103637616

3、基于基本的cell/block构建的搜索空间。

​ 很多的神经网络结构虽然很深,但会有基本的 cell/block,将 cell/ block 通过改变堆叠结构,一方面可以减少优化变量数目,另一方面相同的 cell/ block 在不同任务之间进行迁移。BlockQNN[2]结合Inception blocks和residue blocks,设计block模块,通过堆叠block设计搜索空间。 Zoph et al[3]设计两类 cells:normal cell 和reduction cell (normal cell不改变输入feature map的大小的卷积, 而reduction cell将输入feature map的长宽各减少为原来的一半的卷积,是通过增加stride的大小来降低size),通过构建重复模块(cells)的深度堆叠结构。这个堆叠结构是固定的,但其中各个模块的结构可以改变。

Cell作为基本单元,也可以固定不变。PNAS[9]学习的是单一一种cell类型,而没有区分 Normal cell和 Reduction cell.

image-20210929103617734

NAS搜索策略

​ 搜索算法通常是一个迭代过程,定义了使用怎样的算法可以快速、准确找到最优的网络结构参数配置。常见的搜索方法包括:随机搜索、贝叶斯优化、进化算法、强化学习、基于梯度的算法。

​ 在搜索过程的每个步骤或迭代中,从搜索空间产生“样本”形成一个神经网络,称为“子网络”。所有子网络都在训练数据集上进行训练,然后将它们在验证数据集上的准确性视为目标(或作为强化学习中的奖励) 进行优化。搜索算法的目标是找到优化目标的最佳子网络,例如最小化验证损失或最大化奖励。

​ 随机搜索简单但相对低效,通常用作baseline。其中基于强化学习进化算法的本质:离散空间中搜索,将目标函数看做黑盒。

基于强化学习的搜索策略

​ 基于强化学习(reinforcement learning ,RL)的方法已经成为NAS的主流方法[4]。RL有四个基元:agent, action,environment和reward. 强化学习是通过奖励或惩罚(reward)来学习怎样选择能产生最大积累奖励的行动(action)的算法。

​ NAS的核心思想是通过一个controller RNN在搜索空间(search space)中得到一个子网络结构(child network),然后用这个子网络结构在数据集上训练,在验证集上测试得到准确率,再将这个准确率回传给controller,controller继续优化得到另一个网络结构,如此反复进行直到得到最佳的结果,整个过程称为Neural Architecture Search。

​ 基于NAS的RL算法主要区别在于(a)如何定义行动空间(在新的空间选择配置还是在修订已经存在的网络) (b)如何更新行动策略。Zoph et al首先使用梯度策略更新策略[4],并在其后的工作中使用proximal policy optimization。 Baker et al.使用Q-learning更新行动策略。

​ 在探索高维搜索空间时,基于RL的搜索成本非常高。NAS[4]在使用800块 GPU情况下耗时28天。其后续工作[3]使用450块GPU耗时4天生成简单的搜索空间。

基于进化算法的搜索策略

​ 进化学习(Evolutionary algorithms ,EA)为了达到自动寻找高性能的神经网络结构,需要进化一个模型簇(population)。每一个模型,也就是个体(individual),都是一个训练过的结构。模型在单个校验数据集(validation dataset)上的准确度就是度量个体质量或适应性的指标。

​ 在一个进化过程中[7],工作者(worker)随机从模型簇中选出两个个体模型;根据优胜劣汰对模型进行识别,不合适的模型会立刻从模型簇中被剔除,即代表该模型在此次进化中的消亡;而更优的模型则成为母体(parent model),进行繁殖;通过这一过程,工作者实际上是创造了一个母体的副本,并让该副本随机发生变异。研究人员把这一修改过的副本称为子代(child);子代创造出来后,经过训练并在校验集上对它进行评估之后,把子代放回到模型簇中。此时,该子代则成为母体继续进行上述几个步骤的进化。

​ 简言之,该进化算法就是在随机选出的个体中择其优,因此该方法也属于联赛选择算法(tournament selection)的一种。

​ 另外,如无其他说明,模型簇一般能容纳1000个个体,工作者的数量一般是个体数量的1/4,而消亡个体的目录会被删除,以保证整个算法能长时间在有限空间中运行。

​ 进化学习的一个缺点是进化过程通常不稳定,最终的模型簇质量取决于随机变异。Chen et al[8]提出通过RL 控制器确定变异替代随机变异,稳定搜索过程。

​ Chenxi Liu et al.[9] 使用了基于序列模型的优化(SMBO)策略,按复杂度逐渐增大顺序搜索架构,同时学习一个用于引导该搜索的代理函数(surrogate function),类似于 A* 搜索。

基于梯度的搜索策略

​ 前面的方法网络空间是离散的,它们都将NAS处理为黑盒优化问题,因而效率不尽人意。如果能将网络空间表示为连续分布,就能通过基于梯度的方法进行优化。CMU和Google的学者在DARTS: Differentiable Architecture Search一文中提出可微分结构搜索方法。该方法与ENAS相同,将网络空间表示为一个有向无环图,其关键是将节点连接和激活函数通过一种巧妙的表示组合成了一个矩阵,其中每个元素代表了连接和激活函数的权重,在搜索时使用了Softmax函数,这样就将搜索空间变成了连续空间,目标函数成为了可微函数。在搜索时,DARTS会遍历全部节点,使用节点上全部连接的加权进行计算,同时优化结构权重和网络权重。搜索结束后,选择权重最大的连接和激活函数,形成最终的网络.

性能评估策略

​ 性能评估策略是实现搜索加速的过程。基于强化学习、进化学习等搜索策略,为了引导搜索空间,每个子网络都需要训练和评估。但是训练每个子网络需要巨大的资源消耗(比如NAS[4]需要2000GPU*天)。NAS通常加速方法是经过训练后在查找近似度量方式(例如减少训练epochs,简化评估数据集[3][4]、使用低分辨率图像、每一卷积层使用更少的滤波器)。本章节介绍更两种更优类型: (a) 代理度量improved proxy (b) 权值共享weight-sharing。

1、使用代理度量时,子网络之间的相对排名需要保持与最终模型准确率相关。Zhong et al.[10]提出FLOPS、子模型的model size与最终模型准确率负相关,介绍一种应用于奖励计算的修正函数,子网络的准确性可以通过提前训练停止获得,弥合代理度量和真实准确率的差距。有些算法提出通过预测神经网络模型的准确率、学习曲线、验证曲线等来改进代理度量的方法,预测准确率低/学习曲线差的子网络暂停训练或直接放弃。

2、权值共享。

子网络直接继承已经训练好的模型权重参数,可以显著降低模型的运算量[7]。One-Shot架构搜索[11]将所有架构视作一个 one-shot 模型(超图)的子图,子图之间通过超图的边来共享权重。一些论文直接在模型基础上添加卷积层或插入跳跃连接,参数权重可以直接复用,减少模型的运算量。

Nas缺点

  • 无法自行设计网络架构,仅仅是将人工设计的blocks进行堆叠,需要更广泛的搜索空间
  • 只专注于优化模型的准确率,还需要考虑功耗、推断延时、计算复杂度、内存占用、FLOPs等指标,解决移动端实际应用问题。
  • 目前只在分类任务领域发展,需要在其他领域的应用有更好的表现

Ref:

https://zhuanlan.zhihu.com/p/379315189

NasNet

​ 作者提出先在小数据集上搜索架构构建块,然后将该块转移到更大的数据集.首先在CIFAR-10这种小数据集上进行神经网络架构搜索,以便 AutoML 找到最佳卷积层并灵活进行多次堆叠来创建最终网络,并将学到的最好架构迁移到ImageNet图像分类和 COCO 对象检测中。

image-20210927105609525

​ 在 NASNet 中,虽然整体架构如上所示预定义,但其中的块或单元不是由作者预定义的。

​ NASNet学习的是完整网络中被堆叠、被重复使用的网络单元。为了便于将网络迁移到不同的数据集上,我们需要学习两种类型的网络块:Normal cell 和Reduction cell 。

  • Normal cell不改变输入feature map的大小的卷积
  • reduction cell将输入feature map的长宽各减少为原来的一半的卷积,是通过增加stride的大小来降低size。通过NasNet构建堆叠模块(cells)的深度实现架构的设计。

NasNet中控制器结构如下. 控制器RNN仅搜索Normal cell 和Reduction cell 的(或内部)结构。

image-20210927103338080

给定两个初始隐藏状态,控制器 RNN 递归地预测卷积单元的其余结构。精确的讲,NASNet网络单元的计算分为5步:

  1. 从第 $h_{i-1}$ 个Feature Map或者第 $h_i$个Feature Map或者之前已经生成的网络块中选择一个Feature Map作为输入的hidden layer A;
  2. 采用和1类似的方法选择一个Hidden Layer B作为输入;
  3. 为1的Feature Map选择一个运算;
  4. 为2的Feature Map选择一个元素;
  5. 选择一个合并3,4得到的Feature Map的运算。

其中3,4 可选操作有:

image-20210927103444670

在5中可以选择的合并操作有(1)单位加;(2)拼接。

NasNet 搜索空间示意图:

image-20210927110923216

​ 网络模型递归构建块,每个块由控制器选择一对隐藏状态(深灰色)、对这些隐藏状态执行的操作(黄色)和组合操作(绿色)组成。 生成的隐藏状态保留在潜在隐藏状态集合中,以便在后续块上选择。NASNet 通过控制器 RNN而不是手工操作, 从一组操作中找到最佳组合,以形成具有最佳性能的单元.整个搜索过程超过 4 天的结果产生了几个候选cell,使用 500 个 GPU 耗费了 2000 个 GPU 小时.其中搜索到的NASNET_A结构如下:

image-20210927111145223

与同类架构相比,NASNet 以更少的浮点运算和参数实现了最先进的性能。 使用 CIFAR-10 发现的卷积单元可以很好地泛化到 ImageNet 问题。NasNet虽然实现准确率state-of-art水平,但是推断延时较大,在移动端对实时性苛刻场景难以大规模运用.

MnasNet

论文提出了移动端的神经网络架构搜索方法,该方法主要有两个思路,首先使用多目标优化方法将模型在实际设备上的耗时融入搜索中,然后使用分解的层次搜索空间让网络保持层多样性的同时,搜索空间依然很简洁,MnasNet能够在准确率和耗时中有更好的trade off

使用强化学习设计移动端模型的自动化神经架构搜索方法,并且实现准确率和运算速率突破。

使用强化学习的思路,首先确定了 block 的连接方式,在每个 block 使用层级搜索空间,确定每个卷积层的卷积类型,卷积核、跳跃层连接方式,滤波器的尺寸等。其基本策略还是延续人工设计神经网络思路。

提出的层级搜索空间允许模型的各个 block 包括不同的卷积层。

img

MnasNet的搜索空间与NasNet类似,但是搜索目标函数同时考虑准确率和速率。

FBNetV1,V2,V3

facebook在nas领域的轻量级网络探索

(CVPR 2019)FBNet: Hardware-Aware Efficient ConvNet Design via Differentiable Neural Architecture Search

论文:https://arxiv.org/abs/1812.03443

代码:https://github.com/facebookresearch/mobile-vision

(CVPR 2020)FBNetV2: Differentiable Neural Architecture Search for Spatial and Channel Dimensions**

论文:https://arxiv.org/abs/2004.05565

代码:https://github.com/facebookresearch/mobile-vision

FBNetV3: Joint Architecture-Recipe Search using Neural Acquisition Function

论文:https://arxiv.org/abs/2006.02049

EfficientNet

(ICML2019 quoc le)论文:EfficientNet: Rethinking Model Scaling for Convolutional Neural Networks

代码:https://github.com/qubvel/effic

EfficientDet

(ICML2019 quoc le)论文:EfficientDet: Scalable and Efficient Object Detection

代码:xuannianz/EfficientDet

RegNet

(CVPR2020 fair)论文:Designing Network Design Spaces

RegNet不仅网络设计范式与当前主流“背道而驰”:简单、易理解的模型,也可以hold住高计算量。在类似的条件下,性能还要优于EfficientNet,在GPU上的速度还提高了5倍。

ref:

2017:A Survey of Model Compression and Acceleration for Deep Neural Networks

2018:Recent Advances in Efficient Computation of Deep Convolutional Neural Networks

Distiller :用于神经网络压缩研究的开源python包

Clone this wiki locally