![805323112e9b00902d8ce4e2828f9000.png](https://i-blog.csdnimg.cn/blog_migrate/00a5280d11ff0d02cddd2a8188d13862.jpeg)
这是薰风读论文的第1篇投稿,欢迎互相交流学习~
神经网络压缩一直是一个重要的研究方向,而目前业界最认可的压缩方法莫过于ICLR 2016的最佳论文Deep Compression,算法流程如下图所示:
![2bff29f73baa9143a64973d8864be5d0.png](https://i-blog.csdnimg.cn/blog_migrate/2adf08837756ca535214ff6da9ee1fe2.jpeg)
上图为Deep compression论文介绍的神经网络压缩方法,可分为三步:
- 剪枝:舍弃权重绝对值较小的权重,并将剩余权重以稀疏矩阵表示。
- 量化:将剪枝结果进行进一步量化,具体的是构建一组权值码本,使模型中的权值共享码本中的其中一个权重值,以减少每个权重保存所需的比特数。
- 霍夫曼编码(可选):通过霍夫曼编码,进一步地压缩索引值以及权重数值地存储空间。
Deep Compression通过上述三个步骤之后,可以系统地压缩任意训练好的神经网络,达到35到49倍的压缩率。
1. 剪枝
首先,Deep Compression通过设定一个阈值
若阈值设置得当,则权重矩阵应会从稠密矩阵转为一个稀疏矩阵(也可以是一个稀疏矩阵变得更加稀疏),由此权值矩阵可以使用存储稀疏矩阵的压缩存储方式存储,例如CSR(compressed sparse row) 或CSC(compressed sparse column)。Deep Compression在CSR和CSC的基础上,将索引值转为3比特的偏移量值(若超出3比特则需要补零),下面举一个简单的例子:
假设稀疏矩阵原来的存储方式为:
![a7a84466ffaeef902b233a234a642327.png](https://i-blog.csdnimg.cn/blog_migrate/977c618da7822cb90a478e9e06932a52.jpeg)
现在的存储方式为:
![c8eb544cbf6c55cd8d9c481f5298eb39.png](https://i-blog.csdnimg.cn/blog_migrate/7b23af6c1a58a9983214c26f9ac6a065.jpeg)
偏移量相较于索引值可以使用更少的比特进行存储,如果偏移量超过3比特可以表示的范围,则需要补充额外的0权重。
注意,这里的剪枝过程不止进行一次。通常情况下,模型进行一次剪枝之后需要再次训练,然后对训练结果再次剪枝,之后还要再次训练……重复这一过程直到保持精度的前提下模型无法继续剪枝为止。
2. 量化
量化从定义上指使用较低的位数,以一定的误差为代价,去表示一个高位数表示的值。
Deep Compression的量化为创建一个权值码本,所有的权重大小都只能从码本中进行选择,即进行整个模型之间的权值共享。量化具体分为以下三步:
- 初始化k-means质心:Deep Compression量化过程中的权重聚类使用了k-means算法,因此k-means质心的初始化非常关键。常见的初始化方法三种:均匀初始化、随机初始化和按密度初始化,论文中证明最好使用均匀初始化,均匀初始化的方法是在权值的最小值
与最大值
之间线性插值,得到均匀的初始化结果,如公式所示,其中
是初始化的第
个质心,
为量化的位数,则有:
- 确定对应关系:即确定各个权值分别对应码本中的哪个权值,对应关系通过上一步初始化的 k-means算法确定。同一个聚类簇中的权重共享聚类中心的权值。
- 权值微调:通过再训练微调k-means的质心,即码本中的权值(只微调质心的权值,所有权重与码本权值的对应关系不变)如下图所示:
![3d842032eeba91ab38da7d798ace86f2.png](https://i-blog.csdnimg.cn/blog_migrate/36bf3df1d50797ff84d4a15e84eace0a.jpeg)
如上图所示,首先所有权重和正常的神经网络一样计算梯度。但由于剪枝的作用,矩阵实际上已经是稀疏矩阵,权值矩阵中为0则表示该连接被移除,因此这些位置的梯度被舍弃(置0)。而剪枝后,每一个权值对应的聚类结果(即对应码本中的权值)已经确定,在图中的聚类索引表示聚类的结果,同时该结果在权重和梯度图中以对应的颜色标注,例如权重中的2.09(第一行第一列)和2.12(第二行第四列)为同一类,量化之后他们的值也都是质心的值。
当生成梯度矩阵后,对聚类质心进行微调,即对同一类的所有权值的梯度求和,再乘以学习率(这里为了方便,假定学习率lr=1),进行梯度下降,公式如下:
其中,
微调过后,最终Deep Compression存储的是一个数据内容是码本索引的稀疏矩阵外加一个存储索引对应权值(质心)的码本。如此一来,就可以将存储权重所需的比特数进一步降低,达到压缩的目的。
3. 霍夫曼编码
采用变长的位数存储索引值,总的来说能够让占比较多的索引值用较长的比特数表示,而出现次数较少的则用较多的比特数表示,已达到进一步压缩的效果。
通过如上三步,我们就能得到一个被Deep Compression充分压缩的模型。
算法效果分析
为了得到具体的压缩比,首先要考虑最终模型保存了哪些内容。实际上,Deep Compression保存了一个由稀疏矩阵构成的索引集合,以及一个索引对应权重的码本。
假设权重经过k-means聚类后(共
而且,在量化之前权重已经经过了一次剪枝,因此实际上的权重数比压缩前更少,因此压缩率还要再除以剪枝后的权重留存的比率
实验中,若参数设置合理,并进行反复剪枝,在精度降低较小(1%以内)的情况下 Deep Compression可以在VGG Net上实现高达49的压缩比!直至目前为止,49倍压缩比都是一个非常高的数字。
薰风说:深度神经网络模型的压缩,无外乎两种方案:减少模型的参数量/减少每个参数占用的内存。在众多的压缩方法中,剪枝解决了前者的问题,而量化解决了后者的问题。
Deep Compression巧妙地通过一个pipeline同时解决了两个问题,这也是它所以达到那么好效果的原因。