图1

剪枝对象分析:

剪枝分为结构化剪枝和非结构化剪枝,细化可分为weights剪枝、神经元剪枝、filters剪枝、layers剪枝、channel剪枝、对channel分组剪枝,还有今年新提出来的Stripe剪枝。
先讲对weights做剪枝和对神经元做剪枝的区别


由 于 非 结 构 化 的 剪 枝 在 硬 件 方 面 需 要 有 专 用 的 库 支 持 {\color{blue}由于非结构化的剪枝在硬件方面需要有专用的库支持} 没 有 结 构 化 剪 枝 易 于 实 现 , {\color{Blue}没有结构化剪枝易于实现,} 正在逐渐淡出人们的焦点。

1.weights剪枝:

最原始的权重剪枝
将权重矩阵中相对不重要的权值剔除,然后再重新精修(finetune)网络进行微调。

基于结构化剪枝中比较经典的方法是:
Pruning Filters for Efficient ConvNets(ICLR 2017),基于L1-norm判断filter的重要性。如下图:在这里插入图片描述

和2016年Han S的Deep compression: Compressing deep neural networks with pruning, trained quantization and huffman coding,
基于权重的绝对值大小来判断重要性。(ICLR 2016)

  • 顾名思义,也就是将权重矩阵里一部分的权值剪枝掉,那它是怎么剪掉的呢?通过将权重设置为0,那么剪掉哪些weighs呢?答案很简单,就是直接把那些数值近于0的weights赋为0。如下图:

但是有人问:将数值 ≈ {\color{Blue} \approx} 0的weights赋为0后,真的能起到压缩模型大小的作用吗,Parameters并没有减少啊?

这 就 是 我 们 要 提 到 的 非 结 构 化 剪 枝 — — 权 重 修 剪 导 致 产 生 非 结 构 化 稀 疏 的 f i l t e r s , 这 很 难 被 通 用 硬 件 加 速 。 {\color{Red}这就是我们要提到的非结构化剪枝——权重修剪导致产生非结构化稀疏的filters,这很难被通用硬件加速。} filters

至于上面问题的回答是,Parameter的确没有减少,但是FLOPs减少了,所以仍然起到了压缩模型大小,降低Inference latency的效果。

  • 显然数值 ≈ {\color{Blue} \approx} 0的weights赋为0是最简单的判断unimportant的方式,判断的标准还有很多。

Weights Pruning是一种细粒度的剪枝方法,它对网络内部的单个权值进行剪枝,在不牺牲Accuracy的情况下形成稀疏网络。

细粒度级的稀疏性使其提供了最高的灵活性,通用性导致了更高压缩率,然而,由于非零的位置权重是不规则的,需要额外的权重记录位置信息,并且由于网络内部的随机性,WP修剪后的稀疏网络不能像FP(Filters Pruninng)那样以结构化的方式表示,使得权重剪枝无法在通用处理器上实现加速。


2.神经元剪枝:

神经元(Activation)剪枝
Activation pruning中比较经典的方法有:
Network trimming: A data-driven neuron pruning approach towards efficient deep architectures,
这是2017年Hu等人发表在ICLR上的工作。这篇论文中用activations中0的比例 (Average Percentage of Zeros, APoZ)作为度量标准,

An Entropy-based Pruning Method for CNN Compression,则利用信息熵进行剪枝。文章针对VGG16和ResNet18采用了两个不同的裁剪策略。对VGG16:
1. 裁剪前十层的layer
2. 用最大平均池化代替全连接层

Remarkable,也就是将模型中一部分的神经元剪掉,那它是怎么剪掉的呢?有人说是随机的。但很显然并不是。随机减去神经元的那就是dropout的工作了—————那么对应在实践操作中,只要删掉参数矩阵的一行元素就好啦~~

神经元剪枝可见下图,神经元简直就是去掉一些Neurons, 但是与weights 剪枝不同,体现在具体操作上就不是对权重矩阵的不规律的位置赋值为0 了,就是对权重矩阵的某一行置零了。那怎么找到这一行呢?或者说怎么找到这一行对应的神经元呢?做法可以是,计算神经元对应的一行或一列的平方和的根,以这个数值进行unimportance 的排序,将排序最小的那 k%置零。示意图如下:
在这里插入图片描述

  • 可以看到,与weights pruning相比,神经元剪枝就是对权重矩阵的整行整列做修剪,有基础知识应该很好理解…

权重矩阵的剪枝除了将权重矩阵中某些零散的参数,或者整行整列去掉外,我们能否将整个权重矩阵去掉呢?答案是肯定的,目前也有很多这方面的研究。而且直接进行权重矩阵剪枝,也是可行的方案。相比突触剪枝和神经元剪枝,压缩率要大很多。这就是对filters做pruning。

3.Filters剪枝:

由于原始卷积结构仍然保留,因此不需要专用硬件/库来实现。

