模型压缩与加速入门

date
Sep 12, 2022
Last edited time
Sep 25, 2022 04:40 AM
status
Published
slug
模型压缩与加速入门
tags
summary
半成品, 接下来继续添加. 2022.09.13@添加了关于OBS的介绍 2022.09.14@添加了关于Data-free Parameter Pruning for Deep Neural Networks的介绍, 修改了目录结构 2022.09.17@添加更多的剪枝示例,添加权值分解相关资料链接 2022.09.18@添加部分与知识蒸馏相关资料.
type
Post
Field
Plat
 

参数共享

参数共享是通过设计一种映射将多个参数共享同一个数据.

示例

HashedNets
论文Compressing Neural Networks with the Hashing Trick[4] 论文中使用的HashedNets使用低成本哈希函数将连接权重随机分组到哈希桶中,并且同一哈希桶中的所有连接共享一个参数值。在训练过程中,对这些参数进行调整,以适应具有标准反向支持的HashedNets weights共享架构。如下图所示
notion image
可以看出这个例子中原始的参数有16+8=24个,压缩后有6个,压缩因子为1/4。
Product Quantization
假设有50,000张图片组成的图片集,使用 CNN 提取特征后,每张图片可以由1024维的特征表示。那么整个图片集由50000*1024的向量来表示。然后我们把1024维的向量平均分成m=8个子向量,每组子向量128维。如下图:
notion image
对于这8组子向量的,使用 kmeans 方法聚成k=256类。也就是说,每个子向量有256个中心点(centroids)。如下图:
notion image
在product quantization方法中,这256个中心点构成一个码本。这些码本的笛卡尔积就是原始D维向量对应的码本。用 表示第 组子向量,用 表示其对应学习到的聚类中心码本,那么原始 维向量对应的码本就是 ,码本大小为 km。 注意到每组子向量有其256个中心点,我们可以用中心点的 ID 来表示每组子向量中的每个向量。中心点的 ID只需要 8位来保存即可。这样,初始一个由32位浮点数组成的1,024维向量,可以转化为8个8位整数组成。
notion image

权值量化

量化是指将信号的连续取值近似为有限多个离散值的过程。可理解成一种信息压缩的方法。在计算机系统上考虑这个概念,一般用“低比特”来表示。也有人称量化为“定点化”,但是严格来讲所表示的范围是缩小的。定点化特指scale为2的幂次的线性量化,是一种更加实用的量化方法。

分类

1、二值化,其可以用简单的位运算来同时计算大量的数。
2、线性量化,又可细分为非对称,对称和ristretto几种。由于线性量化引入的额外量化/反量化计算都是标准的向量操作,也可以使用SIMD进行加速,带来的额外计算耗时不大。
3、对数量化,一个比较特殊的量化方法。两个同底的幂指数进行相乘,那么等价于其指数相加,降低了计算强度。同时加法也被转变为索引计算。

线性量化的具体方法

  1. L1: Data Free 直接将一个浮点参数直接转化成量化数,一般会带来很大的精度损失,但使用上非常简单。
  1. PTQ: Post Training Quantization 基于数据校准的方案。它需要转模型的时候提供一些真实的计算数据。
  1. QAT: Quantization Aware Training 基于训练finetune的方案,有很多论文都是使用这种方法,它的好处是可以带来更大的精度提升,缺点是需要修改训练代码,实施周期比较长。
线性量化
其中 表示量化后的整数值, 表示量化前的浮点值, 表示量化的scale, 表示浮点中的 值经量化后对应的整数:
和  通过统计得到,  和  则是整型数能表示的最大值和最小值。

网络剪枝

模型剪枝的原因

模型剪枝建立在两个广为认可的重要假设上.
  1. 第一是具有冗余参数的大模型很重要,它能够提供一个高性能的模型,并且去除掉一部分冗余的参数对模型性能是不会造成显著影响的。(否则我们直接从头训练一个小模型即可,不必要大费周章的训练一个大模型然后剪枝再获得一个小模型);
  1. 第二是剪枝后保留下来的模型的权重非常重要,如果将剪枝后的模型重新初始化并进行训练,其效果很难接近原有大模型的水平。

为什么可以剪枝

论文 The Lottery Ticket Hypothesis: Training Pruned Neural Networks 给出了解释:
论文根据现象:压缩技术可以在保持精度不变的情况下,可以去除90%的参数,提出彩票解说:训练成功的大网络包含子网络,这个子网络从头开始训练可以达到大网络的精度,这个网络也可以叫做中奖彩票。至于,为什么叫彩票假说,因为一群人如果有一人中奖,那么把这个人单独拿出来,他得的奖和这群人的总奖金相同。两件事原理相通。
文中为了证明中奖彩票在各种网络架构中的存在,对于全连接层,卷积层,残差层上进行了实验,论文通过训练并随后修剪最小的量级权重来找出大型网络中的中奖彩票。中奖彩票的权重会恢复到在训练开始前初始化的值,从而证明这些中奖彩票的幸运来自初始化

分类

按粒度分类

notion image
结构化的剪枝就是filter-level的剪枝,主要去除的是多余的通道和成组的卷积核,非结构化的剪枝则包括了对单一的权重、权重向量(行/列)和单一的卷积核的剪枝。

按流程分类

  1. one-shot 一次性剪枝
    1. 一次性剪枝在对参数的重要性进行排序后一次性去除所有的多余参数并进行微调
  1. iteration 迭代剪枝
    1. 迭代剪枝则每次只剪去一部分多余的参数,经过短暂的微调后继续进行下一轮剪枝。需要注意的是,迭代剪枝虽然每一轮都要进行微调,在剪枝完成后还是需要进行一次整体的长时间的微调才能确保模型最终收敛。

