深度学习模型加速与压缩常用方法(三)剪枝

一、网络剪枝与稀疏约束

网络剪枝大体上可以分为两个分支:

  • unstructured pruning(非结构化剪枝)
  • structured pruning(结构化剪枝)

unstructured pruning是指对于individual weights进行prune;structured pruning是指对于filter/channel/layer的prune。其中非结构化修剪方法(直接修剪权重)的一个缺点是所得到的权重矩阵是稀疏的,如果没有专用硬件/库,则不能达到压缩和加速的效果。相反,结构化修剪方法在通道或层的层次上进行修剪。由于原始卷积结构仍然保留,因此不需要专用的硬件/库来实现。在结构化修剪方法中,通道修剪是最受欢迎的,因为它在最细粒度的水平上运行,同时仍然适合传统的深度学习框架。

二、典型的修剪算法是三阶段流程

  1. 训练:训练大型的过度参数化的模型,得到最佳网络性能,以此为基准;
  2. 修剪:根据特定标准修剪训练的大模型,即重新调整网络结构中的通道或层数等,来得到一个精简的网络结构;
  3. 微调:微调修剪的模型以重新获得丢失的性能,这里一般做法是将修剪后的大网络中的保留的(视为重要的)参数用来初始化修剪后的网络,即继承大网络学习到的重要参数,再在训练集上finetune几轮。

然而,在《Rethinking the value of network pruning》(ICLR 2019)这篇论文里,作者做出了几个与常见观点相矛盾的结论,通过测试目前六种最先进的剪枝算法得出以下结论:

  1. 训练过度参数化的模型不是获得有效的最终模型所必需的;
  2. 学习的大型模型的“重要”权重不一定有助于修剪后的小型模型;
  3. 修剪的本质是网络体系结构本身,而不是一组继承的“重要”权重,来主导最终模型的效率优势,这表明一些修剪算法可以被视为表征网络架构探索。

作者选择了三个数据集和三个标准的网络结构(数据集:CIFAR-10, CIFAR-100,ImageNet,网络结构:VGG, ResNet,DenseNet),并验证了6个网络裁剪方法,接下来分别介绍这几种当下流行的剪枝算法:

  • L1-norm based Channel Pruning (Li et al., 2017)
  • ThiNet (Luo et al., 2017)
  • Regression based Feature Reconstruction (He et al., 2017b)
  • Network Slimming (Liu et al., 2017)
  • Sparse Structure Selection (Huang & Wang, 2018)
  • Non-structured Weight Pruning (Han et al., 2015)

(一)L1-norm based Channel Pruning

本方法出自论文《Pruning Filters For Efficient ConvNets》,论文提出了对卷积层(对Filters进行剪枝,以及Feature maps)进行剪枝操作,移除对于CNN精度影响很小的卷积核,然后进行retrain,不会造成稀疏连接(稀疏矩阵操作需要特殊的库等来处理)。

卷积核剪枝原则:(即应该去掉哪些卷积核)

  1. 对每个卷积核 Fi,j ,计算它的权重绝对值(L1正则)之和 Sj=\sum_{l=1}^{ni}\sum_{}^{}{\left| Kl \right|} ;
  2. 根据 Sj 排序;
  3. 将m个权重绝对值之和最小的卷积核以及对应的feature maps剪掉。下一个卷积层中与剪掉的feature maps相关的核也要移除;
  4. 一个对于第i层和第i+1层的新的权重矩阵被创建,并且剩下的权重参数被复制到新模型中;

相比于基于其他的标准来衡量卷积核的重要性(比如基于激活值的feature map剪枝),l1-norm是一个很好的选择卷积核的方法,认为如果一个filter的绝对值和比较小,说明该filter并不重要。之后的步骤就是retrain,论文指出对剪枝后的网络结构从头训练要比对重新训练剪枝后的网络(利用了未剪枝之前的权重)的结果差。

(二)ThiNet