Pruning convolutional neural networks for resource efficient inference
In ICLR, 2017。这篇ICLR2017的工作使用泰勒展开作为修剪标准的衡量,对filters进行剪枝

Filter Pruning via Geometric Median for Deep Convolutional Neural Networks Acceleration(CVPR2019) ,这是CVPR 2019的一篇oral,简称 FPGM
如上图,这篇论文利用几何中位数(Geometric Median)进行模型剪枝,属于对filters的剪枝。把绝对重要性拉到相对层面,认为与其他filters太相似的filter不重要。

《ThiNet: A Filter Level Pruning Method for Deep Neural Network Compression》 ICCV2017 以filter(卷积核)为单位,根据该层filter的输出来判断该filter是否对结果有贡献,如果没有贡献或贡献很小,则直接把这个filter去掉,因此文章的核心就在于filter的选择方式。
这篇论文的结果:VGG-16可以达到减少3.31倍FLOPs和16.63倍的压缩,top-5准确率只下降0.52%。

对filter和channel剪枝的工作有很多,各种算法层出不穷,但是这几年的paper各种算法Accuracy的提升很有限,虽然剪枝的主要目的并不在提升精度,但是从17年的那篇network slimming开始,对剪枝后的模型进行finetune之后精度明显超过baseline,而近几年的结果与17年的工作相比都没有一个明显的进步。当然,此言的前提是针对vgg网络的调研。



4.通道剪枝

关于通道剪枝的工作是最多的,是最易于IC实现的。它属于机构化剪枝的一种,通道剪枝就是每次剪枝若干组通道,如封图1所示,并且ICCV 2017年liu.等人的

《Learning Efficient Convolution Networks through Network Slimming》ICCV2017
它是引入BN层中缩放因子的γ对通道进行排序,对这篇论文我在CIFAR-10上的复现结果,在剪枝率为50%时,达到了惊人的94.22%。比paper中给的70%剪枝率时精度高了0.44%。如下图:
在这里插入图片描述
核心公式是 ∑ ( x , y ) l ( f ( x , W ) , y ) + λ ∑ γ ∈ Γ g ( γ ) \color{blue} \sum_{(x,y)}^{}l(f(x,W),y)+\lambda \sum_{\gamma \in \Gamma }^{}g(\gamma ) (x,y)l(f(x,W),y)+λγΓg(γ)

在训练时,对BN层的尺度因子添加L1正则化,达到稀疏化的作用,这样就可以通过BN层的尺度因子趋于0来识别不重要的channel。如上图,对应 γ \gamma γ 小的通道就直接被剪去。

《Channel Pruning for Accelerating Very Deep Neural Networks》ICCV2017 旷视科技。论文提出了新的通道剪枝方法,基于2步迭代的剪枝方法。首先基于LASSO回归选择通道,然后基于最小均方误差,进行权值的重新学习。该方法在VGG-16上取得了5倍的加速,并且只产生0.3%的误差。

同样,由于通道剪枝的亲近性,对其的研究不少于filter pruning。



5.Group-wise剪枝

就是对通道的分组剪枝,如封图所示,对通道进行分组剪枝其实已经是一个改进的方法了。但是他也有一个明显的弊端。
就是他移除的是某一层中所有的filters相同位置上的权重。但是,每个filters中无效的权重位置可能不同,所以这个方法解决不了这一点。

在这里插入图片描述

CVPR 2016的《Fast convnets using group-wise brain damage》和NIPS 2016的《Learning structured sparsity in deep neural networks》介绍了对通道进行分组剪枝的概念,如上图,提出通过group lasso regularization来学习神经网络中的结构化稀疏性。可以看到,分组后每次剪枝都是对每一层中filter的同一个位置剪去,使用“im2col”实现作为过滤器式和通道式修剪,可以有效地处理分组式修剪。

IJCNN2019的这篇《Structured pruning for efficient convnets via incremental regularization》提出一种动态的正则化方法改进了分组剪枝。



6.Stripe剪枝

这是最近NeurIPS2020新提出来的工作,腾讯优图的论文,号称刷新了filter剪枝的SOTA效果,下一篇博客我会详细介绍一下这个方法。方法如下:在这里插入图片描述
如封面图所示,他是结合了两种结构化和非结构化剪枝中的典型方法——weights pruning 和 filters pruning。所以它的做法是在filters中剪枝filter。如上图所示,他是按照kernel size把原filter切分成一个个条状的小条纹。
在这里插入图片描述
比如一个kernel,它的长和宽是经常相等的,假设是k×k×c,那我们就可以按照他的size把它剪成k×k个条。而且结合paper中提出的框架,可以学习到这个最佳形状的条纹。

以上就是对剪枝的对象的总结,如有不全之处,希望读到的各位朋友们指正,下一期会专门出一个对剪枝算法及其相关优秀论文的总结,也是对最近调研工作的一个记忆。




由于是六一儿童节,所以是以可爱的粉粉色来写的,祝大家六一快乐,一直可爱。
Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