量化是一个总括术语,用比32位浮点数更少的空间来存储和运行模型。

1.1 量化动机:
1.减小模型文件的大小

模型文件往往占据很大的磁盘空间,在存储模型的时候用8位整数,模型大小可以缩小为原来32位的25%左右。

2.节省计算资源和功耗

降低预测过程需要的计算资源。这在嵌入式和移动端非常有意义,能够更快地运行模型,功耗更低。

从体系架构的角度来说,8位的访问次数要比32位多,在读取8位整数时只需要32位浮点数的1/4的内存带宽,

例如,在32位内存带宽的情况下,8位整数可以一次访问4个,32位浮点数只能1次访问1个。而且使用SIMD指令,可以在一个时钟周期里实现更多的计算。

另一方面,8位对嵌入式设备的利用更充分,因为很多嵌入式芯片都是8位、16位的,如单片机、数字信号处理器(DSP芯片),8位可以充分利用这些。

1.2 为什么量化有用?
神经网络对于噪声的健壮性很强,因为量化会带来精度损失(这种损失可以认为是一种噪声),并不会危害到整体结果的准确度。对噪声不是很敏感。

深度网络的神奇特性之一是它们倾向于很好地处理输入中的高噪声。

如果您考虑识别刚刚拍摄的照片中的物体,网络必须忽略所有CCD噪音,光线变化以及它与之前看到的训练样例之间的其他非本质区别,并将重点放在重要相反。

这种能力意味着他们似乎将低精度计算看作是噪声的另一个来源,即使数字格式保存的信息较少,仍可产生准确的结果。

1.3 能否用低精度格式来直接训练?
大多数情况下是不能的。因为在训练时,尽管前向传播能够顺利进行,但往往反向传播中需要计算梯度。(8unit 反向传播精度不够,很难收敛)

例如,梯度是0.2,使用浮点数可以很好地表示,而整数就不能很好地表示,这会导致梯度消失。因此需要使用高于8位的值来计算梯度。

1.4 对称量化和非对称量化

tensorflow按如下公式进行8bit 量化:

其中r为需要量化的实数,S为浮点的scale系数,q为量化后的无符号整数(uint8),Z为量化后的零点,也是无符号整数(uint8),当然也可量化成其他位宽的整数。

下面我将详细分析下这种量化方式与传统的量化的差别:

如上所示,主要的差别在于最小值的位移偏差,google的量化方式将位移的最小偏差也做了量化,

可以理解为是以原始0点为基准做的量化,这样还原回去的r偏差会更大一些,

当然这种量化的方式主要是为了在inference的过程中直接使用量化后的值做乘加运算而不必还原回去。