为什么需要量化?
我们知道,cnn网络的前向计算瓶颈主要集中在卷积层,而卷积层的实质是大量的浮点数相乘、相加等运算操作,大量的浮点数计算限制了模型在低处理器或移动端等设备中的部署。如果能将浮点运算转换为整形运算,则cnn模型的前向处理速度将达到质的提升。
为什么量化有用?
关于深度神经网络的一个非常有意思的发现是:即使输入中包含大量的噪声,神经网络依然能处理的很好。深度网络的一个神奇特质是它们倾向于很好地应对输入中的高噪声。如果您考虑识别您刚拍摄的照片中的物体,网络必须忽略所有CCD噪音,光照变化以及它与之前看到的训练样例之间的其他非本质差异,并关注重要事项相似之处。这种能力意味着它们似乎将低精度计算视为另一种噪声源,并且即使使用包含较少信息的数字格式仍能产生准确的结果。
如何量化?
由于网络中主要的计算集中在卷积层,这里主要以卷积层的量化为例讲解。
量化需要完成的是将浮点型的输入值和网络参数值分别映射到一定范围内的整型数。假设我们要将网络参数和输入值量化为kbit,即对应的整型数值表述范围为 2 k 2^k 2k个。一种最常用的量化方法就是线性量化,即将一定范围内的浮点型数均匀量化成 2 k 2^k 2k个区间,每个区间对应一个整形数值,如下表为将[-1, 1]范围内的浮点数线性量化为2比特4个区间:
------------------------------
input | output
------------------------------
[-1.0,-0.5) | -2
[-0.5,0) | -1
[0,0.5) | 0
[0.5,1.0] | 1
------------------------------
均匀量化需要明确被量化的浮点型数值的范围,通过对卷积层的输入和参数特性分析发现,这一数值范围其实是可以大致确定的:
- 卷积层输入范围
对于卷积层,其输入为上一层的输出,通常包含两种情况,一种是输入图像,另一种是经过激活函数的前一层卷积结果,所以卷积层的输入值的取值范围通常为非负数,故对应的量化到[0, 2 k 2^k 2k-1]中。
I ∈ [ 0 , + ∞ ] I\in[0,+∞] I∈[0,+∞] ——> I q ∈ { 0 , 1 , 2 , . . . 2 k − 1 } Iq\in\{0,1,2,...2^k-1\} Iq∈{ 0,1,2,...2k−1} - 卷积层参数范围
而通过对常见网络的卷积层参数的可视化发现,卷积层参数基本呈现以0为中心轴,对称分布的状态,且最大值和最小值的绝对值基本接近,如下图所示,因此可以将参数量化到[-( 2 k / 2 2^k/2 2k/2), 2 k / 2 − 1 2^k/2-1 2k/2−1]中。
W ∈ [ − m i n , + m a x ] W\in[-min,+max] W∈[−min,+max] ——> W q ∈ { − ( 2 k / 2 ) , − ( 2 k / 2 ) + 1 , . . . 2 k / 2 − 1 } Wq\in\{-(2^k/2),-(2^k/2)+1,...2^k/2-1\} Wq∈{ −(2k/2),−(2k/2)+1,...2k/2−1}
通过统计大量的网络参数和输入的数值分布,在量化时我们可以确定输入和参数的大致正负边界(如网络参数基本落在[-1,1]区间,输入值基本落在[0,5]之间,对于大多数网络基本满足这一情况),对于落在边界外的少数数值,直接进行截断即可,这带来的噪声值是相对微弱的。
量化公式
我们知道,卷积层的前向计算公式可以表示为输入和卷积层参数的卷积运算,简化为:
O = I ∗ W O=I*W O=I∗W对于量化计算,我们希望找到一组对应的量化值 I q I^q Iq和 W q W^q Wq,使其满足:
O = I ∗ W ≈ α I q ∗ β W q = α β ( I q ∗ W q ) O=I*W≈\alpha I^q*\beta W^q=\alpha \beta (I^q*W^q) O=I∗W≈αIq∗βWq=αβ(Iq∗Wq)上式中, α \alpha α和 β \beta β是浮点型标量系数。
因此浮点型的卷积操作可以退化成对应量化值 I q I^q Iq和 W q W^q Wq的整型卷积操作,大大提升计算的效率。
-
卷积层输入量化
前面已经说过,我们可以采用最简单的线性均匀量化来确定上面所说的量化值,输入 I I I被量化到[0, 2 k 2^k