Model Compression and Acceleration for Deep Neural Networks

Kaka Chen 2021-12-23

Abstract

随着Deep NN的广泛运用,我们发现如果每次都使用体量巨大的NN模型,会对计算资源要求非常高,因此一些关于模型压缩和加速的手段被提出来,尤其是在将模型应用到移动端的尝试,让模型应用有了如下一些优势:

  • 减轻服务器端计算压力,利用云端一体化实现负载均衡;
  • 实时性好,响应速度快;
  • 稳定性高,可靠性好;
  • 安全性高,用户隐私保护好。

其中模型的压缩和加速是两个不同的方面,它们之间有可能互相有正向影响,也有可能并无相关性,其中压缩的重点在于减少网络参数量,而加速则关注降低计算复杂性,提升并行计算能力等。总体可分为三个层次:

  • 算法层压缩加速:结构优化(矩阵分解、分组卷积、小卷积核等)、量化与定点化、模型剪枝、模型蒸馏;
  • 框架层加速:编译优化、缓存优化、稀疏存储和计算、NEON指令应用、算子优化等;
  • 硬件层加速:AI硬件芯片层加速,如GPU、FPGA、ASIC等多种方案。

简单总结一下常被提及的四种方法:

Theme Name Description Application More Details Drawback
参数剪枝和共享(Parameter Pruning and Sharing) 减少对性能不敏感的冗余参数 卷积层和全连接层 对不同设置有鲁棒性,能够实现好的性能,能支持脚本(Scratch)和预训练模型的训练 1)量化和二进制:二进制网络的精度损失比较大;2)剪枝和共享:更难以收敛,要微调参数,不够灵活;3)设计结构矩阵:结构矩阵会伤害到模型性能,且结构矩阵不好找。
低秩分解(Low-rank factorization) 使用矩阵/张量分解去估计有信息量的参数 卷积层和全连接层 标准的管道(pipeline),容易执行,能够支持脚本和预训练模型。 1)分解的操作不易执行,其计算消耗是昂贵的;2)当前的算法时逐层进行的,因此不能全局压缩;3)分解后,模型的收敛难度增加。
转移/紧致卷积滤波器(Transferred/compact convolutional filters) 设计特殊结构的卷积滤波器去保存参数 卷积层 算法依赖于应用,通常实现好的性能,只支持脚本中训练 1)只支持宽的神经网络而不支持深度的神经网络;2)转移的假设性太强导致某情况的结构不太稳定。
知识蒸馏(Knowledge distillation) 通过大模型中蒸馏知识训练一个紧致的神经网络 卷积层和全连接层 模型的性能对应用是敏感的并且网络结构只支持从脚本中训练 1)目前知识蒸馏只支持softmax损失的分类模型;2)与其他方法相比,模型假设太严格了。

Parameter Pruning and Sharing

Quantization and Binarization

网络量化压缩原始网络通过减少用来表示权值的bits数。极限情况下是1-bits表示权重,这就是二进制权值神经网络。换言之就是通过降低数值存储精度,换取模型尺寸上的缩小。或者是利用weight clustering的方法将weights中原本相似的值用同一个新的值来表示,目标就是能得到binary weight的状态,如下:

缺点:二进制网络的精确率是显著的降低的,如果处理大型的CNNs比如GoogleNet。另一个二进制网络缺点是存在的二进制方案是基于简单的矩阵估计并忽略了二进制在精度损失的效果。

Pruning and Sharing

网络剪枝的整体思想是去掉一些网络中不重要的权重或者神经结构。其中评估其重要性的依据,可以是计算该权重是否趋于0,或者该神经结构的输出是否主要是0。而在去除一些低重要性的权重或者神经结构之后,往往可以获得一个较为轻量级的网络结构,但是会损失一些性能。之后可以通过在得到的轻量级网络上不断fine-tuning来逐步提高其性能,常用的做法是iteratively remove,即每次只是处理一小部分结构。那为何不一开始就用一个轻量级的网络来训练呢,主要的考虑还是在于一开始的轻量级网络难以训练和优化。