按解决方式分类

  1. 启发式
    1. 手动定义每个修剪单元的重要性,以删除神经网络中不重要的单元
      由于特征的输出是由输入与权重相乘后进行加权,权重的幅度越小,对输出的贡献越小,因此一种最直观的连接剪枝方法就是基于权重的幅度,如 L1/L2 范数的大小。这样的方法只需要三个步骤就能完成剪枝:
      其他变种有: 1. 激活值:利用激活值的大小来判别对应的神经元 的重要程度 2. APoZ:零元素占比 3. BN层的规模因子:如果规模因子较小,可以移除对应的特征图
      第一步:训练一个基准模型。
      第二步:对权重值的幅度进行排序,去掉低于一个预设阈值的连接,得到剪枝后的网络。
      第三步:对剪枝后网络进行微调以恢复损失的性能,然后继续进行第二步,依次交替,直到满足终止条件,比如精度下降在一定范围内。
  1. 优化式剪枝
    1. 将模型剪枝看作一个优化问题来自动寻找剪枝位置

剪枝实例

连接剪枝

OBD(Optimal Brain Damage)
OBD 将loss进行二阶泰勒展开, 使用对于参数的二阶导作为参数的重要性判断(海森矩阵的对角线上的元素), 然后和该参数的大小一起计算得到该参数的显著性得分, 然后删除低显著性的权值.
OBD 使用微调的剪枝方式,具体说来,计算每一个参数对于loss的影响,移除影响小的参数,这样迭代一直到参数数量减小到一定数量。OBD 计算每个参数的二阶导,以此来计算每个参数的“显著性”,删掉显著性比较小的参数,如此迭代得到最终结果。
notion image
我们用泰勒级数来近似目标函数 。参数向量的扰动 将会通过下面的式子来改变目标函数:
其中, 的元素, 是目标函数 关于 的梯度 的元素, 是目标函数 关于 的梯度海森矩阵 的元素。.
由于海森矩阵 很大并且计算复杂, 因此引入一个简化的近似方法。
  1. 对角逼近理论假定删除多个参数所引起的 是单独删除每个参数所引起的 的和, 因此
  1. 极值近似理论假设当训练收敛之后进行参数删除,所以参数向量是 的(局部)极小值,因此 ;
那么, .
OBD 算法的步骤如下:
  1. 选择一个合理的网络架构
  1. 训练网络直至收敛
  1. 计算每个参数的二阶偏导数值
  1. 根据公式 计算每个参数的贡献度
  1. 将参数按照贡献度排序,并删除一些贡献度低的参数迭代至第2步
OBS(Optimal Brain Surgeon)
OBS 与 OBD类似, 不过不同的是其使用了海森矩阵的所用元素来计算显著性得分, 与OBS一致的是都忽略了对于参数的一阶导(还有一种方法是使用一阶导来衡量参数的显著性得分).
误差函数关于权重w的导数可以用泰勒级数表示为:
对于一个误差达到局部极小的神经网络,上式的第一项为0,另外,我们也将第三项及更高次幂项忽略。然后,我们的目标是将其中的一个权重 置零,从而使得上式的变化最小。消除 可以表示为 ,或者更加通俗的表示为:.
其中 是在权重空间中对应于 的一个单位向量。于是我们的目标就变为了:
转换为拉格朗日等式:
对上式求导,并使用逆矩阵来找到最优的权重改变并且将最优改变对误差函数的影响是:
注意,这里的海森矩阵 和逆矩阵 都不要求是对角矩阵。进一步,我们的方法通过公式 重新计算了网络中所有权重的大小。我们将 叫做权重 的“贡献度“(当某个参数删除后,所引起的误差的增加)。该方法定义的贡献度比OBD方法更加通用,当然该方法也包含了OBD方法。 于是我们就算法流程如下:
  1. 训练一个相当大的神经网络至收敛
  1. 计算海森矩阵的逆矩阵
  1. 找到使得 最小的 。如果这个候选误差比 小得多,那么第 个权重就应该被删除,然后转到步骤4,否则转到步骤5。(也可以选择其他的停止条件)
  1. 使用第3步的q,用公式 更新所有的权重,然后转到步骤2
  1. 没有更多的权重可以删除,结束。(可以进行重训练)
