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


而要做的事情 , 就是在使用 per-layer 量化的情况下 , 使用一些方法使得不同卷积核之间的数值分布能够均衡一些 , 让大家的数值分布都尽量接近 , 这样就可以用 per-layer 量化实现 per- 的精度 (毕竟 per- 实现上会比 per-layer 复杂一些) 。
高通说他们实现这一步并不需要额外的数据 , 可以优雅地在 Data-Free 的情况下实现 , 这也是他们给论文起名 Data-Free 的缘由 。具体的算法我们后面再说 。
Bias
除了的问题之外 , 研究人员发现 , 模型量化的时候总是会产生一种误差 , 这种误差对数值分布的形态影响不大 , 但却会使整个数值分布发生偏移 () 。
假设有N N N 个样本 , 那么对于map 上面的每一个数值 , 我们可以用下面这种方式计算偏移误差 ( error):

高通Data free quantization保姆级讲解

文章插图
E [ y j ~ ? y j ] ≈ 1 N ( ∑ n ( W ~ x n ) j ? ( W x n ) j ) (1) E[\{y_j}-y_j]\\frac{1}{N}(\sum_n(\{W}x_n)_j-(Wx_n)_j) \tag{1} E[yj???yj?]≈N1?(n∑?(Wxn?)j??(Wxn?)j?)(1)
其中 ,  W ~ \{W} W 是量化后再反量化的(即带了量化误差) ,  W W W 是原先的  ,  x n x_n xn? 是输入 , 对应的y j ~ \{y_j} yj?? 是量化后的输出 ,  y j y_j yj? 是原输出 。
用这个公式可以算出引入量化误差后的map 上每个点和原先的相差了多少 , 统计一下这些误差 , 就得到下面这张图:
这里面蓝色的柱状图就统计了量化后的误差分布 , 看得出 , 有不少的误差已经超过了 1 , 而理想状态下 , 我们是希望量化后的误差能集中到 0 附近 , 越接近 0 越好 , 就像橙色直方图那样 。
其实 , 这种error 不仅仅只有量化的时候会出现 , 在做模型压缩的时候也会遇到 。做过画质类任务模型剪枝的同学可能有这种体验 , 就是当你把一个大模型里面某些卷积的通道数砍掉时 , 会发现模型的输出结果出现一种整体上的色彩变化 。比如 , 我在一个图像去噪的实验中用了剪枝后 , 出现下面这种现象:
模型剪枝后 , 你会发现模型的输出结果和原来相比 , 好像整体的颜色上多了一个偏移 () , 但图像里面的物体基本还能辨识 (数值分布的形态没有发生变化) 。
我自己画了幅简图描述这种现象:
其中红色的分布是原模型的分布 , 而橙色分布就是剪枝后带了error 的分布 , 它的形状大体上和红色分布类似 , 但整体向右发生了一点偏移 , 从而导致整个画面的色彩发生了变化 。一般来说 , 经过后 , 这种现象可以慢慢得到缓解 。
以上是我对error 的一些理解 。
研究人员发现 , 用上后 , 这种error 会更加地突出 。而 Bias就是为了解决该问题提出的 。
具体方法
要实现 , 一个很直接的想法就是对卷积核的每个(或者是全连接层的每个权重通道) 都乘上一个缩放系数 , 对数值范围大的进行缩小 , 范围小的则扩大 。
(伸缩等价)
不过 , 乘上放缩系数的同时不能影响网络的输出 。为了保证计算上的等效性 , 论文利用了卷积层 (包括全连接层) 和 ReLU 这类激活函数的伸缩等价性 () 。
卷积层和全连接层 , 本质上都是加权求和 (线性映射) , 因此都满足下式:
f ( s x ) = s f ( x ) (2) f(sx)=sf(x) \tag{2} f(sx)=sf(x)(2)