网络压缩-2,剪枝,3、量化,4、降低数据数值范围 ,5、迁移学习

2,剪枝(pruning) 在训练结束后,可以将一些不重要的神经元连接

非结构化剪枝Pruning,结构化剪枝Filter Pruning,梯度Pruning等方法

(可用权重数值大小衡量配合损失函数中的稀疏约束)或整个滤波器去除, 之后进行若干轮微调。实际运行中,神经元连接级别的剪枝会 使结果变得稀疏,
不利于缓存优化和内存访问,有的需要专门设计配套的运行库。 相比之下,滤波器级别的剪枝可直接运行在现有的运行库下,
而滤波器级别的剪枝的关键是如何衡量滤波器的重要程度。 例如,可用卷积结果的稀疏程度、该滤波器对损失函数的影响、
或卷积结果对下一层结果的影响来衡量。

特别地,由于计算稀疏矩阵在CPU和GPU上都有特定的方法,所以前向计算也需要对一些部分进行代码修改。
GPU上计算稀疏需要调用cuSPARSE库, 而CPU上计算稀疏需要mkl_sparse之类的库去优化稀疏矩阵的计算, 否则达不到加速效果.

剪枝方法基本流程如下:
1. 正常流程训练一个神经网络。以CAFFE为例,就是普普通通地训练出一个caffemodel。
2. 确定一个需要剪枝的层,一般为全连接层,设定一个裁剪阈值或者比例。
实现上,通过修改代码加入一个与参数矩阵尺寸一致的mask矩阵。
mask矩阵中只有0和1,实际上是用于重新训练的网络。
3. 重新训练微调,参数在计算的时候先乘以该mask,则mask位为1的参数值将继续训练通过BP调整,
而mask位为0的部分因为输出始终为0则不对后续部分产生影响。
4. 输出模型参数储存的时候,因为有大量的稀疏,所以需要重新定义储存的数据结构,
仅储存非零值以及其矩阵位置。重新读取模型参数的时候,就可以还原矩阵。

a、非结构化剪枝
b、结构化剪枝

3、量化(quantization)。对权重数值进行聚类,

4、降低数据数值范围。 其实也可以算作量化

5、迁移学习 Knowledge Distillation

已训练好的模型上做裁剪

这种就是在训练好的模型上做一些修改, 然后在fine-tuning到原来的准确率, 主要有一些方法:
1、剪枝:神经网络是由一层一层的节点通过边连接,每个边上会有权重,
所谓剪枝,就是当我们发现某些边上的权重很小,
可以认为这样的边不重要,进而可以去掉这些边。
在训练的过程中,在训练完大模型之后,
看看哪些边的权值比较小,把这些边去掉,然后继续训练模型;
2、权值共享:就是让一些边共用一个权值,达到缩减参数个数的目的。
假设相邻两层之间是全连接,每层有1000个节点,
那么这两层之间就有1000*1000=100万个权重参数。
可以将这一百万个权值做聚类,利用每一类的均值代替这一类中的每个权值大小,
这样同属于一类的很多边共享相同的权值,假设把一百万个权值聚成一千类,则可以把参数个数从一百万降到一千个。
3、量化:一般而言,神经网络模型的参数都是用的32bit长度的浮点型数表示,
实际上不需要保留那么高的精度,可以通过量化,
比如用0~255表示原来32个bit所表示的精度,
通过牺牲精度来降低每一个权值所需要占用的空间。
4、神经网络二值化:比量化更为极致的做法就是神经网络二值化,
也即将所有的权值不用浮点数表示了,
用二进制的数表示,要么是+1,要么是-1,用二进制的方式表示,
原来一个32bit权值现在只需要一个bit就可以表示,
可以大大减小模型尺寸。

你可能感兴趣的:(神经网络优化)