本方法出自论文《ThiNet: A Filter Level Pruning Method for Deep Neural Network Compression》,主要贡献:1)基于贪心策略与最小化重建误差,设计了ThiNet剪枝方法,并且是规整的通道剪枝方法;2)将网络剪枝视作优化问题,并利用下一层的输入输出关系获取统计信息,以决定当前层的剪枝;3)在ImageNet数据集上,获得了良好的剪枝效果(主要是Resnet50与VGG-16),并在其他任务上取得了良好的迁移效果。

ThiNet的剪枝步骤如上图所示,对于给定的预训练模型以及固定的剪枝率,逐层裁剪冗余的滤波器(3D filters或2D kernels),总体包括通道选择、通道剪枝与fine-tuning三个阶段:

  1. Channel Selection:利用第i+1 层的统计信息指导第i 层的剪枝,即从第i+1 层的输入特征中提取最优子集,用于估计第i+1的输出特征,而其余输入特征以及相对应的3D filters均可被删除;
  2. Pruning:根据第一步通道选择的结果,剪除第i 层对应的3D filters以及第i+1 层的2D kernels,从而获得结构紧凑、纤瘦的模型(Thin-Net);
  3. Fine-tuning:完成第i 层的剪枝之后,在训练集上微调1~2个epochs,以恢复因剪枝丢失的精度。在完成整个模型的剪枝之后,通常需要微调更多的epochs;
  4. 回到第一步,完成第i+1 层的剪枝;

通道选择原则:

寻找通道最优子集用于估计输出特征的Channel Selection,可表示为如下优化问题:

等价而言,定义T 为需要移除的通道子集,其满足 S\cup T=\left\{ 1,2,...,C \right\} and S\cap T=\oslash ,则最优化问题可重新写成:

上式亦可理解为,所构建的集合T , 其所包含元素的L2 norm最小。由于集合T 通常比集合S 小,因此求解上述等价问题,具有更高的实现效率。下图是采用贪心策略(Greedy Method)求解集合T 的描述,每次迭代往T 中所添加的元素,需要确保目标函数最小。从而确保完成样本集遍历、并达成目标剪枝率之后,能够删除最不重要的输入特征,最终完成Channel Selection。

以上为应用贪心策略选取需要删除的通道集合。

(三)Regression based Feature Reconstruction

本方法出自论文《Channel Pruning for Accelerating Very Deep Neural Networks》,本文采用了通道剪枝方法,同上一种方法思路一致,考虑减少输入feature maps中的若干channels信息,然后通过调整weights使整体output feature map的信息不会丢失太多。

如图所示,目标就是减少B 的feature map, 那么B中的channel被剪掉,会同时使得上游对应的卷积核个数减少,以及下游对应卷积核的通道数减少。关键在于通道选择,如何选择通道而不影响信息的传递很重要。为了进行channel selection ,作者引入了β作为mask ,目标变为 :

β是一个列向量,如果βi=0 则代表对应的通道被剪除,c ‘代表经过选择后的通道个数 c’<=c,因此作者分两步来优化,首先固定W,优化β ;然后固定β,优化W。而且为了增加β的稀疏度,将β的L1正则项加入优化函数;另外则增加了W的范数为1的强约束以让我们得到的W解不过于简单,原优化函数变为:

进而我们再将它变为两个分步骤的子优化问题:

(1).求参数β的子优化问题

首先,我们可固定W不变,寻求参数β的组合,即决定输入feature map的哪些input channels可以舍弃。这显然是个NP-hard的组合优化问题,作者使用了经典的启发式LASSO方式来迭代寻找最优的β值,如下公式所示:

(2).求参数W的子优化问题

然后我们再固定上面得到的β不变,再求解最优的W参数值,本质上就是求解如下的MSE问题:

以上所介绍的方法为单个conv层pruning所使用的方法。而在将此方法应用于整个CNN model时,方法也类似,只需要sequentially将此它应用于每个层即可(当然某些特殊的多分支层需要稍稍特殊对待)。

编辑于 2020-07-07 17:31