模型剪枝算法综述笔记

今天把最近看的一批模型剪枝相关论文整理了一下,方法大体可以分为三类:预定义结构剪枝、自动结构剪枝和非结构化剪枝。

先提一篇引发思考的文章:它做了大量对比实验,结论是——如果剪枝后的网络结构是预先定义好的,那么直接从头(scratch)训练这个瘦网络就能得到比较好的结果,没有必要再走那套繁琐的”预训练 → 剪枝 → fine-tune”流程。实验覆盖了 Predefined Structured Pruning、Automatic Structured Pruning、Unstructured Magnitude-based Pruning 三个方向。

预定义结构化剪枝

这类方法的共同点是:在执行剪枝之前,先由人工或通过敏感性分析确定每一层要删掉多少比例的 filter/channel,算法只负责在给定比例内找”最不重要”的那些。

L1 剪枝

论文Pruning Filters for Efficient ConvNets

最直接的做法:把 L1 范数最小的卷积核直接去掉,相当于砍掉下一层的 channel 数。每层的剪枝比例是固定的,依赖事先做好的敏感性分析——逐层单独剪枝,在验证集上测精度;再对剪后的单层重新训练,再测精度,由此确定每层对剪枝的容忍度。如果没有预训练模型,这套流程意义不大,还不如重新训练。

ThiNet

论文ThiNet: A Filter Level Pruning Method for Deep Neural Network Compression

目标是:剪掉第 L 层的若干 filter 后,尽量保持第 L+2 层的输入(即第 L+1 层的输出)不变。删掉 L 层的 filter 后,L+1 层对应的输入 channel 数和 filter channel 数也随之减小。

做法是用贪心算法在第 L+1 层的输出里找对整体影响最小的 channel——按 feature map 维度和 batch 维度上绝对值之和排序,逐步去掉影响最小的那个。需要优化的式子如下(m 是分辨率 × channel 数 × batch 大小):

使用的贪心算法如下:

LASSO 回归剪枝

论文Channel Pruning for Accelerating Very Deep Neural Networks

出发点和 ThiNet 类似,同样是希望剪掉某些 channel 后让下游层响应尽量不变,但用 LASSO 回归的稀疏正则项替代了贪心搜索。对每个 channel 引入加权系数 β,目标是让 β 尽可能稀疏,同时保持重建误差最小。N 是采样的卷积输入块数量,Y 是 N×n 的特征矩阵:

求解采用交替优化,分两步:

Step 1:固定 w,优化 β,直接当作 LASSO 回归问题求解:

Step 2:固定 β,优化 w:

与 ThiNet 的主要区别就在求解算法上,这里是交替优化而不是贪心枚举。

自动结构化剪枝

这类方法不需要人工指定每层的剪枝比例,训练过程本身会决定哪些 channel 该去掉,某种程度上可以看作轻量级的 NAS。

Network Slimming

论文Learning Efficient Convolutional Networks through Network Slimming

在 BN 层的缩放参数(γ)上加 L1 正则化。由于 BN 层的 weight 是在 channel 维度上独立作用的,某个 channel 对应的 γ 趋近于零就意味着这个 channel 的输出几乎被压制,可以直接剪掉。

与 L1 filter pruning 的关键区别:Network Slimming 的阈值是对所有 BN 层的 γ 做全局排序后得出的,而 L1 剪枝是在每层内部做相对排序。前者不需要人工指定每层的压缩比,结构自动涌现。L1 不可导,实现时直接对梯度做操作(次梯度),用普通 SGD 即可收敛。

Sparse Structure Selection

论文Data-Driven Sparse Structure Selection for Deep Neural Networks

思路与 Network Slimming 类似,通过数据驱动的稀疏正则化让网络自动选择结构。

其他值得关注的方法

AOFP(ICML 2019)

论文Approximated Oracle Filter Pruning for Destructive CNN Width Optimization

用二分搜索来定位最不重要的 channel,通过多次随机采样估计每个 channel 对下一层输出的影响,然后剪掉影响较小的 channel。用采样来近似估计影响量,避免枚举所有组合,这个思路挺值得借鉴的。

NISP

论文NISP: Pruning Networks Using Neuron Importance Score Propagation

同样是预定义每层剪枝比例,再按某种重要性分数进行剪枝,属于预定义类方法的变体。

SNIP

论文SNIP: Single-Shot Network Pruning Based on Connection Sensitivity

非结构化剪枝,直接剪掉 loss 对 mask 梯度最小的连接——即对 loss 最不敏感的 weight。其中 s 是敏感度,用近似微分来得到:

这样只需一次 backward 就能算出所有 weight 的敏感度,不需要多次 forward:

Autopruner

论文Autopruner: An End-to-End Trainable Filter Pruning Method for Efficient Deep Model Inference

不用简单的惩罚项来驱动稀疏,而是用额外的网络结构来预测每个 filter 的 mask。对 sigmoid 做了改造,逐渐增大 α 使激活值越来越接近 0/1 编码,相当于用神经网络激活值直接充当 mask,这样可以端到端用反向传播找到最佳编码。缺点是压缩率不易控制,还需要额外措施。

激活函数形式如下:

压缩率的控制通过在 loss 中加正则项实现,v 是编码向量,C 是向量长度,r 是目标保留比例:

其他备忘

  • ISTA-basedRethinking the Smaller-Norm-Less-Informative Assumption in Channel Pruning of Convolution Layers):暂跳过,看着很费劲,之后再补。
  • C-SGDCentripetal SGD for Pruning Very Deep Convolutional Networks with Complicated Structure):针对 ResNet 这类有复杂跳接结构的网络设计。
  • AMCAMC: AutoML for Model Compression and Acceleration on Mobile Devices):用 DDPG 搜索每层的压缩比超参,把确定”剪多少”这件事也交给强化学习来解决。
  • SFPSoft Filter Pruning for Accelerating Deep Convolutional Neural Networks)、CFPGDPSSR-L2DCP 等:记下来,后续有时间细读。
  • Influence FunctionsUnderstanding Black-Box Predictions via Influence Functions):好像也是利用求导找敏感度,和 SNIP 的思路有相通之处。

小结

结构化剪枝(无论预定义还是自动)在硬件加速上更友好,能直接缩小网络规模;非结构化剪枝虽然理论压缩比更高,但稀疏矩阵在常规 GPU 上难以真正加速,实用价值有限。自动结构剪枝和 NAS 越来越接近,Network Slimming 用稀疏正则、AMC 用强化学习,分别代表两种搜索结构的路线,是目前看来比较有意思的方向。

另外,今天还看了 MixMatch 的论文,把 CSAPP 第三章看完了,收获不少。