其他分享
首页 > 其他分享> > QAT:IAO+DoReFa

QAT:IAO+DoReFa

作者:互联网

最近看了两篇早期著名的QAT(Quantization Aware Training)的文章:IAO(Integer-Arithmetic-Only)和DoReFa,统一整理如下:

IAO: https://arxiv.org/pdf/1712.05877.pdf

DoReFa:https://arxiv.org/abs/1606.06160

Background

背景部分其实无需过多介绍,量化早已成为了神经网络部署过程中必不可少的一个步骤,而针对它的算法研究更是层出不穷,例如低比特的INQ,甚至1比特的BNN等。但是在实际工业部署中,最常用的还是8比特的训练后量化算法。对于训练后量化,虽然有对称非对称,截断/边界值拟合等优化思路,但是量化对于原数据分布的破坏依然是无可避免的,也因此一般肯定会造成精度的损失。这时便提出了量化感知训练(QAT)的思路,在训练中变考虑到量化操作所带来的损失,从而使得训练所得的参数天然适应定点数分布,从而消弭量化操作所带来的精度损失。

Method

QAT的核心思想,就是在网络训练过程中,实现一个量化模拟器,从而将量化误差引入到网络训练中。在量化后的定点数推理过程中,所涉及到的量化操作,主要包含两部分,一个是针对weights的量化,另一个是针对每一层输出激活值activation的量化。所以QAT的主要做法就是在forward过程中的每一层中嵌入了针对weights和activation的量化/反量化操作。这里采用了反量化,表明训练中实际所使用的数据还是浮点形式,但每一层的量化误差都已经被引入了网络训练过程中,从而通过梯度下降来最小化该量化误差。

QAT中的量化实现:以一个卷积层的QAT操作为例来说明,如下图所示,输入tensor与weights进行卷积运算,再加上bias,最后经过激活层输出。在QAT中,只需要对weights和activation加入量化操作。表现在代码实现中,需要实现一个Quant_Conv的kernel,本质只是对原始的Conv2d进行一层包装,在forward函数部分卷积操作前后,分别加入对weights和activation的量化即可(在有的实现中,对activation的量化被放在了最前面,这本质上是一致的)。

具体量化操作,则可以有不同的实现方法,以Dorefa中weights的量化为例,如下所示,这是一个对称量化,对weights进行一个tanh的操作首先将数据范围压缩到[-1,1]之间,然后查找边界值,计算缩放因子scale,将数值映射到定点数范围并截断,然后再反量化为伪量化数。对于activation也是类似,但是量化方法上可能会有不同。

其他重点:

Thoughts

由于论文比较早,所以不重点关注实验部分。不过目前的qat也主要是基于该思路,所以实验结果其实很优秀。主要来讨论一些我对qat简单认识所发现的问题和思考:

  1. 在个人实验中,发现qat训练的网络,必须使用所定义的Quant_kernel来运行结果正确,而把它当作正常的float 参数来计算则误差特别大,基本会导致精度掉为0。不明白为什么会有这么大误差,事实上训练过程中也是使用的伪量化数。同时在推理中也必须严格使用qat所生产的量化超参数,如果不同则导致精度极低。

  2. 目前的网络训练和推理过程中,存在很多reparameter的操作,即训练和推理过程中的网络结构有所不同。这意味着使用qat所得到的定点数分布在rep之后可能不再适用。其实bn_fuse就是一种简单的rep的操作。如何针对更复杂更多样的重参数化操作,需要研究。

标签:QAT,IAO,训练,DoReFa,activation,weights,操作,量化
来源: https://blog.csdn.net/li6016265/article/details/120701660