网络剪枝和共享已经被用于减少网络复杂性和处理过拟合任务。一个早些的剪枝方法是基于权值的。最优脑损害(The Optimal Brain Damage)和最优脑外科医生(the Optimal Brain Surgeon)方法减少了基于损失函数Hessian阵的连接层的参数,这些工作说明这样的剪枝得到了较高的精确率比那些基于权值剪枝方法的机制。

这个方向的最近趋势是剪枝冗余性,即预训练CNN模型中非信息的权值。

训练紧致的带有稀疏约束的CNNs同样也是一个增长的兴趣点。这些稀疏性约束时典型的引入了最优化问题如$l_0$或者$l_1$范数正则化。

缺点: 剪枝和共享有一些潜在的问题。首先,带有$l_0$或者$l_1$正则化的剪枝更多的迭代以达到收敛(难以收敛)。另外,所有的剪枝的关键点时要求对层的敏感性的手动启动,这要求微调好参数因此在一些应用上可能变得更加笨重。

Designing Structural Matrix

在包含全连接层的结构中,探索全连接层中的参数冗余性时很重要的,这总是内存消耗的瓶颈。全连接网络层一般是$f(x, M)=\sigma(Mx)$,这里的$\sigma(\cdot)$是一个元素式的非线性操作,$x$是输入向量,和$M$是$m \times n$的参数矩阵。其中$M$通常是大的稠密矩阵,计算矩阵向量乘法的时间复杂度是$O(mn)$。因此,一个直觉上的剪枝方法是利用$M$作为一个参数化的结构矩阵。一个$m \times n$矩阵可以描述成一个使用少于$mn$参数的矩阵去呼叫一个结构矩阵。典型上,结构不应该只减少内存消耗,也急剧的大叔了推理和训练阶段,如果通过快速矩阵向量乘法和梯度计算。

在这个方向上,有一些研究提出了简单而有效的基于循环投影的方法,同时维持的可竞争的错误率。给定一个向量$r=(r_0, r_1,…,r_{d-1})$,一个循环矩阵$R \in R^{d \times d}$定义如下:

\[R=circ(r) := \begin{bmatrix} r_0 & r_{d-1} & \cdots & r_2 & r_1 \\ r_1 & r_0 & r_{d-1} & & r_2 \\ \vdots & r_2 & r_0 & \ddots & \vdots \\ r_{d-2} & & \ddots & \ddots & r_{d-1} \\ r_{d-1} & r_{d-2} & \cdots & r_1 & r_0 \\ \end{bmatrix}\]

这样,内存消耗就会从$O(d^2)$变成$O(d)$. 而且训练矩阵也能够使用快速傅里叶变换加速矩阵计算。给定一个$d$维的向量$r$,则$Rr$乘法的时间复杂度维$O(d log(d))$

缺点:这个方法的一个问题是结构约束将会损害性能,由于约束会带给模型偏移。另一方面,找一个合适的结构矩阵是困难的,目前也没有理论告诉我们怎么做。

Low-Rank Factorization and Sparsity

卷积操作占据了深度CNNs模型中的最大计算篇幅,因此减少卷积层能够提升压缩率同时也能加快运算速度。对于卷积核,它可以被认为一个4D张量。基于张量分解的想法驱使我们本能的认为4D张量的冗余性去除会有一个显著提升,这是一个特殊的方式去移除冗余性。注意到全连接层,它能够被视为一个2D矩阵并且低秩也能有所帮助。

很长时间以来,人们使用低秩滤波器去加速卷积,例如,高维DCT(discrete cosine transform, 离散余弦变换)和小波系统(wavelet systems)各自使用张量积去构造从1D DCT和1D的小波。

低秩估计是逐层而做的。一层的参数在低质估计后固定下来,而上面的层是微调基于一个重构误差准则。这些是典型的用于压缩2D卷积滤波器的低秩估计方法。根据这个方向,Canonical Polyadic(CP)分解是一个用于核张量的方法。人们使用非线性的最小二乘去计算CP分解。然而,找到最好的低秩估计在CP分解中式一个病态问题,并且最好的$rank-K$($K$是秩的值)估计可能是不存在的。

