目录
如果模型太大,参数太多,占用空间,计算时间长,那么在手机、嵌入式设备(无人机、机器人、手环、等等)等应用场景,就会受到限制,所以希望能对网络模型做压缩
通常从几百 M 压缩到几十、十几 M
网络剪枝(Network Pruning)
训练出来的网络,参数其实偏多,会有冗余,可以剪枝叶,使模型变小,同时效果不会受太大影响
- 训练小模型效果差,甚至训练不出来,一般是训练大模型后剪枝
- 先训练大模型,去掉一些神经元或是去掉一些权重,重新评估,还太大就继续剪,不要一次剪太多
- 减权值或神经元,但减权值后连接不规则,导致无法利用 GPU 进行并行矩阵计算反而更慢,所以一般是减神经元
- 随机减,或减那些权值小的
小模型的精度会下降(可以对小模型再用一些数据作简单的训练提高精度)
知识蒸馏(Knowledge Distillation)
一个 teacher net 和一个 student net
teacher net 是正常学习的模型
student net 是从 teacher net 学习
比如 mnist 数字图片 1,在 teacher net 学习的时候是要求输出分类 1 的概率是 100%,其他分类的概率是 0,学完后,模型对图片 1 输出结果假设是:1 的概率 70%,7 的概率 30%
那么 student net 学习的时候,就是要求输入图片 1 的时候,输出结果是:1 的概率 70%,7 的概率 30%
不止最终输出,甚至中间层的输出也可以从 teacher net 学习
这样能学到更多信息,“这个图片很可能是 1 但也有点像 7” 比 “这个图片就是 1” 包含的信息量更多,因为 1 确实和 7 有点类似,前一个结论更符合现实
这种方法可以使小模型得到和大模型相似的结果 (student 一开始就是设计成小模型)
Temperature :在做 softmax 的时候,可以除以一个值,防止结果差距太大
参数量化
- 用更少位数 (bit) 代表参数
- 把值接近的参数组成一组参数,用同一个值表示(取平均)
- 编码(比如霍夫曼编码)
目的是减少存储
结构设计
-
把全连接的权重 W 拆成更小的两个 W,相当于插入一个新的连接层
比如原来的 W 是 (200,100) 矩阵共 20000 个参数,拆成 (200,10) 和 (10,100) 两个矩阵,就只有 3000 参数
这样最终输出的结构是一样的,但参数少很多,当然精度也会下降
就是 SVD 分解法 -
深度可分卷积(depthwise separable convolution)
传统的卷积计算,比如输入是 64 x 64 x 3 的图片,希望输出 4 维数据
通常用 4 个 3 x 3 x 3 的卷积核计算,共 (3 x 3 x 3 x 4) = 108 个参数深度可分卷积将计算拆成两步
- 用 3 个 3 x 3 的核,每个核只计算图片的其中一个通道,这样输出一个 3 维数据,其长和宽和希望的最终结果一样
- 用 4 个 1 x 1 x 3 的核对第一步的结果作进一步计算,每个核都计算所有 3 个通道,这样最终输出的长和宽没变化还是和希望的最终结果一样,但变成了 4 维数据
这样共 (3 x 3 x 3 + 1 x 1 x 3 x 4) = 39 个参数
这样能以较小的性能损失大大减少模型大小
动态计算
如果资源不够的话,就只计算模型的部分网络层,比如一个 10 层网络,只算 5 层就给出结果