剪枝系列1:AutoPruner
这是此系列第一篇博客,也是我的第一篇博客,可能许多地方写的简略。主要目的是记录一下看过的论文,以后自己要用到的时候可以快速了解这篇论文的主要思想。
AutoPruner: An End-to-End Trainable Filter Pruning Method for Efficient Deep Model Inference是2018年南京大学的一篇文章,算是比较新的剪枝算法吧。这几年在剪枝方面出了很多思路,比如三阶段法(train-prune-finetune),边训练边剪法,逐层剪还是所有层同时剪,一次性剪还是每次剪,或者有人直接质疑剪枝的必要性,认为直接训练小模型效果并不差。但是总体来说,主要还是围绕着channel pruning(filter pruning)来展开。最传统的也是最简单的方法是,根据每一层自己的卷积核的参数,设计准则去掉被判断为不重要的channel,有L1准则,泰勒展开准则,GM和RePr准则;其他做法比如ThiNet是根据下一层的输出来判断本层的重要性;还有的剪枝算法关注每层剪枝率的设置,用了强化学习的方法来找出最佳剪枝率;也有的希望在训练时通过修改损失函数来训练出冗余卷积核的。
本篇论文,是一个通道剪枝+边剪枝边finetune+逐层剪枝+非人工准则的方法。(两阶段,训练阶段还是要的,只是剪枝和finetune结合到一起了)
方法如下:对每一层,添加一层编码层,设置损失函数来使得编码层输出为0,1的向量,并且1的数量满足剪枝率。编码层的输出会和原来的层相乘,训练结束后,0对应的通道被直接拿掉,不用再另外finetune。
但是这个方法有一个控制收敛到0,1的参数
α
\alpha
α特别不好设置。每种网络、每个层的
α
\alpha
α都不一样。特别不方便。而损失函数是用来控制稀疏程度的。还有编码层的初始化也比较难搞。
实验结果
VGG16 on CUB200-2011
ImageNet
总之,可以借鉴的地方是编码层0,1来代表剪枝与否的思想,以及用损失函数控制稀疏度的思想,还有把finetune和剪枝合到一起的思想。但是逐层剪真的不提倡。
好像没有开源代码。