正如前面所提,全连接层可以看成是2D矩阵,因此上述的方法(指低秩估计的方法)也能够应用到这儿(指全连接层的分解)。也有工作应用截断奇异值分解去分解全连接层用于设计紧凑的多任务深度学习框架。

缺点:低秩方法在估计矩阵压缩和加速上是简单直接的。这个想法最近补充深度学习的优点,比如dropout, rectified units 和 maxout. 然而, 由于它涉及到分解操作,执行起来并不容易。分解是计算代价昂贵的。 另一个问题是当前的低秩估计方法是逐层的,因此不能执行全局的参数压缩, 而这对于不同的层保持不同的信息时重要的。最后,比较原始模型, 分解需要额外的再训练去实现收敛。

Transfered/Compact Convolutional Filters

CNNs 是参数有效的对于转换的不变性,对于输入图片表示的不变性,而这对于训练深度模型而不导致过拟合是重要的。尽管目前还缺失强理论证明,但是大量的经验事实支持转换的不变性和卷积权值共享对于好的预测性能是重要的。 使用转移卷积滤波器去压缩CNN模型的想法受到研究工作启发,它引入了等价理论。让$x$是一个输入,$\Phi (\cdot)$是一个网络层和$\tau(\cdot)$是一个转换矩阵。等价性的概念如下所定义:

\[\tau^{'} \Phi(x) = \Phi(\tau x)\]

表明转换了$\tau(\cdot)$的输入$x$然后传递它到层次$\Phi(\cdot)$的网络(即得到$\tau x$后再用网络作用)应该有同样的结果在第一次用网络映射$x$然后再转换表示(即先得到$\Phi(x)$,再用$\tau$作用)。注意:$\tau(\cdot)$和$\tau^{‘}(\cdot)$不是必须相同的。根据这个理论,应用转换到层或者滤波器$\Phi(\cdot)$去压缩整个网络模型是合理的。从经验观察,深度CNNs同样受益于使用大的卷积滤波器通过应用确定的转换$\tau(\cdot)$到一个小的基础偏置滤波器的集合,由于它扮演了一个模型的正则化。

在这个方向,有许多最近的研究工作去建立一个由基础滤波集合构建的卷积层。(就是从不同的角度定义函数$\tau(\cdot)$

缺点:应用转换约束到卷积的滤波器有一点问题。首先,这些方法能够对于宽度(扁平)的框架(比如VGGNet)能够实现竞争性的性能,但是对于深度的瘦的网络(比如GoogleNet,Residual Net)就不行了。第二,转移假设的条件有时太强了去指导学习,这使得结构对于某些情形是不稳定的。

使用一个紧致的卷积滤波器能够直接减少计算损失。这个关键的想法是去替代松弛和过参数滤波器维紧凑的块进行加速,这能够显著的加速CNNs在一些基准上。

Knowledge Distillation

就我们所知道的,第一次探索使用知识转移的方法压缩模型的工作是由Caruana等人提出的。他们训练一个压缩/完整的带有伪数据标签的强分类器的模型,并复现了原始大网络的效果。但是这项工作被限制到了浅层模型。这个想法最近吸收为知识蒸馏(Knowledge Distillation)压缩深和宽的网络到浅的网络。知识蒸馏的基本思想是去转移大的教师模型的知识到一个小的学生模型通过学习由softmax带来的类分布。简单来说,就是先训练一个巨大的网络模型,再用一个较小的网络模型去学习它。

学习的主要内容集中在大模型的输出label和对应的conf上,针对softmax有一个temperature softmax:

\[y_i^{'}=\frac{exp(y_i)}{\Sigma_j exp(y_j)}\to y_i^{'}=\frac{exp(y_i/T)}{\Sigma_j exp(y_j/T)}\]

缺点:基于知识蒸馏的方法能够使更深的模型瘦身,并且显著的减少计算损失。然而,知识蒸馏只能应用到带有softmax损失的分类任务,这限制了其应用,另一个缺点使模型假设有时过于严格,相比较其他竞争性的方法。