INQ 论文解读:Incremental Network Quantization: Towards Lossless CNNs with Low-Precision Weights
这篇论文是ICLR 2017的一篇量化相关的论文。本文提出了一种渐进式量化的方法( INQ ):先分组量化,然后冻结已量化的部分并训练未量化的部分,重复以上步骤多次直到所有权重都被量化。这种渐进式量化的方法可以把一个预训练的全精度模型近乎无损地压缩成一个低精度的模型,在Alexnet,VGG,ResNet等模型上都表现良好,甚至可以压缩成三值模型,精确度比TWN等方法都要好。
论文原地址:https://arxiv.org/abs/1702.03044v2点我下载论文
更多论文解读欢迎来访我的博客:https://fishercat.top/
对ECCV 2020 ReActNet 的解读:https://fishercat.top/20200829423/
亮点1:量化表征方式 variable-length encoding scheme
一般的量化方法(也就是谷歌的IAO算法)是这样的:
scale=max(abs(W))
α=(2^(bit−1)−1)÷scale
W=round(W×α)÷α
这种量化方式是最简单的对称式量化,其实就是把一段区域上所有的实数点对应到其最近的离散均匀分布的点上。INQ采用的量化方法有所不同,它是把权重映射到指定的正负2的n次幂或者0:
其中:
n1=floor(log2(4scale/3))
n2=n1+1−2^(bit−2)
n2≤n1
映射公式如下:
这样量化我觉得比IAO的方法要灵活,而且是一种非线性的量化。鉴于权重的分布一般是如下图所示的双峰分布:
(借用师姐论文里的图)
这样的非线性量化可以很好地拟合双峰的位置(注意n1的选取)还有类似正态分布的特点(中间多、四周少,利用了幂函数的特点),使得量化后的权重与原权重相似度提高,权重的变化不那么大,有利于之后的重训练恢复精度的进行。缺点就是有点复杂,不够直观(不过这也不能叫缺点叭)。
亮点2:渐进式量化的策略 weight partition, group-wise quantization and re-training
首先,作者阐释了如何选择当前需量化的部分。论文中并没有明确说明选择的策略,只是笼统地说选择的策略是受了剪枝的启发。作者在这里引用了两篇论文:
Learning both weights and connections for efficient neural networks (Han et al., 2015)
Dynamic network surgery for efficient dnns (Guo et al., 2016)
然后,作者解释了为什么在重训练的时候要冻结已量化的部分,只训练未量化的部分。作者先指出得到最终的量化神经网络的本质是一个优化问题:
直接从头训练这个网络是不实际的,一来是浪费时间,我们可以利用全精度的模型,干嘛要从头训练?二来是很多论文都指出量化网络的学习能力没那么强,从头训练无法达到比较优秀的水平。考虑到哪些权重需要被量化是已经确定了的,我们可以通过多次迭代来逐渐量化。因此,以上优化问题等价于下面这个优化问题:
这个优化问题可以用SGD来求解,更新的方法是:
以上内容纯粹是论文凑字数,最重要的是看这个梯度更新。我们可以发现,如果T(i,j)=0,意思是这个权重被量化了,那么这个权重就不需要被更新。所以我们要得到最终的最优化模型,确实只需要梯度更新未量化的权重即可。
总体的算法如下所示:
总的来说就是用与剪枝类似的方法选择可以量化的权重,冻结量化了的权重并重训练未量化的权重,反复以上两步直到所有权重都量化完毕。其实还是很简单的一个idea,但效果很好。
实验结果 EXPERIMENTAL RESULTS
一个字:牛!
详细的训练参数论文中有给出(好像没给学习率),代码也开源了,感兴趣的小伙伴可以复现一下。
原作者的Caffe代码:https://github.com/AojunZhou/Incremental-Network-Quantization
非官方的Pytorch代码:https://github.com/Mxbonn/INQ-pytorch
我自己也写了个,太丑了就不放上来了……
需要注意的地方是部分权重冻结的代码要怎么写。Mxbonn是通过自定义optimizer来实现的,我是在梯度更新前保存需要冻结的权重,梯度更新后再把冻结的权重还原回去(有点ugly)。
附录给了一张5-bit AlexNet model量化后权重分布的表,大家可以参考下: