一:背景介绍

众所周知的是,神经网络有个很大特点就是参数太多了,计算量太大了,可能是几百兆的规模,这么大的存储量和计算量在小型设备上是运行不起来的,我们 必须要做对网络进行精简。
精简后有很多好处,比如
1)最直接的好处就是计算量和存储量的减小,从而使计算时间更少,功耗更小。
2)Memory footprint变小,可以放到更低端的设备上跑。。ss
3)Size更小的包有利于应用发布和更新。

所以这一些都是非常工程化的方法了。

一般大方向上来说,方法有如下:
Outline:
网络剪裁(Network pruning)
知识蒸馏(Knowle Distillation)
参数量化(Parameter Quantization)
架构设计(Architecture Design)
动态调整计算。
深度压缩等方法。

学习自李宏毅的课程。我们今天主要简单学习下Network pruning,其他的在后续的博文中将逐渐学习。

一:Network pruning
模型不能随便剪裁,因为可能会带来很多精度的损失。
这里简单学习学习,浅浅解析下。

当然,也有情况会在pruning后精度提高的,这说明原模型过似合(overfit)了,这样的话,pruning起到了regularization的作用。就一般情况下讲,核心问题是成如何有效地裁剪模型且最小化精度的损失。

其思想就是把网络中不重要的部分给剪裁掉。
包括参数和单元。

整体步骤如下:
1:初始化训练网络
2:评估各个参数和Neuron单元的重要性,并做排序。
3:裁减掉部分不重要的参数和Neuron单元,一次不要裁剪太多,否则可能网络精度损失到无法恢复。
4:查看模型的精度,如何精度提升则跳过,如果精度损失(希望别损失太多)则重新利用数据进行训练,希望能把精度恢复回来,这时候就是对剩下的结构进行微调。
5:是否满足大小和精度要求?满足则结束算法,不满足则跳到第二步重新来一遍。

现在整体的流程就是这样了,下面大概讲一下一些吧。
核心问题是怎么评估所谓的“重要性”以及每一次取裁剪时候的剪裁量。

所谓的“重要性”
1:对于参数来说,使用L1,L2的大小来衡量,越接近于0,越不重要,对于Neuron单元来说,在训练过程中,总是出现接近于0值,相对于其他Neuron单元激活值小,说明这个Neuron单元没什么贡献,那这个Neuron单元就不重要。实际中,更一般主要选择Neuron单元进行裁剪,如果按照参数裁剪会产生不规则的结构,参数个数不一致,少的补充0,可能导致没有什么大的变化。参数裁剪作为辅助。

2:通过衡量参数/Neuron单元对Loss的影响程度。将归一化的目标函数相对于参数/Neuron单元的导数绝对值作为重要性的衡量指标,如果偏导数越小,越不重要。

3:第三个思路是考虑对特征输出的可重建性的影响,即最小化裁剪后网络对于特征输出的重建误差,它的intuition是如果对当前层进行裁剪,然后如果它对后面输出还没啥影响,那说明裁掉的是不太重要的信息。

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

我们知道贪心算法的缺点就是只能找到局部最优解,因为它忽略了参数间的相互关系。那自然肯定会有一些方法会尝试考虑参数间的相互关系,试图找导全局更优解。

• 离散空间下的搜索:如2015年的论文《Structured Pruning of Deep Convolutional Neural Networks》基于genetic algorithm与particle filter来进行网络的pruning。2017年的论文《N2N Learning: Network to Network Compression via Policy Gradient Reinforcement Learning》。
• 规划问题:如比较新的2019年论文《Collaborative Channel Pruning for Deep Networks》提出CCP(Collaborative channel pruning)方法,它考虑了channel间的依赖关系 ,将channel选取问题形式化为约束下的二次规划问题,再用SQP(Sequential quadratic programming)求解。
• Bayesian方法:如2017年论文《Variational Dropout Sparsifies Deep Neural Networks》。
• 基于梯度的方法:如2017年的论文《Learning Sparse Neural Networks through L0 Regularization》。
• 基于聚类的方法:如2018年的论文《SCSP: Spectral Clustering Filter Pruning with Soft Self-adaption Manners》和《Exploring Linear Relationship in Feature Map Subspace for ConvNets Compression》。
如上论文都是可以在google学术上可以搜索到的。

另外还有个核心问题是在哪里裁剪多少,即sparsity ratio的确定。这里的sparsity ratio定义为层中为0参数所占比例,有些文章中也称为pruning rate等。从目标结构或者sparsity ratio的指定方式来说,按2018年论文《Rethinking the Value of Network Pruning》中的说法可分为预定义(predifined)和自动(automatic)两种方式。Predefined方法由人工指定每一层的比例进行裁剪,因此目标结构是提前确定。而automatic方法会根据所有的layer信息(即全局信息)由pruning算法确定每层裁剪比例,因此目标结构一开始并不确定。

有一些可以参考的pruned网络比如:
MobileNet:https://arxiv.org/abs/1704.04861
SqueezeNet:https://arxiv.org/abs/1602.07360
ShuffleNet:https://arxiv.org/abs/1707.01083
Xception:https://arxiv.org/abs/1610.02357

二:其他
为什么要prune?难道不能一开始就去训练个小的网络么?
小的网络可能比较难训练,大的网络包含了很多不同形式的小网络,从概率上讲会更大概率train好的。

其实小网络也可能存在可以prune的地方。这是个思路,不管是大网络,还是小网络,其实都可以在训练好之后进行prune,毕竟将网络简化,有利于存储和计算,节省内存。