Quantization and Training of Neural Networks for Efficient Integer-Arithmetic-Only Inference

这篇文章是Google发布的关于神经网络量化方面的文章,文章地址:https://arxiv.org/abs/1712.05877

本博客参考了微信公众号“AI芯片算法”中的原创文章《Google CVPR2018 8bit 量化论文》一文。

1、本文的贡献

本文主要侧重将推断中的浮点数运算量化为整数运算(Integer-Arithmetic-Only),最终将权重和激活函数量化为8-bit,只有一小部分参数(bias)为32-bit整数。另外,本文提出一种新的量化框架,在训练过程中引入伪量化的操作,用于模拟量化过程带来的误差(这一框架在mobilenet等本身比较精简的网络上效果不错)。

2、量化推断

2.1、量化方案

令 q 为实数值 r 量化后的值,有

其中,S 和 Z 为量化参数。 S 为浮点型的scale,Z 为 zero-point。具体的数据结构如下

与传统的一致非对称量化不同,这里是将最小值对应的量化值(zero-point)也做了量化。这样做的原因是为了推断时候做整数乘法累加运算(但偏差会稍微大一些,损失一点精度)。这里,同一层采用相同的量化参数。

2.2、矩阵乘法的整数运算

首先,两个实数矩阵相乘可以表示为

 这里,除了M外,其他都是整数。

因此,需要将“乘以M”这一浮点操作,转化为整数运算和移位运算的合成。

(这里将M0控制在[0.5,1)的范围内,应该是为了更好的表示成int32类型,这个地方一直有点疑惑)。

第二步,缩减公式(4)中的运算次数,将公式(4)转化为公式(7)。

 公式(8)可以用2N^2次假发得到,剩下的运算主要集中在计算公式(9)中(2N^3)

 而uint8的乘法累加运算需要int32来存储,即

第三步,将bias表示为int32,对应的量化参数为

然后将 r_bias = S_1·S_2·q_bias 加到公式(3)的右边,再转化为类似公式(7)的形式。转化后,括号中的运算为int32类型,乘以M可以看作先乘以int32类型的定点数M0,再进行移位操作。最后,将得到的结果截取到[0, 255]区间内,实现uint8类型的输出。需要注意的是,由于后面采用了伪量化操作,因此ReLU的效果已经由clamping(0,255)代替,故而不再需要激活函数。

3、模拟量化训练

一般量化的方法都是先用浮点数训练,然后量化权重。但这种方法对参数冗余的网络很适用,但是对本身比较精简的网络效果不太好。效果不好的原因主要有两点:(1)每一层中的各输出通道对应的权重差距过大(大于100x);(2)outlier weight会降低其他权重的量化精度。

本文提出在前向的时候进行模拟量化的方法。后向传播不变,仍按照浮点型存储数据。在前向传播时,在推断时需要量化的地方,插入伪量化操作。这里需要注意的是,

(1)权重是在与输入进行卷积前进行量化,如果有BN层,需要将BN层的参数在量化前folded into权重中。

(2)activation的量化在激活函数或者bypass(resnet)之后进行。

伪量化操作为

 即先量化,再还原。

3.1、学习量化range

对权重来说,可以令a,b为最小和最大的权重。对activation来说,[a,b]由EMA计算得到。

一般的量化流程(不带BN层)为

 

 3.2、BN层的folding

对于BN层,需要将BN参数考虑进权重,然后再进行量化。

如图

 

4、实验

略,后续有空再补

 

 

 

 

没有更多推荐了,返回首页