原标题 | Pruning Deep Neural Networks

剪枝后这个深度神经收集速度提高了 3 倍体积缩小了 4 倍_神经元_权重 智能问答

作 者 | Ranjeet Singh

翻 译 | had_in(电子科技大学)

编 辑 | Pita

目前,深度学习模型须要大量的打算、内存和功耗,这成为我们在实时推理或在打算资源有限的边缘设备以及浏览器上运行模型的瓶颈。
能量效率是当前深度学习模型的紧张关注点。
提升这种效率的方法之一是着眼于推理效率。

更繁芜的模型=>更多的内存花费=>更多的功耗

剪枝便是一种推理方法,它可以有效地得到更小的模型、更高效的内存、更高效的功率和更快的推理,同时在精度上丢失较小,其他类似的技能还有权值共享和量化。
深度学习的灵感来自于神经科学领域的几个方面。
在深度学习中剪枝也是一个受生物学启示的观点,我们将在稍后的文章中进行谈论。

随着深度学习的进步,最前辈的模型也变得越来越精确,但这种进步是有代价的,我将在这个博客里对个中的一些进行解释。

寻衅一:模型尺度变得越来越大

很难通过空中下载技能来分配大尺度模型。

寻衅二:速率

演习韶光以fb.resnet.torch为基准,基于M40 GPUs。

如此长的演习韶光限定了机器学习研究职员的效率。

寻衅三:能量效率

AlphaGo: 1920个cpu和280个gpu,每场比赛3000美元的电费

在移动设备上:快速耗尽电池电量

数据中央:增加本钱

办理方法 — 高效的推断算法

剪枝

权重共享

量化

低秩逼近

二值神经网络 / 三值神经网络

Winograd转换

生物学启示的剪枝算法

人工神经网络中的剪枝被认为是来自人类大脑突触修剪的一个想法,在人类大脑中,当轴突和树突完备衰退和去世亡,会导致突触消逝,这发生在许多哺乳动物的幼年早期和发育期初期之间。
突触修剪从出生时开始,一贯持续到25岁旁边。

深层神经网络剪枝

[Lecun等. NIPS,89] [Han等. NIPS’15]

网络常日看起来与左边的那个类似:下层的每个神经元都与上层每个神经元相连,但这意味着我们须要将许多浮点数相乘。
空想情形下,我们只须要将每个神经元连接到其他的几个神经元上就可以省去一些乘法;这便是所谓的“稀疏”网络。

稀疏模型更随意马虎压缩,而且我们可以在推断时跳过0值以改进推断延迟。

如果可以根据神经元的贡献大小对网络中的神经元进行排序,那么就可以将排名较低的神经元从网络中移除,从而得到一个更小、更快的网络。

得到更快/更小的网络,对付在移动设备上运行这些深度学习网络非常主要。

例如,可以根据神经元权重的L1/L2范数进行排序。
在修剪之后,准确性会低落(如果排序较合理,可则能不会低落太多准确率),并且网络常日是迭代地演习-修剪-演习-修剪以较大程度担保模型的准确率。
如果我们一次修剪得太多,网络可能会受到严重毁坏,无法规复准确率。
因此在实践中,这是一个迭代的过程——常日称为“迭代剪枝”:修剪/演习/重复。

请参阅Tensorflow团队编写的代码,以理解迭代剪枝。

权重修剪

将权重矩阵中的单个权重设置为零。
这相称于删除连接,如图所示。

为了实现k%的稀疏性,我们将权重矩阵W中的各个权重按大小排序,然后将最小的k%的部分权重设置为零。

f = h5py.File(\公众model_weights.h5\"大众,'r+')for k in [.25, .50, .60, .70, .80, .90, .95, .97, .99]: ranks = {} for l in list(f[‘model_weights’])[:-1]: data = f[‘model_weights’][l][l][‘kernel:0’] w = np.array(data) ranks[l]=(rankdata(np.abs(w),method=’dense’) — 1).astype(int).reshape(w.shape) lower_bound_rank = np.ceil(np.max(ranks[l])k).astype(int) ranks[l][ranks[l]<=lower_bound_rank] = 0 ranks[l][ranks[l]>lower_bound_rank] = 1 w = wranks[l] data[…] = w

单元/神经元修剪

将权重矩阵中的全体列设置为零,实际上是删除相应的输入迷经元。

为了达到k%的稀疏性,我们根据权重矩阵的l2范数对列进行排序,并删除最小的k%的列。

f = h5py.File(\"大众model_weights.h5\公众,'r+')for k in [.25, .50, .60, .70, .80, .90, .95, .97, .99]: ranks = {} for l in list(f[‘model_weights’])[:-1]: data = f[‘model_weights’][l][l][‘kernel:0’] w = np.array(data) norm = LA.norm(w,axis=0) norm = np.tile(norm,(w.shape[0],1)) ranks[l] = (rankdata(norm,method=’dense’) — 1).astype(int).reshape(norm.shape) lower_bound_rank = np.ceil(np.max(ranks[l])k).astype(int) ranks[l][ranks[l]<=lower_bound_rank] = 0 ranks[l][ranks[l]>lower_bound_rank] = 1 w = wranks[l] data[…] = w

当然了,当您想增加稀疏性并删除更多的部分网络时,模型性能将逐步低落。
您估计稀疏性与性能之间的退化曲线是什么样的呢?

利用一个大略的神经网络构造对MNIST数据集上的图像分类模型进行剪枝 ,如下:

引用的参考代码中利用的体系构造

利用代码重新天生的退化曲线图

关键要点

许多研究职员认为剪枝是一种被忽略的方法,但它将得到更多的关注,并在实践中更多地利用。
我们展示了如何利用一个非常大略的神经网络构造在一个大略数据集上得到良好的结果。
我认为在实践中利用深度学习来办理的许多问题都与此类似,在有限的数据集上利用迁移学习,因此这些问题也可以从修剪算法中受益。

参考

Code for this blog post(https://drive.google.com/open?id=1GBLFxyFQtTTve_EE5y1Ulo0RwnKk_h6J)

To prune, or not to prune: exploring the efficacy of pruning for model compression, Michael H. Zhu, Suyog Gupta, 2017(https://arxiv.org/pdf/1710.01878.pdf)

Learning to Prune Filters in Convolutional Neural Networks, Qiangui Huang et. al, 2018(https://arxiv.org/pdf/1801.07365.pdf)

Pruning deep neural networks to make them fast and small(https://jacobgil.github.io/deeplearning/pruning-deep-learning)

Optimize machine learning models with Tensorflow Model Optimization Toolkit(https://www.tensorflow.org/model_optimization)

via https://towardsdatascience.com/pruning-deep-neural-network-56cae1ec5505

封面图来源:https://commons.wikimedia.org/wiki/File:Single-layer_feedforward_artificial_neural_network.png