做电影网站一年赚多少,ant design 做网站,广州的广告公司有哪些,wordpress网站程序员模型压缩常用方法简介 整理自台湾大学李宏毅老师视频课程#xff1a; 神经网络压缩 为什么要进行模型压缩#xff1f;
延迟 latency隐私 privacy
本文主要从算法#xff08;而非硬件#xff09;的角度出发#xff0c;介绍一些常用的模型压缩技术。
网络剪枝 Network Pr…模型压缩常用方法简介 整理自台湾大学李宏毅老师视频课程 神经网络压缩 为什么要进行模型压缩
延迟 latency隐私 privacy
本文主要从算法而非硬件的角度出发介绍一些常用的模型压缩技术。
网络剪枝 Network Pruning
概念
深度学习网络通常是 over-parameterized 参数是高度冗余的并且不同部分的参数对性能的贡献差异也非常大。顾名思义网络剪枝就是将模型中一些不必要的参数修剪掉。
流程
网络剪枝的流程如下图所示 先训练一个大的、准确的网络 评估该网络参数中每个参数/每个神经元的 “重要性” 如何度量参数/神经元的 “重要性” 呢最直觉的想法参数的重要性可以由它绝对值的大小来表征绝对值较大的参数对网络整体的影响较大比较重要神经元的重要性可以通过记录对于多个输入它输出为零的次数来表征经常输出为零说明它不太重要。 移除掉不重要的参数/神经元 微调剪枝后的网络 通常在移除掉一些神经元之后网络的性能会有所下降。这时我们对剪枝过的网络进行微调使得它的准确率回升一些 重复 34 步骤直到模型的大小和精度都满足我们的需求。 移除参数/移除神经元
移除参数
如果我们要移除参数这个过程如下图所示。这样做得到的会是不规则的这样会带来两个问题一是不太好实现想想我们在深度学习框架如 Pytorch 中定义网络层时都是直接指定神经元的个数框架会给出一个标准的层。而如果要指定某些神经元的某些参数不存在是比较麻烦的二是不利于 GPU 加速现代神经网络大都是通过 GPU 进行并行加速的不管是全连接还是卷积其底层实现都是进行矩阵乘法而如果指定某些参数不存在对于 GPU 加速也是很麻烦的。
想要实现移除参数一个可行且直接的做法是不是真的移除参数而是将该参数的权重置为 0。这样做就能规避上面提到的两点问题达到与移除指定参数同样的效果。但是想想看我们现在是在做模型剪枝如果并没有实际移除参数那网络的参数量和计算量都根本没有减小啊这就没有意义了。
因此实际中通常采用的是移除神经元的方式。 移除神经元
如果通过移除神经元来实现模型剪枝模型在剪枝之后还是规则的这就没有上面移除参数方式中的难以实现和难以加速的两点问题。 为什么要剪枝
当有一个准确度较高的大模型通过剪枝的方式将它的参数量和计算量减小而且掉点不多这是模型剪枝做的事情。但是为什么不直接训练一个比较小、也比较准确的模型呢
实际上大模型比较容易训练并且也可以在剪枝之后保持准确率。而小模型很难通过直接训练得到较高的准确率。
大乐透假说
The Lottery Ticket Hypothesis: Finding Sparse, Trainable Neural Networks 提出了大乐透假说给出了大模型训练、小模型训练与剪枝的一种解释。
文章认为训练一个神经网络某一组结构的某一组初始化参数是可以训练成功的而其他结构、初始化参数很可能就是无法训练成功的。就像买彩票一样如果一个神经网络中恰好有这一组结构、初始化参数那么这个网络就是可以训练成功的。而一个神经网络可以看作是很多子网络的结合在这些子网络中只要有一组训练成功了那么整个大的网络就训练成功了。
大模型中子网络更多相当于买彩票的注数更多自然更可能成功。大模型成功之后就已经证实了该模型中的一个子网络是可以成功的因此如果将大模型中的其他子网络剪枝掉就可以得到规模又小、准确率又高的网络。而如果直接训练小模型相当于买彩票的注数较少因此很难直接训练出一个性能很好的小网络。 大乐透假说是如何通过实验证明的呢
下图中先有一个随机初始化的大模型最左侧经过训练之后得到高准确率的大模型。对训练好的大模型进行剪枝得到的是大模型的一个子网络小模型并且这个小模型性能也比较好。然后对于这个小模型如果完全重新随机一组初始化参数对小模型从头训练是无法得到好的性能的。但是如果使用原始大模型的随机初始化参数对小模型进行初始化再进行训练就可以得到好的性能。
这说明大模型通过训练找出了一个可行的初始化参数和子网络这就是 “中奖” 的那注彩票验证了大乐透假说。 相关研究
这里再列几篇与大乐透假说同期或之后的研究工作以及它们的主要结论有兴趣读一下原文
Deconstructing Lottery Tickets: Zeros, Signs, and the Supermask
详尽地测试了各种不同的剪枝策略并给出了哪种最好的实验结论如何初始化参数只要保持最终参数的符号而绝对值没那么重要从一个完全随机初始化的网络剪枝出一个可行的网络 并不是我创造了大卫他本来就在石头中我只是把多余的石头敲掉 —— 米开朗琪罗
Weight Agnostic Neural Networks
1.5 或随机初始化就可以得到很好的结果
Rethinking the Value of Network Pruning
小网络本身也可以训练起来只是之前的工作的 epoch 数设的不够而已 与大乐透解说相悖
知识蒸馏 Knowledge Distillation
概念
知识蒸馏是指先训练一个大的教师模型然后用教师模型训练学生模型将教师模型的输出 logits知识蒸馏给学生模型。这样做往往能够比直接从头训练一个小的学生模型的效果更好原因已经在模型剪枝部分讨论过了。
流程
知识蒸馏的常见流程如图所示。先用数据集中的样本及 one-hot 标签正常训练一个大的教师模型Teacher Net训练完成之后固定教师模型的参数将它的输出 logits 作为标签训练一个相对较小的学生网络Student Net。 为什么要蒸馏
相比于 one-hot 标签教师模型的输出能够提供更多、更丰富的信息量比如不同类别之间的相近程度。虽然我们知道分类模型是要让同类的输出尽量相近、不同类的输出尽量远离。但在实际中我们数据集中的各个类别之间的相近关系也有所不同比如数字1和数字7就比较接近和数字8就比较远离。然后“硬”的 one-hot 标签并不能给出这种不同类间的关系。但是教师模型的输出却可以。这种更丰富的、更有意义的标签或许能够帮助学生模型学的不那么吃力对这张图片不需要给出 数字1 是1其他都是0的预测给出 1: 0.7, 7: 0.2, 9: 0.1 … 的预测就很好了。
Distilling the Knowledge in a Neural Network
标签平滑的softmax
在知识蒸馏中所使用的 softmax 与常规 softmax 有所不同在于对每个标签的值除以了一个温度系数 temperature T T T这可以使得标签由陡峭变得平滑。如下图所示左侧是常规 softmax右侧是经过标签平滑的 softmax 。
为什么要让标签平滑呢 y i y_i yi 是教师模型的输出 logits如果直接经过常规 softmax 处理得到 y i ′ y_i yi′ 各类之间的差异会变的陡峭这样的话其实就跟原本的 one-hot 标签差不多了就失去了做知识蒸馏的意义。因此通过除以一个温度系数 T T T使得标签变得平滑学生模型才能从教师模型的输出中学到更多有用的东西。当然 T T T 也不能过大否则各类的预测值就都一样了。这里的温度 T T T 是一个需要手动调整的超参数。 几个trick/讨论
蒸馏哪一层
蒸馏 logits softmax前/softmax后蒸馏特征
学生模型是否可能优于教师模型
如果学生/教师模型规模/表达能力差距不太大是有可能的。
一个原因是学生模型学习的是教师模型的输出有更多有用的信息量。
可以看作是正则
参数量化 Parameter Quantization
参数量化
参数量化通常在神经网络中参数的数据类型是单精度的 fp32。如果我们对某些参数可以用更低的比特来表示比如 fp16、int8那么网络的规模明显会降低很多。
weight clustering
除了低比特表示之外另一个做法是参数聚类weight clustering。对于模型中的各个参数将他们数值接近的聚为一类比如在下图中不同的颜色就是不同一类的参数。然后用一个 table 将这一类的参数数值的平均值记录下来。在网络中记录每个参数属于哪一类对于每一类直接用 table 中存的平均值来表示。这样的话在网络中存储每个参数所占用的空间就只与类的个数有关比如图中有四个类那么网络中每个参数就只需要 2 个位来存储。 霍夫曼编码
在霍夫曼编码中比较常出现的数据用更少的位数来表示比较少出现的数据用更多的数据来表示这样平均下来会用到更少的存储空间。
Binary Weights
参数量化的极致当然就是将表示每个参数的所用的位数压到最低一位。这样的话每个参数就只有两个可能值了。听起来很不可思议这样的模型应该会效果很差甚至完全不 work 吧。但其实已经有一些研究表明甚至有时二值网络的表现会比正常的网络表现还要好。一个解释是将网络二值化相当于对网络参数进行了极致的正则化要求每个参数只能是 -1/1这样可以较好地缓解过拟合现象。
结构设计 Architecture Design
概念
结构设计的模型压缩方法是指通过设计适合的网络模型结构来得到更低参数量/计算量效果接近的模型。
深度可分离卷积 Depthwise Separable Convlution
标准卷积回顾
首先先来回顾一下标准卷积的参数量。一个标准卷积示意图如下该层卷积的输入有 2 个通道卷积核的 size 是 3x3所以每个卷积核的参数量是 2x3x3而一共有 4 个卷积核即输出通道数为 4因此总的参数量为3x3x2x472。 Depthwise Separable Convlution
然后来看一下深度可分离卷积是怎么做的。深度可分离卷积有两个步骤第一个步骤是 Depthwise Convulution即深度卷积第二个步骤是 Pointwise Convolution即点卷积。
Depthwise Convulution
在这一步中有几个输入通道就有几个卷积核每个卷积核只处理对应的一个通道。比如在图中输入有两个通道那么卷积核的个数也有两个分别处理一个输入通道那么对应的输出通道数也会是 2。也就是说在 Depthwise Convlution 这一步 输入通道数卷积核个数输出通道数。
Depthwise Convlution 非常明显的缺陷是只能够处理同一张特征图内部的特征交互而没有跨通道的特征交互如果有某些 pattern 是跨通道才能识别到的Depthwise Convlution 是无能为力的这就需要 深度可分离卷积的第二个步骤Pointwise Convlution。 Pointwise Convlution
经过 Depthwise Convlution 之后特征的通道数与输入一致。在 Pointwise Convlution 中是以 Depthwise Convlution 的输出作为输入。然后 Pointwise Convlution 是对 Deptwise Convlution 的输出再进行一次标准的卷积但是有一点限制是卷积核的尺寸必须是 1x1。这样Pointwise Convlution 只需要处理跨通道的信息交互就好了不需要再考虑同一张特征图内部的特征交互因为这在前一步中已经处理过了。
可以看到深度可分离卷积两步完成之后输出特征图的尺寸是与标准卷积一致的并且也都计算了特征图内部/跨通道之间的特征交互。因此它的性能应该是不会差标准卷积太多的。现在来计算一下这个例子中深度可分离卷积的计算量Depthwise Convluton3x3x218Pointwise Convlution1x1x2x48共计 26。而刚才计算得到的标准卷积的计算量为 72。可以看到深度可分离卷积对于模型参数量的压缩效果还是很可观的。 参数量对比
现在来计算以下一般情况下标准卷积与深度可分离卷积的参数量对比。
记输入输出通道数分别为 I , O I,\ O I, O卷积核尺寸为 K K K
常规卷积参数量 I × O × K × K I\times O\times K\times K I×O×K×K深度可分离卷积参数量 I × K × K I × O × 1 × 1 I\times K\times KI\times O\times 1\times 1 I×K×KI×O×1×1
二者比值 P a r a m s d s c o n v P a r a m s r e g c o n v K 2 I I O K 2 I O 1 O 1 K 2 \frac{Params_{dsconv}}{Params_{regconv}}\frac{K^2IIO}{K^2IO}\frac{1}{O}\frac{1}{K^2} ParamsregconvParamsdsconvK2IOK2IIOO1K21 在常见的深度 CNN 中 O O O 是一个很大的大叔(128, 512, …)而卷积核尺寸通常为 K 3 K3 K3。因此在常见的 CNN 中换用深度可分离卷积可粗略地估计卷积层的参数量较小到了原来的九分之一。
为什么深度可分离卷积是可行的——Low Rank Approximation
深度可分离卷积降低参数量的理论依据是低秩近似Low Rank Approximation。
线性层
先以线性层为例如果有一个线性层输入输出维度分别为 M , N M,\ N M, N 那么它的参数量为 M × N M\times N M×N 。
如果想要降低它的参数量可以怎么做呢
做法就是在它们中间加一个映射到 K K K 维的中间层。现在一层变两层参数量会变小吗不难得到变为两层之后参数量为 M × K K × N M\times KK\times N M×KK×N 。因此如果 K K K 的值远远小于 M , N M,N M,N 那么两层的参数量是会比一层的 M × N M\times N M×N 更小的。但是做了这种变换之后整个映射过程的秩是变小了因此该映射的表达能力可能有所降低。
深度可分离卷积
实际上深度可分离卷积的思想与上面线性层的低秩近似是类似的。也是通过将一层操作转换为两层操作降低总的参数量但是有最大限度地保证了整个映射的表达能力。如下图所示在常规卷积和深度可分离卷积中左上角的粉色元素的计算都是根据输入特征图中左上角的 18 个元素进行的。 动态计算 Dynamic Computation
概念
与上面介绍的四种技术不同动态计算的技术并不是直接压缩模型的大小而是根据设备即时算力不同动态地调整模型的大小。
做法
比较常见的做法是在深度或宽度两个维度来动态调整模型的规模。
深度
我们知道深度学习模型通常是有很多层堆叠起来的然后用最后一层的输出特征接一个线性层进行分类。在按深度动态计算中我们可以在训练时给模型的每一层输出特征都接一个分类器将他们的输出结果都与标签计算损失。这样就可以在推理时根据当前的算力情况动态地选择经过多少层就输出预测结果。
这样做可能存在的问题是一般CNN的浅层只需要提取一些局部的纹理特征但是如果在浅层就要求模型能够根据特征进行预测就强迫模型在浅层要提取一些高层的语义特征这可能会影响最终的性能。 宽度
动态计算也可以在模型的宽度维度上来做即根据当前算力选择用较宽或较窄的层。注意虽然模型的宽度可以选择但是它们实际上是同一个模型即图中相同颜色标记的权重都是一样的只是动态地选择根据那些神经元进行计算。 根据样本难度进行动态计算
之前介绍的动态计算方式都是需要根据即时算力来动态地选择模型的规模实际上也可以根据样本的难度由模型自己决定在哪一层停止。比如图中的例子比较简单的样本在浅层就已经有比较确定的答案即可停止而比较困难的样本在需要在深层才能做出预测。 Ref
神经网络压缩The Lottery Ticket Hypothesis: Finding Sparse, Trainable Neural NetworksBinaryConnect: Training Deep Neural Networks with binary weights during propagationsMobileNets: Efficient Convolutional Neural Networks for Mobile Vision Applications