深度学习模型压缩方法(5)-----Deep Compression

《Deep Compression: Compression Deep Neural Networks With Pruning, Trained Quantization And Huffman Coding

原作者基于Alex的代码:https://github.com/songhan/Deep-Compression-AlexNet 

用Caffe实现:https://github.com/may0324/DeepCompression-caffe 

Deep Compression[1],Stanford的Song Han的这篇文章,获得了ICLR2016 的 best paper。文章其实非常好懂,如下图所示,主要流程分三个阶段,一是对网络剪枝,让连接数量减少;第二是通过共享权重和权重进行索引编码来减小权重数量和存储空间;第三是用霍夫曼编码的方式来编码第二阶段的权重和索引,这样可以进一步压缩空间。

 

深度学习模型压缩方法(5)-----Deep Compression

 

图 1 Deep Compression网络压缩流程

1-网络剪枝

如图 1所示,剪枝需要三个步骤,首先是训练一个普通的神经网络;然后我们选择一个阈值,将权重小于阈值的连接剪开,这样就得到一个稀疏连接的网络了(图 2);剪枝后网络性能肯定会下降一些,所以最后我们对这个稀疏网络进行再训练,将性能提上去。对AlexNet,剪枝可以减少9倍的参数,对VGG-16网络,剪枝能减少13倍参数数量。

 

深度学习模型压缩方法(5)-----Deep Compression

 

图 2 网络剪枝示意图

这一步里面还有一个稀疏网络权重表达的技巧,一般来说表达一个稀疏数组是(index, value)这样成对的值来表示,对应于我们的权重数组就是一个index,一个weight,数组比较大,所以index至少得是整型(int)的,一个index需要32个bit,文章巧妙地采用了相对索引来表达(图 3),也就是每次存储原先前后两个index的差值,这个值我们可以用比较小的数据类型来存,比如途中用3bit(0-8),当然差值超过8时要补上一个0,这样index的字节数就得到了压缩。实际上卷积层用8bit(0-255)存的,全连接层用5bit(0-32)存的。

 

深度学习模型压缩方法(5)-----Deep Compression

图 3 用相对索引表达稀疏的权重数组

2-权重共享

如图 4所示,假设我们的权重是4*4的,一共16个浮点数值,我们可以用K均值聚类的方法,把它们按大小的相近程度聚类成4类,也就是图中的4种颜色块。聚成4类后,我们只需要保存4个浮点型的权值就可以了,然后每个点存一个类别index就可以了,这个index也是很小的(4类只需要2bit)。

另一个问题是进行权重共享后,权重如何更新,图 4中下半部分也展示了,就是先还是后项传播时一样计算梯度gradient,然后把同一类别点的梯度累加起来,用这个累加得到的梯度就可以对每个类的权值进行更新了,当然要乘上学习率lr。

深度学习模型压缩方法(5)-----Deep Compression

图 4 权重共享和调节

3-霍夫曼编码

霍夫曼编码是一种常用的无损编码技术,主要的思想是按照符号的概率来进行变长编码,就是出现概率大的符号,我编码短一些,出现概率小的符号编码长一些,这样整体就变小了。

Huffman编码按照符号出现的概率来进行变长编码。下面的权重以及索引分布来自于AlexNet的最后一个全连接层。由图可以看出,其分布是非均匀的,因此我们可以利用Huffman编码来对其进行处理,最终可以使的网络的存储减少20%~30%。 

深度学习模型压缩方法(5)-----Deep Compression

图 5 Alexnet中权值和索引的统计图

最后,看一下图 6,用deep compression的压缩效果,在几种主流网络上都达到了40倍左右的压缩率,而且精度完全没有降低,甚至还提高了一点点。

深度学习模型压缩方法(5)-----Deep Compression

图 6 deep compression 压缩效果