N比M细粒度结构化稀疏
此方法就是直接将权重的大小作为显著性得分, 要注意的地方是STE策略, 看看附上的链接.
神经网络模型压缩随笔(三):剪枝/稀疏论文分享之N比M细粒度结构化稀疏
前面提到过,剪枝粒度越小,剪枝效果越好,所能达到的稀疏度越高。对于同一个网络,非结构化剪枝能比结构化剪枝达到更高的稀疏度。例如ResNet-50网络通过非结构化剪枝能够达到5.96倍的压缩率而不损失精度,而为了保证原精度,结构化剪枝就只能达到1倍的压缩率[3]。然而,非结构化的细粒度稀疏难以利用向量处理的范式,这会导致数据读取时依赖一定序列并引起延迟增加[1],这反而不利于模型加速。面对这种两难的问题,一个好的做法是结合两种方法。英伟达在2020年推出的基于ampere架构[2]的A100显卡使用了结构化的细粒度稀疏,通过ASP(APEX's Automatic Sparsity)对一个网络进行一次性剪枝,能够获得50%的稀疏度和2倍的加速。今天我们介绍一篇在此基础上的工作,发表于ICLR2021的《Learning N:M Fine-grained Structured Sparse Neural Networks From Scratch》。 为了获得稀疏的模型,有两种剪枝pipeline,一种是常见的两步法:先训练一个dense的大模型,然后去除冗余的参数,另一种则是一步法:动态的训练模型和进行模型结构剪枝。与两步法相比,一步法虽然节省了训练时间和资源消耗,但通常会得到更糟糕的preformance。作者采用了后一种方法,并引入了STE(Straight-through Estimator)训练方法和定义了SAD(Sparse Architecture Divergence)分析来确保稀疏模型的preformance。 什么是N:M 所谓的N:M稀疏,指的是每M个连续的权重中,最多只有N个非零值。一个当N=2,M=4时,稀疏权重矩阵的例子如下图所示: 为了使权重矩阵满足这样的稀疏性,我们必须强制要求M个连续的权重 \mathbf{w}_{i} 中,除了前N个最大权重之外,其余权重全为0,这个约束可以表示为函数 S(\cdot) : 其中 \xi 是第N个最大的权重。 如何训练这样的网络 引入这样的约束后网络就会变得不可导从而无法训练,好在神经网络量化中已经给出了解决方案,那就是STE(Straight Through Estimator),其原理是跳过约束函数,把梯度直接传给未加约束的权重。更具体一点,我们使用稀疏的网络 \mathbf{\tilde{W}} 获得loss和反向梯度,并把梯度加到稠密的网络 \mathbf{W} 上。但这样做会使得网络精度出现显著的下降,由于前向传播和反向传播的不匹配: 为此作者引入了 SAD (Sparse Architecture Divergence)来对稀疏网络的结构变化和对应精度下降的关系进行分析: 其中 i 和 j 代表训练的iteration, \varepsilon 是一个0-1mask,表示网络中哪些权重被保留了。从SAD的定义中不难发现,网络结构变化越小,SAD值也就越小。通过实验对比,作者发现较大的性能损失往往对应着较高的SAD,因此为了保证STE后网络的精度,就需要减小SAD,也就是减少网络的结构变化。 为此有两种选择,一种是增大未被置零的权重,一种是限制置零的权重变大(减小其梯度值)。很显然,由于未被置零的权重在前向传播和后向传播中使用的是同一个值,其估计精度要更为精确,而被置零的权重在前向和后向传播中使用的是不同的值,其估计精度不高,因此限制它的值要更为容易。 作者提出了SR-STE( Sparse-refifined STE)来完成这一操作,即改变权重的更新策略: W_{t+1}=W_{t}-\gamma_{t}(g(\tilde{W_{t}})+\lambda_{W}(1-\varepsilon_{t})\cdot W_{t}) 其中 W_{t} 表示第t个iteration的稠密权重, \gamma_{t} 表示学习率, g(\tilde{W_{t}}) 表示稀疏权重矩阵得到的梯度, \lambda_{W} 是一个人为设定的超参, \varepsilon 表示第t个iteration的0-1mask。 可以看到,通过SR-STE的训练方法,网络的精度损失得到了控制: 相关代码 论文代码已开源: https:// github.com/NM-sparsity/ NM-sparsity 引用: [1]Zhou A, Ma Y, Zhu J, et al.
神经网络模型压缩随笔(三):剪枝/稀疏论文分享之N比M细粒度结构化稀疏
什么是N:M
所谓的N:M稀疏,指的是每M个连续的权重中,最多只有N个非零值。一个当N=2,M=4时,稀疏权重矩阵的例子如下图所示:
notion image
为了使权重矩阵满足这样的稀疏性,我们必须强制要求 个连续的权重  中,除了前 个最大权重之外,其余权重全为 ,这个约束可以表示为函数  :
其中 是第 个最大的权重。
如何训练这样的网络
引入这样的约束后网络就会变得不可导从而无法训练,好在神经网络量化中已经给出了解决方案,那就是STE(Straight Through Estimator),其原理是跳过约束函数,把梯度直接传给未加约束的权重。更具体一点,我们使用稀疏的网络  获得loss和反向梯度,并把梯度加到稠密的网络  上。但这样做会使得网络精度出现显著的下降,由于前向传播和反向传播的不匹配:
notion image
由于剪枝前后的网络结构变化越小, 则模型的性能损失也较小, 因此需要减少网络的结构变化。为此有两种选择,一种是增大未被置零的权重,一种是限制置零的权重变大(减小其梯度值)。很显然,由于未被置零的权重在前向传播和后向传播中使用的是同一个值,其估计精度要更为精确,而被置零的权重在前向和后向传播中使用的是不同的值,其估计精度不高,因此限制它的值要更为容易。
作者提出了SR-STE( Sparse-refifined STE)来完成这一操作,即改变权重的更新策略:
其中  表示第t个iteration的稠密权重,  表示学习率,  表示稀疏权重矩阵得到的梯度,  是一个人为设定的超参,  表示第 个iteration的0-1mask。
可以看到,通过SR-STE的训练方法,网络的精度损失得到了控制:
notion image
Learning both Weights and Connections for Efficient Neural Networks
文章首先讲了LeNet、AlexNet和VGG这些当时经典的网络的参数量的非常大,同时需要的存储空间也越来越大;然后以能量消耗的角度谈了这些模型运行具体能消耗多少能量。这就引出了本文的目标,就是对较大的网络模型进行剪枝以降低能量消耗从而能在移动端实时运行。
文章提出的剪枝策略是:①在初始模型训练完成后,②移除权重低于特定阈值的所有连接,即从稠密连接的网络剪枝得到一个稀疏连接的网络,③然后重新训练得到的网络用来减小精度损失。其中,②③两步可以多次迭代进行以得到最优模型。如图所示:
notion image
该策略能在剪枝后还能保持原有的精度几乎不损失。
Deep Compression
文章提出了一个对模型进行压缩的pipeline, 即剪枝-量化-编码.
网络模型剪枝-论文阅读-Deep compression_AManFromEarth的博客-CSDN博客
下载地址: 《Deep compression: Compressing deep neural networks with pruning, trained quantization and Huffman coding》 这篇是韩松大神的代表作,是ICLR2016年的best paper,值得好好读一下。 其实这篇论文本质上是《Learning both Weights and Connections for Efficient Neural Networks》的极致扩展,是在这篇论文基础上继续压缩模型,建议先看下 该篇论文的讲解 。 论文首先从存储大小和能量消耗的角度表明现有大模型的缺点,然后引出论文的目标: 降低网络模型的存储和能量消耗使得这些模型能更好地部署到移动端 。所以论文提出了Deep Compression,包括三个步骤,如下图: 首先,对网络进行剪枝并且保留剪枝前的精度;然后,对权重进行量化,使得多个连接能共享同一个权重,从而可以使用更加有效的存储方式;最后,使用霍夫曼编码(Huffman coding)压缩权重。 这里的网络剪枝是完全按照 《Learning both Weights and Connections for Efficient Neural Networks》 这篇论文进行的,所以就不详述方法了。通过剪枝,可以分别减少AlexNet和VGG-16网络的9X和13X的参数。 剪枝后的网络是稀疏结构,所以需要特殊的存储方式,文中使用的是compressed sparse row(CSR)或compressed sparese column(CSC)方式,只需要2a+n+1个数字即可存储,其中a是非零数字的个数、n是行数或列数(感兴趣的可以看下 说明,一般实现是用 scipy.sparse.csr_matrix 实现)。 为了更进一步压缩,文中还对数据的索引进行了压缩,对卷积层和FC层分别使用8bits和5bits压缩。如图所示是3bits压缩方式, 该图有点不直观,简单来说就是对于 3.4 这个值,它的idx为1,而上一个索引是0,所以它的diff=1-0=1; 对于idx为4、value为0.9的这个值,它与上一个索引(即idx为1、值为3.4的索引)的差距diff=4-1=3; 对于idx为15、value为1.7的值,由于它与上一个索引(idx=4)的diff(15-4=11)超过了3bits(2^3=8),所以在idx=12处加了一个diff=8,然后idx=15处的diff就等于3了。 网络量化就是指将本来32bits的数据量化到16bits、8bits甚至1bits,权重共享是指多个网络连接使用共享同一个权重。 如下图所示是权重共享示意: 对于一个4x4的权重矩阵来说,将它的所有权重进行量化后聚类成4个centroid(使用不同的颜色标注),同一个centroid的所有权重共享同一个权重,所以为了存储对应关系,需要一个4x4的cluster index矩阵来存储。在反向传播过程中,同一个centroid的所有的权重的梯度相加然后乘以学习率lr更新centroids。 对于AlexNet来说,可以将每层卷积层量化为8bits(256个共享权重)和每层FC层量化为5bits(32个共享权重)的同时不损失精度。 文中还给出了压缩比例计算公式: 以上图举例,共有16个连接权重,聚类中心为4个。原始的权重是32bits,index矩阵需要16个2-bit大小,所以压缩比例r = 16 * 32 / (16 * 2 + 4 * 32) = 3.2。 权重共享 文中使用k-means聚类方法来确定哪些权重可以共享一个centroid,这个比较基础,就不多说了,实现方式可以用 sklearn.cluster.KMeans 。 共享权重初始化(即选择聚类中心) 文中比较了3种不同的聚类中心初始化方式:随机、基于分布密度、线性。 如图所示,剪枝后的权重分布呈现双正态分布状态。 随机:由于权重多在正态分布的峰值位置,所以随机初始化倾向于选择峰值位置的点作为聚类中心(左图黄点); 基于分布密度:如图中蓝色线是累计分布函数CDF曲线,按照相同的间隔取值作为聚类中心(左图蓝点),结果也是在峰值位置,但是比随机初始化更加分散; 线性:对权重的[min,max]区间进行线性划分(左图红点),该划分与权重分布无关。 在之前的 剪枝介绍中 有一个重要的剪枝前提就是权重越大的连接越重要,但是这些连接较少。所以随机和基于分布密度的初始化方式中很少有聚类中心能落到这些点附近,使得聚类中心对这些重要的权重表现能力差。但是线性初始化并不存在上述问题。同时在实验中也证明了上述结论,如下图: ...
网络模型剪枝-论文阅读-Deep compression_AManFromEarth的博客-CSDN博客
  1. 剪枝
    1. 剪枝方法按照上面的 Learning both Weights and Connections for Efficient Neural Networks 所进行.
      剪枝后的网络是稀疏结构,所以需要特殊的存储方式,文中使用的是compressed sparse row(CSR)或compressed sparese column(CSC)方式,只需要2a+n+1个数字即可存储,其中a是非零数字的个数、n是行数或列数.
      为了更进一步压缩,文中还对数据的索引进行了压缩,对卷积层和FC层分别使用8bits和5bits压缩。如图所示是3bits压缩方式
      notion image
      该图有点不直观,简单来说就是对于3.4这个值,它的idx为1,而上一个索引是0,所以它的diff=1-0=1;
      对于idx为4、value为0.9的这个值,它与上一个索引(即idx为1、值为3.4的索引)的差距diff=4-1=3;
      对于idx为15、value为1.7的值,由于它与上一个索引(idx=4)的diff(15-4=11)超过了3bits(2^3=8),所以在idx=12处加了一个diff=8,然后idx=15处的diff就等于3了。
  1. 量化与权重共享
    1. 网络量化就是指将本来32bits的数据量化到16bits、8bits甚至1bits,权重共享是指多个网络连接使用共享同一个权重。
      如下图所示是权重共享示意:
      notion image
      对于一个4x4的权重矩阵来说,将它的所有权重进行量化后聚类成4个centroid(使用不同的颜色标注),同一个centroid的所有权重共享同一个权重,所以为了存储对应关系,需要一个4x4的cluster index矩阵来存储。在反向传播过程中,同一个centroid的所有的权重的梯度相加然后乘以学习率lr更新centroids。
      对于AlexNet来说,可以将每层卷积层量化为8bits(256个共享权重)和每层FC层量化为5bits(32个共享权重)的同时不损失精度。
      文中还给出了压缩比例计算公式:
      其中, 是聚类数目,cluster index矩阵需要 bits, 表示所有连接数,每个连接占用 个bits。
      以上图举例,共有16个连接权重,聚类中心为4个。原始的权重是32bits,index矩阵需要16个2-bit大小,所以压缩比例r = 16 * 32 / (16 * 2 + 4 * 32) = 3.2。
  1. 霍夫曼编码
    1. 霍夫曼编码是一种非常常见的压缩方式,这里也不赘述了。实验证明,霍夫曼编码能节省20%-30%的网络存储。
 

神经元剪枝

Data-free Parameter Pruning for Deep Neural Networks(显著性矩阵)
此文章提出了不依赖于训练数据(data-free pruning)和反向传播,直接构建并排序权重的显著性矩阵,删除不显著冗余的节点.这里的显著性矩阵的判断依据是这两个神经元的贡献是否相似, 而不是对loss的权值低.
本篇论文的主要思想是,找到两个非常相似的神经元,删除其中的一个并使最终的输出尽量不变。
定义相似的神经元
之前的神经元剪枝操作是找到冗余的(权重为0的)神经元,然后进行剪枝,这样的话最终的网络输出是没有任何影响的。
在这篇论文中,作者定义了另外一种神经元冗余。首先以单层隐藏层、只有一个输出 的神经网络举例,如下图:
notion image
对于该神经网络输出 来说:
其中 是包含bias的权重向量, 是单个权重标量(或向量),是单调增长的非线性单元如sigmoid或ReLU。
假如 ,这就意味着 .
则原公式可以改成:
文中称这种剪枝方式为"surgery"。需要注意的是,这里的每个神经元所使用的非线性化函数 都是一样的。
不相似的神经元
由于神经网络来说,很难找到 的情况,所以文中使用了一种新的定义方式:
为经过 个隐藏神经元输出的结果,当  与 相似时,剪枝掉 ,就得到
那么, 枝减前后的输出值的差异定义为 .
由于若 ,而且 是单调递增函数,则 .
对随机变量 (服从于输入数据的分布)进行求期望操作,得到
所以为了求得上式左边,需要求下标对 使得 最小。需要注意的是,由于 是独立变量,所以不需要计算 的期望。此时只考虑 .
扩展到多个输出神经元时,得到:
其中 表示所有输出神经元的平均值。
为了简化后续叙述,定义 ,则神经元剪枝操作如下:
  1. 计算所有可能的 ,并保存在矩阵
  1. 选择矩阵 中的最小项,假设其下标为 ,删除第 个神经元,然后更新
  1. 通过删除第 行和第 列更新 矩阵,同时更新第 列。
计算量最大的是计算 矩阵,但是只需要计算一次。

通道剪枝

  • 通道剪枝(卷积核剪枝)
    • 对于一个维度为 的输入特征 ,其中 分别是第 层卷积层的输入特征通道数、高和宽。单个卷积操作是将一个大小为 的3D卷积核 上卷积得到维度为 的单个通道的特征图;正常卷积是有 个大小为 卷积核组组成的 大小的 卷积核组 上进行卷积,得到维度为 的输出特征图
      notion image
      当其中一个卷积核 被剪枝后,根据卷积操作方式,它所对应的特征通道 也会被移除,就减少了一个卷积核的计算量。同时,由于特征通道 的移除,对其进行的下一层卷积操作计算量也会相应减少。所以,剪枝第 层的 个卷积核会减少第 层和 层的共计 的计算量。
Pruning Filters For Efficient Convnets
文中声明所提出来的剪枝方法可以在对已训练好的模型剪枝用处较小的卷积核的同时尽可能地不损失精度。该方法通过计算当前卷积层的每个卷积核的F1-norm来确定各个卷积核的相对重要性,它也同样代表着卷积核的平均权重大小:F1(F2)-norm值低(权重小)的卷积核相对于其他卷积核一般会产生较弱激活的特征图。
对第 层卷积层剪枝 个卷积核的步骤如下:
  1. 对每个卷积核 ,计算其F1-norm记为 ;
  1. 进行排序;
  1. 个最小的 值的卷积核和相应输出特征图进行剪枝,下一层卷积层的对应卷积核通道也删除;
  1. 创建第 层和第 层的新的卷积核矩阵,同时保留其原来的权重并拷贝到新模型中。
Channel pruning for Accelerating Very DNN
这篇文章使用Lasso回归来计算每个通道的重要性, 移除不重要的通道(即移除生成此通道的卷积核以及减少再对其卷积的卷积核的层数). 由于LASSO回归使用L1约束(Ridge回归为L2, ElasticNet为L1+L2)来计算每个通道的权值, 得到的是一个稀疏解. 此后剪枝完, 再使用最小二乘法得到新的卷积核权重.
静态剪枝系列--Channel Pruning for Accelerating Very Deep Neural Networks
本文提出了一个新的通道剪枝方法来加速非常深的CNN。给定一个训练好的CNN模型,我们提出一个迭代、两步走的算法,通过channel selection和output reconstruction,来高效地对每一层进行剪枝。对于VGG-16,在只增加0.3%的错误率情况下,实现5x的加速。 作者源代码 问题建模 我们先提出对单层进行通道剪枝的方法,然后把方法拓展到多层甚至是整个模型。单层通道剪枝方法如下图所示,剪枝的重点是减少layer B的feature channels的通道数,同时保持下一层layer C的feature map和剪枝前的一致性。一但B的某些feature channels被剪了,我们就可以剪掉卷积核W中与被删掉通道对应的weight channels。同时,产生B中被剪掉的feature channels的卷积核也可以被删掉(就是虚线表示的立方体)。 通过上述分析,我们可以总结出通道剪枝包含了两个关键点 channel selection:我们需要选出适合被剪掉的通道来保留更多的信息 reconstruction:我们需要通过剩下的channels来重建下一层的feature maps 因此,本文提出了一个迭代的两步走算法 步骤1:通过LASSO regression选出最具有代表性的channels,然后剪掉剩下冗余的channels 步骤2:通过linear least squares和剩下的channels重建出输出 假设对一个位置进行卷积,输入 X 大小为 N \times c \times k_{h} \times k_{w} ,卷积核大小为 n \times c \times k_{h} \times k_{w} ,输出大小为 N \times n , N 是batch size,
静态剪枝系列--Channel Pruning for Accelerating Very Deep Neural Networks
如图,基于重建误差的剪枝算法,就是在剪掉当前层 的若干通道后,重建其输出特征图C使得损失信息最小。假如我们要将 的通道从 剪枝到 ,一但 的某些feature channels被剪了,我们就可以剪掉卷积核 中与被删掉通道对应的weight channels。同时,产生 中被剪掉的feature channels的卷积核也可以被删掉(就是虚线表示的立方体)。
notion image
通过上述分析,我们可以总结出通道剪枝包含了两个关键点
  • channel selection:我们需要选出适合被剪掉的通道来保留更多的信息
  • reconstruction:我们需要通过剩下的channels来重建下一层的feature maps
因此,本文提出了一个迭代的两步走算法
  1. 通过LASSO regression选出最具有代表性的channels,然后剪掉剩下冗余的channels
  1. 通过linear least squares和剩下的channels重建出输出
假设对一个位置进行卷积,输入  大小为  ,卷积核大小为  ,输出大小为  ,  是batch size,  是输出通道的数量, ,  是卷积核大小。为了把输入通道从  剪成  ,同时最小化reconstruction error。
我们把问题建模成下式,  是输入  的第  个通道,大小是  。  是  的第  个通道。  是一个 向量,表示第  个通道会不会被选中,  是输出。  是保留的通道数,可以根据目标加速比手动设置。定义列向量 为mask层(决定保留哪些channel)。因此为了最小化裁剪前后的误差,可将问题建模如下:
事实上这个问题属于NP-hard问题,为了便于求解论文中给等式加入了l1正则项
并且提出了两步走求解的方法, 首先固定 再求解 ,固定了 之后这个问题可以用Lasso回归解决:
其中 .
经过上一步求解 后,此时可以固定 求解 ,此时问题就变成了简单地最小二乘法可以解决的了
Learning Efficient Convolutional Networks through Network Slimming
该论文提出了在 batch normalization 层中对每个通道引入 作为比例因子,以乘积的方式应用到通道中;然后同时训练网络权重和这些比例因子,并且使用稀疏正则化对比例因子进行选择;最后剪枝掉 值比较小的通道并且重训练剪枝后的网络。如图所示:
notion image
当一个通道被剪枝后,前一层和后一层中与其相关的通道和卷积核都会被移除,这样就得到了一个窄网络。
目标函数为:
其中 为训练输入和输出,为可训练的权重;上式第一项为CNN的常规损失函数,是稀疏惩罚项, 是平衡系数。在实验中,,即L1-norm。在优化过程中,使用次梯度下降优化非平滑L1惩罚项,或者是使用smooth-L1作为惩罚项。
在BN层中应用比例因子
Batch Normalization是CNN中非常常用的一种优化方式,一般作用在激活层之前,它能使网络快速收敛和增加泛化性能。令 分别是BN层的输入和输出,B是当前的mini-batch,BN层是这样使用的:
其中 的均值和标准差, 是可训练的仿射变换参数(scale和shift),它们提供了恢复任意尺度线性转换的可能性。
因为BN的作用就是对所有batch中的相同通道进行normalization操作,所以论文直接使用BN中的 参数当作网络剪枝的比例因子。论文分析了不这样做的后果:
  1. 如果直接使用 而不使用BN层,那么 对于通道来说仅仅是线性变换,即使缩小 也可以放大相应通道权重来弥补,无法达到特征选择目的;
  1. 如果在BN层之前使用 ,该参数会被BN层完全抵消;
  1. 如果在BN层之后使用 ,每个通道就会存在连续的两个比例参数。
Learning Structured Sparsity in Deep Neural Networks
其使用 Group Lasso 回归来压缩网络的结构,这里包括了filter、channel、filter的形状与网络的深度 。SSL方法将结构正则化(网络的分类精度)与本地最优化(内存访问的计算效率),最后结果并不只是正则化之后提升精度的原始网络,而且还加速了计算过程。
Group Lasso
在线性回归中,我们需要对代价函数Cost Function 最小化拟合训练集: 岭回归,就是在线性回归的基础上加上 l2-norm的约束。为了之后推导方便改成了 ,因为是求代价函数最小值 所以并不改变结果。 其中 是正则项(惩罚系数),对 的模做约束,使得它的数值会比较小,很大程度上减轻了overfitting过拟合的问题。通过求解可以得出 . 上面两种优化形式是等价的,我们可以找到相对应的λ和θ。 LASSO是另一种缩减方法,将回归系数收缩在一定的区域内。LASSO的主要思想是构造一个一阶惩罚函数获得一个精炼的模型, 通过最终确定一些变量的系数为0进行特征筛选。 Yuan在2006年将lasso方法推广到group上面,诞生了group lasso。我们可以将所有变量分组,然后在目标函数中惩罚每一组的L2范数,这样达到的效果就是可以将一整组的系数同时消成零,即抹掉一整组的变量,这种手法叫做Group Lasso 分组最小角回归算法。其目标函数为: 其中, , 对于每个分组权重 代表一个 中的分组权重. 代表权重 的参数数量. 需要注意的是, 当 即分组只有一组的时候, Group Lasso 等价于 Ridge, 当 即分组数量等于 的参数个数的时候, Group Lasso 等价于 Lasso. 因为在 平面或者 平面上, 其最优解区域任然是尖锐的, 因此同样容易产生稀疏的结果. 在相同的正则化强度 下, Group Lasso 的稀疏强度小于 Lasso, 大于 Ridge.
Group Lasso
 
 

模型残留问题

  • 定义
    • 优化式剪枝中面临的最大问题:这些正则化项并不能使参数完全归零,只能在一定程度上接近零,如此以来,移除这些参数仍会造成损失,此现象称为模型残留.
  • 解决思路
    • Zeroing-out:模型残留主要由于:随着模型参数的降低,正则项对于参数的衰减梯度逐渐降低,从而和交叉熵的梯度相抵消,从而导致参数不会变小,因此在文章 Global Sparse Momentum SGD for Pruning Very Deep Neural Networks 中,提出截断冗余参数的目标函数反传的梯度,只允许参数的衰减,最终直至为零。

张量分解(低秩分解)

核心思想是利用矩阵或张量分解技术估计并分解深度模型中的原始卷积核.卷积计算是整个卷积神经网络中计算复杂度最高的计算操作,通过分解4D卷积核张量,可以有效地减少模型内部的冗余性.
这些方法将一个层分解为几个较小的层。虽然分解后会有更多的层,但浮点运算和权重的总数将更小。张量分解方法仅使用层的权重,其假设该层是过度参数化的,其权重可以由具有较低秩的矩阵或张量表示。
 

全连接层的分解

SVD分解

奇异值分解允许我们分解具有 行和 列的任何矩阵
其中, 是一个对角线矩阵,沿其对角线具有非负值(奇异值),通常构造为使奇异值按降序排序。 是正交矩阵:.
如果我们取最大的 个奇异值并将其余值归零,我们得到 的近似值:
具有很好的性质,即 是 Frobenius 范数最接近 的秩为 的矩阵,因此如果 足够大, 的良好近似。

分解过程

全连接层可以表示为: , 我们将矩阵 进行 SVD 分解, 保留前 个奇异值, 则可以将原公式表示为:
这样我们就通过 SVD 分解把一个全连接层分为了两个较小的层.

卷积层的分解

二维卷积层是一个具有 4 维的多维矩阵:out_channels x input_channels x height x width.
按照 SVD 示例,我们希望以某种方式将张量分解为几个较小的张量。然后,卷积层将由几个较小的卷积层近似。
为此,我们将使用两种流行的(至少在张量算法领域)张量分解:CP 分解Tucker 分解(也称为高阶 SVD 和许多其他名称)。

知识蒸馏

知识蒸馏(KD)的基本思想是通过软Softmax 变换学习教师输出的类别分布,并将大型教师模型的知识精炼为较小的模型。
最经典的,也是明确提出知识蒸馏概念的工作,通过使用带温度的softmax函数来软化教师网络的逻辑层输出作为学生网络的监督信息,为文章《Distilling the Knowledge in a Neural Network》。
逻辑单元是 Softmax 激活的前一层,而类概率是逻辑单元通过 Softmax 激活函数转化而来:.
其中, 是第 类的逻辑单元值, 是第 类的类概率以及 表示类别的数量. 网络输出逻辑单元和类概率的关系如图所示:
notion image
如果使用逻辑单元来表示知识,这些不受约束的值在测试的时候可能会包含噪声信息.如果将其包含噪声信息的逻辑单元作为学生的监督信号,则会因过拟合而限制了学生的泛化能力. 另一方面,如果使用类概率来表示知识,那么负标签的概率被 Softmax 压扁后将会接近零而导致在网络训练时这部分信息丢失.将该类概率作为学生的监督信号,相当于让学生学习硬目标知识.
软目标公式为:
其中, 为温度系数,用来控制输出概率的软化程度。
那么,蒸馏损失为:
则反向传播的损失为:
在假定 为零均值的情况下,有:
知识蒸馏在测试阶段令 时,不同逻辑单元值的软目标的差异很大,所以在测试时能够较好地区分开正确的类和错误的类. 而在训练时,较大 值的软目标差异比 时的差异小,模型训练时会对较小的逻辑单元给予更多的关注,从而使学生模型学习到这些负样本和正样本之间的关系信息.
另外,Hinton 等人还发现了在训练过程加上正确的数据标签(即硬目标)会使学习效果更好。知识蒸馏的总损失可以表示为:
其中 是硬标签的向量.
notion image

Reference

模型剪枝技术原理及其发展现状和展望 - AIQ
模型剪枝作为一项历史悠久的模型压缩技术,当前已经有了比较大的进步和发展,本文给大家梳理模型剪枝的核心技术,发展现状,未来展望以及学习资源推荐。 深度学习网络模型从卷积层到全连接层存在着大量冗余的参数,大量神经元激活值趋近于 0,将这些神经元去除后可以表现出同样的模型表达能力,这种情况被称为过参数化,而对应的技术则被称为模型剪枝。 模型剪枝是一个新概念吗?并不是,其实我们从学习深度学习的第一天起就接触过,Dropout 和 DropConnect 代表着非常经典的模型剪枝技术,看下图。 Dropout 中随机的将一些神经元的输出置零,这就是神经元剪枝。DropConnect 则随机的将一些神经元之间的连接置零,使得权重连接矩阵变得稀疏,这便是权重连接剪枝。它们就是最细粒度的剪枝技术,只是这个操作仅仅发生在训练中,对最终的模型不产生影响,因此没有被称为模型剪枝技术。 当然,模型剪枝不仅仅只有对神经元的剪枝和对权重连接的剪枝,根据粒度的不同,至少可以粗分为 4 个粒度。 细粒度剪枝(fine-grained):即对连接或者神经元进行剪枝,它是粒度最小的剪枝。 向量剪枝(vector-level):它相对于细粒度剪枝粒度更大,属于对卷积核内部(intra-kernel)的剪枝。 核剪枝(kernel-level):即去除某个卷积核,它将丢弃对输入通道中对应计算通道的响应。 滤波器剪枝(Filter-level):对整个卷积核组进行剪枝,会造成推理过程中输出特征通道数的改变。 细粒度剪枝(fine-grained),向量剪枝(vector-level),核剪枝(kernel-level)方法在参数量与模型性能之间取得了一定的平衡,但是网络的拓扑结构本身发生了变化,需要专门的算法设计来支持这种稀疏的运算,被称之为非结构化剪枝。 而滤波器剪枝(Filter-level)只改变了网络中的滤波器组和特征通道数目,所获得的模型不需要专门的算法设计就能够运行,被称为结构化剪枝。除此之外还有对整个网络层的剪枝,它可以被看作是滤波器剪枝(Filter-level)的变种,即所有的滤波器都丢弃。 既然冗余性是存在的,那么剪枝自然有它的必要性,下面以 Google 的研究来说明这个问题。 Google 在《To prune, or not to prune: exploring the efficacy of pruning for model compression》[1]中探讨了具有同等参数量的稀疏大模型和稠密小模型的性能对比,在图像和语音任务上表明稀疏大模型普遍有更好的性能。 它们对 Inception V3 模型进行了实验,在参数的稀疏性分别为 0%,50%,75%,87.5% 时,模型中非零参数分别是原始模型的 1,0.5,0.25,0.128 倍进行了实验。实验结果表明在稀疏性为 50% 时,Inception V3 模型的性能几乎不变。稀疏性为 87.5% 时,在 ImageNet 上的分类指标下降为 2%。 除了在大模型上的实验结果,还对小模型 MobileNet 也进行了实验,分别在同样大小参数量的情况下,比较了更窄的 MobileNet 和更加稀疏的 MobileNet 的分类指标,发现稀疏的 MobileNet 模型性能明显优于非稀疏的 MobileNet 模型。 具体来说,稀疏率为 75% 的模型比宽度为原始 MobileNet 的 0.5 倍的模型在 ImageNet 分类任务的 top-1 指标上高出了 4%,而且模型的体积更小。稀疏率为 90% 的模型比宽度为原始 MobileNet 的 0.25 倍的模型在 ImageNet 分类任务的 top-1 指标上高出了 10%,而两者的模型大小相当。 因此,我们完全可以相信,模型剪枝是有效的而且是必要的,剩下的问题就是怎么去找到冗余的参数进行剪枝。 模型剪枝算法根据剪枝的处理策略来说,可以分为对模型进行稀疏约束然后进行训练后的剪枝,在模型的训练过程中进行剪枝,以及在模型训练之前就进行剪枝。而根据粒度的不同,流行的剪枝算法是细粒度的权重连接剪枝和粗粒度的通道/滤波器剪枝。 这些方法各自有交叉,无法完全分开,下面我们就基于两大不同的粒度来介绍一些训练中剪枝的代表性方法,而不再单独介绍稀疏约束以及训练前剪枝方法,相关内容感兴趣的读者可以去有三 AI 知识星球中阅读。 对权重连接和神经元进行剪枝是最简单,也是最早期的剪枝技术,下图展示的就是一个剪枝前后对比,剪枝内容包括了连接和神经元。 这一类技术的整体步骤如下: ...
模型剪枝技术原理及其发展现状和展望 - AIQ
剪枝综述论文阅读:Methods for Pruning Deep Neural Networks_李明朔的博客-CSDN博客_apoz 剪枝
论文链接: Methods for Pruning Deep Neural Networks 近年来,随着嵌入式设备的广泛使用,在嵌入式设备上运行神经网络模型有了很大的需求,然而当前的网络结构越来越复杂,因此对网络进行修剪成为了比较热门的问题。 本文将一系列减小网络结构的方法分为了以下八部分,分别是: Magnitude based pruning methods:权重和神经元的显著性可以通过其数量级等本地度量来确定,或者通过它们对下一层的影响来近似确定。具有最小的显著性的权重和神经元被删除后对准确性的影响最小。 相似度和聚类方法:重复或者相似的权重是多余的,可以被剪枝 敏感度分析方法:评估移除或干扰权重对损耗的影响,然后移除对精度影响最小的权重的部分。 知识蒸馏方法:利用Teacher网络来学习Student网络。 低轶方法:将一个矩阵分解成两个较小的矩阵的乘积。 量化方法:使用量化,哈希,低精度和二进制表示的权值来减少计算。 结构设计方法(NAS):利用智能搜索和强化学习方法生成神经网络架构。 混合方法:将以上方法混合使用 基于相似度和聚类方法比较少,因此不进行细分。 利用灵敏度分析的方法可以细分为: 利用泰勒级数近似的损失和 使用采样等方法估计权重被删除时损失的变化。 当评估剪枝方法,以下措施用来比较他们的性能: 论文 Learning both Weights and Connections for Efficient Neural Networks 首先介绍了权重剪枝的方法:将权重低于某个阈值的全部被剪枝,之后进行fine-tuned直到准确率达到预期。 该论文的作者在LeNet、AlexNet、VGGNet上分别进行了实验验证了剪枝的作用。另一个针对L1和L2正则化的结论表明,不进行fine-tuned的情况下L1正则化更好,进行fine-tuned则L2正则化更好。另外,前面的网络层对剪枝更加敏感,因此迭代式剪枝方式更好。 彩票理论 :对于一个已经训练好的网络,一定存在它的一个子网络可以在不超过原网络训练轮数的情况下达到和原网络相当的准确率。这个子网络就类似于买彩票。 在LeNet和MNIST数据的实验中,研究者尝试了两种方法,第一种是完成训练后剪枝p%的参数,将剩余的参数重新初始化并重新训练,第二种方法是进行n轮迭代式剪枝。研究者们得到了如下结论: 在比较大的网络如AlexNet和VGGNet的结论表明,彩票理论依赖于学习率,较小的学习率更容易找到"彩票"。 在之后的论文 Rethinking the Value of Network Pruning 中,研究者对彩票理论提出了质疑。该作者使用了三种剪枝方法,分别是结构化剪枝(每层剪枝的通道比例是预定义的),自动化剪枝(全局剪枝比例确定,每层剪枝比例由算法决定),非结构化权重剪枝(只有权重的剪枝比例是预定义的)。 根据以上三种方法进行的实验,作者得出的结论是对于结构化和自动剪枝,随机初始化依旧有效,对于非结构化剪枝,在小型数据集可以去得不错的结果,大型数据集需要进行fine-tuning。 在后续的研究中,针对以下几个问题进行了更多的实验: 经过大量实验得到的结论是: 一些作者指出,尽管修剪权值的方法会导致更少的参数,但它们需要专门的库或硬件来处理产生的稀疏权值矩阵。相反,更高粒度级别的修剪(例如修剪过滤器和通道)可以从许多当前工具包中已有的优化中获益。这导致了许多旨在剪枝特征映射和过滤器的方法,这些方法将在本节中总结。 本部分主要从三个方向来阐述: 论文 Channel-level Acceleration of Deep Face Representations 提出了两种通道剪枝的方法,Inbound pruning和Reduce and Reuse pruning Inbound pruning Inbound pruning目的是为了减少输入到过滤器的通道数,其核心思想是使用不同的样本作为输入时,评估输入通道对输出特性映射的贡献变化的程度。这种方法的实现方式是用一些图片样本输入网络,使用特征图中由于通道而产生的差异作为其贡献的度量。 给定Wji为第j个过滤器对应第i个输入通道,和Xip为第i个通道第p个样本的输入,则第j个输出特征图的贡献Y可以被定义为: 根据上述定义,评估该贡献的方差的方法如下: 经过评估后将低于阈值的通道全部剪枝掉 Reduce and Reuse pruning Reduce and Reuse ...

© Lazurite 2021 - 2024