神经网络中的剪枝

编译:ronghuaiyang

导读

目前,深度学习模型需要大量的计算、内存和能力,这成为我们需要实时推理或在计算资源有限的边缘设备和浏览器上运行模型的瓶颈。能源效率是当前深度学习模型的主要关注点。处理这种效率的方法之一是启用高效推理。

更大的模型=>更多的内存使用=>更多的能量

剪枝是一种推理方法,它可以有效地生成更小的模型、更高效的内存使用、更高效的能量使用和更快的推理,同时在精度上损失最小,其他类似的技术还有权值共享和量化。深度学习的灵感来自于神经科学领域的几个方面。在深度学习中剪枝也是一个受生物学启发的概念,我们将在稍后的文章中讨论。

随着深度学习的进步,最先进的模型变得越来越精确,但这种进步是有代价的。我将在这个博客中讨论其中的一些。

第一个挑战 :模型越来越大

很难通过在线更新来发布非常大的模型。

神经网络中的剪枝

第二个挑战:速度

神经网络中的剪枝

训练时间以fb.resnet.torch为基准,使用四个M40 gpu。

如此长的训练时间限制了ML研究人员的生产力。

第三个挑战:能耗效率

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

神经网络中的剪枝

  • 在移动设备上:干电池
  • 在数据中心:增加TCO

解决方案:高效推理算法

  • 剪枝
  • 权值共享
  • 量化
  • 低秩近似
  • 二值化 / 三元化 网络
  • Winograd转换

受到生物学启发的剪枝

人工神经网络中的剪枝是从人脑的突触修剪借鉴过来的,在早期童年和青春期开始的时候,许多(哺乳动物)的触突和轴突会逐渐死亡。剪枝从出生时开始,一直持续到25岁左右。

神经网络中的剪枝

神经网络剪枝

神经网络中的剪枝

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

稀疏模型更容易压缩,我们可以在推理过程中跳过零值,以改进延迟。

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

要在移动设备上运行这些深度学习网络,获得更快/更小的网络非常重要

例如,可以根据神经元权重的L1/L2范数进行排序。在修剪之后,准确性会下降(如果排名很聪明,希望不会下降太多),并且网络通常是迭代地训练-修剪-训练-修剪来恢复。如果我们一次修剪得太多,网络可能会受到严重破坏,无法恢复。因此,在实践中,这是一个迭代过程——通常称为“迭代剪枝”:修剪/训练/重复。

权值剪枝

  • 将权重矩阵中的单个权重设置为零。这对应于删除连接,如图所示。
  • 这里,为了实现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 = w*ranks[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]:
\tranks = {}
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 = w*ranks[l]
data[…] = w

自然,当您增加稀疏性并删除更多的网络时,性能将逐步下降。您预期稀疏性与性能之间的退化曲线是什么?

在MNIST数据集上使用一个简单的神经网络结构剪除图像分类模型的结果,给出如下-

神经网络中的剪枝

网络的体系结构

神经网络中的剪枝

使用代码生成的图

神经网络中的剪枝

要点

许多研究人员认为剪枝是一种被忽视的方法,将得到更多的关注和在实践中使用。我们展示了如何使用一个非常简单的神经网络结构在一个玩具数据集上获得良好的结果。我认为在实践中使用深度学习来解决的许多问题与此类似,在有限的数据集上使用迁移学习,所以它们也可以从剪枝中受益。

英文原文:https://towardsdatascience.com/pruning-deep-neural-network-56cae1ec5505

神经网络中的剪枝


分享到:


相關文章: