原文链接:https://www.yuque.com/yahei/hey-yahei/quantization-retrain_differentiable
欢迎引用&转载,但烦请注明出处~
在传统的QAT中,训练的只有权重,而量化参数是根据权重的分布所确定的。有研究者就想,为什么不把量化参数也作为训练对象呢?既然量化参数是可训练的,那么它能被求导,也就是可微的,所以我们可以称这类方法为“可微量化参数”。
PACT
论文:《PACT: Parameterized Clipping Activation for Quantized Neural Networks (ICLR2018)》
PArameterized Clipping acTivation(PACT)_——这字母缩写取的还真是奇葩……_
PACT讨论了ReLU激活下,如何直接训练输入数据的截断范围
跟ReLU6有点像,ReLU6用的是一个固定的,而PACT让作为一个可训练参数,直接用目标任务的loss来训练。思路比较简单,求导也不复杂
众所周知,量化时动态范围越小,那么分辨率就越高。为了避免截断范围太大,论文里为引入了L2正则化。并建议,惩罚参数跟权重的惩罚参数保持一致,并且随着量化位宽的增加而减小——直观理解,量化位宽越大,则可以保证有更大的分辨率,那么与之对立的动态范围也应该有更大的增长空间。
QIL
论文:《Learning to Quantize Deep Networks by Optimizing Quantization Intervals with Task Loss (CVPR2019)》
Quantization Interval Learning(QIL)
在PACT的基础上,QIL除了训练输入数据的量化参数外,还训练权重的量化参数,并且使用了带offset的量化,实际操作中用一个区间中心和区间半宽来表示(可以是权重,也可以是输入数据)。
其中,
区间宽度,区间偏移;
是量化的levels,比如有符号数是,无符号数是;
,而
在设计量化时还有一个额外的指数,这是为了扭曲区间上的量化分辨率,当时,数值较大的部分分辨率较小(一个整型值对应更大范围的浮点数区间);当时,数值较小的部分分辨率较小;当相当于均匀分布的量化。
考虑到输入数据需要在推理时实时进行量化,引入指数运算会带来额外的复杂计算;但权重是预先量化好的,所以作者建议只在量化权重时引入。
另外,既可以是人工设置的,也可以是训练出来的,实验证明,将其设为可训练的参数的效果更好。
论文里还提出一种渐进式的量化,这个有点像课程学习,先从简单的任务学起,逐渐增加任务难度。比如先做W5A5的训练,然后继续训练W4A4、W3A3,直到W2A2,实验证明渐进式的量化训练更加稳定,效果更好。
(ResNet18)
LSQ
论文:《Learned Step Size Quantization (ICLR2020)》
Learned Step size Quantization(LSQ),一项来自IBM的工作。
LSQ也同时训练权重和输入数据的量化参数,但不像QIL绕那么多弯子,就直接是最朴素的量化公式
不过LSQ只讨论了不带offset的情况,后续LSQ+会进一步讨论带offset的情况。
直接对量化公式求导
而
故
与PACT和QIL相比,LSQ的梯度更为合理,当v位于量化区间中心时为0,位于左侧时为负数,位于右侧时为正数——训练时会倾向于调整s把v拉到量化区间的中心位置。
作者还指出调整梯度的尺度有助于稳定训练过程,具体来说,就是让量化参数的相对更新幅度与权重的相对更新幅度尽可能接近,也即
并且经验性地给出一个缩放因子来修正,
其中是某一层的权重或输入tensor的数据总量
(不同缩放因子设计下的R值比较)
(ResNet18,2bit)
一些训练细节:
- 训练初始化量化参数;
- 第一层和最后一层只量化到8bit;
- 对于ImageNet数据集,全精度网络训练120epoch,8bit恢复训练1epoch,更小bit恢复训练90epoch;
- 对于ImageNet数据集,8bit恢复训练学习率取全精度网络训练的百分之一,更小比特取十分之一
作者还比较了不同精度下,惩罚因子对结果的影响,并且指出,对于精度越高的网络应采用更重的惩罚(这与QIL的结论相反,不过QIL是同时考虑了量化参数和权重的惩罚)。
(ResNet18)
(明显优于PACT、QIL等其他方法)
(常见分类网络的实验结果,4bit几乎都不掉精度)
(结合知识蒸馏效果更好)
LSQ+
论文:《LSQ+: Improving low-bit quantization through learnable offsets and better initialization (CVPR2020)》
看名字以为是LSQ同一团队的工作,仔细一看发现LSQ+原来是来自高通的工作。
标题说的很清楚,LSQ+主要在偏移和初始化上对LSQ做了若干改进。
首先,LSQ只考虑了ReLU激活函数,而采用无offset的量化方法,这样的方案对于EfficientNet和MixNet等使用Swish激活函数的网络是很不友好的。于是,LSQ+就引入了offset
的偏导求解过程与LSQ类似,这里直接放个结果
简单推一下的偏导
其中
故
而在权重量化参数的初始化上,作者观察到LSQ的初始化数值与训练后的数值相差甚远,所以提出一种新的初始化方式——
(权重的初始化量化参数的数值尺度与训练后的比较)
输入数据的量化参数则用梯度下降法若干次迭代后最小化L2误差来实现。
事实上也不需要局限于论文里的这两种初始化方式,几乎所有后训练量化得到的量化参数都可以拿来作为重训练量化的初始化。
(使用Swish激活函数的网络)
(使用ReLU激活函数的网络)
(不同的初始化方式,EfficientNet-B0)
(偏移量offset的作用,EfficientNet-B0)