高通Data free quantization保姆级讲解( 四 )


论文只针对对称量化求解这个函数 , 非对称量化结果也是一样的 。具体求解过程在论文附录里面已经给出了 , 感兴趣的同学可以自行参考 。实在看不懂的话 , 也不用过分纠结 , 毕竟求解一个数学问题是数学家要做的事 , 作为工程师 , 我们要做的是在了解原理的情况下把想法实现 。
这里直接给出最终的答案:
s i = 1 r i ( 1 ) r i ( 1 ) r i ( 2 ) (9) s_i=\frac{1}{r_i^{(1)}}\sqrt{r_i^{(1)}r_i^{(2)}} \tag{9} si?=ri(1)?1?ri(1)?ri(2)??(9)
这就是每个最优的放缩系数了 。
至此 , 两个卷积核的算法可以通过下面的代码实现:
def equalize(weight1, bias1, weight2):# 重排列weight2 = weight2.permute(1, 0, 2, 3)out_channel = weight1.shape[0]for i in range(out_channel):r1 = compute_range(weight1, i)# 计算kernel数值范围r2 = compute_range(weight2, i)s =r1 / sqrt(r1 * r2)weight1[i] = weight1[i] * (1. / s)weight2[i] = weight2[i] * sbias1[i] = bias1[i] * (1. / s)# 调整回之前的数据排布weight2 = weight2.permute(1, 0, 2, 3)return weight1, bias1, weight2
在实际操作中 , 我们会以两个相邻的 conv 为一组 (比如 conv1、conv2 为一组 , conv2、conv3 为一组) , 按顺序逐个计算每一组的缩放系数 , 逐层逐层地做直到结尾 。
另外 , 我们上面的讨论都忽略了卷积里面 bias 的影响 。论文提到 , 如果s < 1 s < 1 s