模型压缩——量化

量化

int
int8取值范围是-128 - 127(符号位+数值位=8)
Int16 意思是16位整数(16bit integer),相当于short 占2个字节 -32768 ~ 32767
Int32 意思是32位整数(32bit integer), 相当于 int 占4个字节 -2147483648 ~ 2147483647
Int64 意思是64位整数(64bit interger), 相当于 long long 占8个字节 -9223372036854775808 ~ 9223372036854775807
float
一个float单精度浮点数一般是4bytes(32bit)来表示,由三部分组成:符号位、指数部分(表示2的多少次方)和尾数部分(小数点前面是0,尾数部分只表示小数点后的数字)
双精度64位,单精度32位,半精度自然是16位
float32: 单精度浮点数float的这三部分所占的位宽分别为:1,8,23
float16: 半精度浮点数half的这三部分所占的位宽分别为:1,5,10
量化的作用:更小的模型尺寸、更低的功耗、更快的计算速度。下图是不同数据结构比较及执行基本运算时的计算消耗。
float32转为int时都是转为int8的原因是:float32的指数部分位宽为8,截断小数部分后就等于int8;虽然int16占用的字节比float32少,但使用int8就能够表示float32的整数部分,所以float32不转为int16。
定点:指的是小数点的位置是固定的,即小数位数是固定的数。
在量化的实现代码中要做溢出保护,加个clip

对称量化和非对称量化

浮点转到定点: Q = r o u n d ( R S ) + Z Q=round(\frac{R}{S})+Z Q=round(SR)+Z
定点转到浮点: R = ( Q − Z ) ∗ S R=(Q-Z)*S R=(QZ)S
R R R代表真实浮点值, Q Q Q代表量化后的定点值, Z Z Z(Zero)表示0浮点值对应的量化定点值, S S S(Scale)表示定点量化后可表示的最小刻度。
S = R m a x − R m i n Q m a x − Q m i n S=\frac{R_{max}-R_{min}}{Q_{max}-Q_{min}} S=QmaxQminRmaxRmin
R m a x / R m i n R_{max}/R_{min} Rmax/Rmin代表最大/最小的浮点值, Q m a x / Q m i n Q_{max}/Q_{min} Qmax/Qmin代表最大/最小的定点值。
Z = Q m a x − R m a x S Z=Q_{max}-\frac{R_{max}}{S} Z=QmaxSRmax
比如进行int8的量化,数据范围是[-128,127],浮点的最大值最小值分别是 X m a x X_{max} Xmax X m i n X_{min} Xmin X q X_q Xq表示量化后的数据, X f X_f Xf表示浮点数据。
X q = X f S + Z X_q=\frac{X_f}{S}+Z Xq=SXf+Z
S = X m a x − X m i n 127 − ( − 128 ) S=\frac{X_{max}-X_{min}}{127-(-128)} S=127(128)XmaxXmin
Z = 0 − r o u n d ( X m i n S ) Z=0-round(\frac{X_{min}}{S}) Z=0round(SXmin) or Z = 255 − r o u n d ( X m a x S ) Z=255-round(\frac{X_{max}}{S}) Z=255round(SXmax)
round代表四舍五入
量化分为对称量化和非对称量化,上面的是非对称量化,如果是对称量化,则是将原浮点数的范围由 [ X m i n , X m a x ] [X_{min}, X_{max}] [Xmin,Xmax]扩充为 [ − X m a x , X m a x ] [-X_{max}, X_{max}] [Xmax,Xmax],这里假定 ∣ X m a x ∣ > ∣ X m i n ∣ |Xmax|>|Xmin| Xmax>Xmin
对称量化图示:
在这里插入图片描述
非对称量化图示:
在这里插入图片描述
S S S除了上述的公式为还可以采用以下公式:
对称量化: S = 2 n − 1 − 1 m a x ( ∣ x ∣ ) S=\frac{2^{n-1}-1}{max(|x|)} S=max(x)2n11
非对称量化: S = 2 n − 1 − 1 m a x ( x ) − m i n ( x ) S=\frac{2^{n-1}-1}{max(x)-min(x)} S=max(x)min(x)2n11
x x x代表浮点数, n n n代表量化后的位宽,float32量化为int8则n为8。

矩阵量化

假设 R 1 R_1 R1 R 2 R_2 R2是浮点实数上的两个 N × N N\times N N×N的矩阵, R 3 R_3 R3 R 1 R_1 R1 R 2 R_2 R2相乘后的矩阵:
R 3 i , k = ∑ j = 1 N R 1 i , j R 2 j , k R_3^{i,k}=\sum_{j=1}^NR_1^{i,j}R_2^{j,k} R3i,k=j=1NR1i,jR2j,k
假设 S 1 S_1 S1 Z 1 Z_1 Z1 R 1 R_1 R1矩阵对应的 scale 和 zero point, S 2 S_2 S2 Z 2 Z_2 Z2 S 3 S_3 S3 Z 3 Z_3 Z3 同理,那么通过上式可以推出:
S 3 ( Q 3 i , k − Z 3 ) = ∑ j = 1 N S 1 ( Q 1 i , j − Z 2 ) S 2 ( Q 2 j , k − Z 2 ) S_3(Q_3^{i,k}-Z_3)=\sum_{j=1}^NS_1(Q_1^{i,j}-Z_2)S_2(Q_2^{j,k}-Z_2) S3(Q3i,kZ3)=j=1NS1(Q1i,jZ2)S2(Q2j,kZ2)
=> Q 3 i , k = S 1 S 2 S 3 ∑ j = 1 N ( Q 1 i , j − Z 2 ) ( Q 2 j , k − Z 2 ) + Z 3 Q_3^{i,k}=\frac{S_1S_2}{S_3}\sum_{j=1}^N(Q_1^{i,j}-Z_2)(Q_2^{j,k}-Z_2)+Z_3 Q3i,k=S3S1S2j=1N(Q1i,jZ2)(Q2j,kZ2)+Z3
除了 S 1 S 2 S 3 \frac{S_1S_2}{S_3} S3S1S2外都是定点运算,此时设 M = S 1 S 2 S 3 M=\frac{S_1S_2}{S_3} M=S3S1S2, M M M ( 0 , 1 ) (0,1) (0,1)之间(这是通过大量实验统计出来的),因此可以表示成 M = 2 − n M 0 M=2^{-n}M_0 M=2nM0,其中 M 0 M_0 M0是一个定点实数。因此,如果存在 M = 2 − n M 0 M=2^{-n}M_0 M=2nM0,那我们就可以通过 M 0 M_0 M0的 bit 位移操作实现 2 − n M 0 2^{-n}M_0 2nM0,这样整个过程就都在定点上计算了(其实这是由误差的,用这种方法可以得到一个近似的结果)。

卷积网络的量化

在这里插入图片描述
卷积和全连接的本质就是矩阵运算。
假设网络为上图,则这个网络只有三个模块,现在需要把 conv、fc、relu 量化。
假设输入为 x x x,我们可以事先统计样本的最大值和最小值,然后计算出 S x S_x Sx(scale) 和 Z x Z_x Zx (zero point)。
同样地,假设 conv、fc 的参数为 w 1 w_1 w1 w 2 w_2 w2,以及 scale 和 zero point 为 S w 1 S_{w_1} Sw1 Z w 1 Z_{w_1} Zw1 S w 2 S_{w_2} Sw2 Z w 2 Z_{w_2} Zw2 。中间层的 feature map 为 a 1 a_1 a1 a 2 a_2 a2,并且事先统计出它们的 scale 和 zero point 为 S a 1 S_{a_1} Sa1 Z a 1 Z_{a_1} Za1 S a 2 S_{a_2} Sa2 Z a 2 Z_{a_2} Za2
(不考虑bias)
a 1 i , k = ∑ j = 1 N x i , j w 1 j , k a_1^{i,k}=\sum_{j=1}^Nx^{i,j}w_1^{j,k} a1i,k=j=1Nxi,jw1j,k=> Q a 1 i , k = M ∑ j = 1 N ( Q x i , j − Z x ) ( Q w 1 j , k − Z w 1 ) + Z a 1 Q_{a_1}^{i,k}=M\sum_{j=1}^N(Q_x^{i,j}-Z_x)(Q_{w_1}^{j,k}-Z_{w_1})+Z_{a_1} Qa1i,k=Mj=1N(Qxi,jZx)(Qw1j,kZw1)+Za1( M = S w 1 S x S a 1 M=\frac{S_{w_1}S_{x}}{S_{a_1}} M=Sa1Sw1Sx)
得到 conv 的输出后,我们不用反量化回 a 1 a_1 a1,直接用 Q a 1 Q_{a_1} Qa1继续后面的计算即可。
量化后的ReLU的计算公式为 Q a 2 = m a x ( Q a 1 , Z a 1 ) Q_{a_2}=max(Q_{a_1},Z_{a_1}) Qa2=max(Qa1,Za1)
量化后的fc层计算公式为:
Q y i , k = M ∑ j = 1 N ( Q a 2 i , j − Z a 2 ) ( Q w 2 j , k − Z w 2 ) + Z y Q_y^{i,k}=M\sum_{j=1}^N(Q_{a_2}^{i,j}-Z_{a_2})(Q_{w_2}^{j,k}-Z_{w_2})+Z_y Qyi,k=Mj=1N(Qa2i,jZa2)(Qw2j,kZw2)+Zy
然后通过公式 y = S y ( Q y − Z y ) y=S_y(Q_y-Z_y) y=Sy(QyZy)把结果反量化回去,就可以得到近似原来全精度模型的输出了。
可以看到,上面整个流程都是用定点运算实现的。我们在得到全精度的模型后,可以事先统计出 weight 以及中间各个 feature map 的 min、max,并以此计算出 scale 和 zero point,然后把 weight 量化成 int8/int16 型的整数后,整个网络便完成了量化,然后就可以依据上面的流程做量化推理了。
Conv输出的Scale和zero point需要用一些样本去跑一遍,然后统计

后训练量化(post training quantization)

后训练量化指的是,对预训练后的网络选择合适的量化操作和校准操作,以实现量化损失的最小化,该过程不需要训练,通常不直接更新权重原始数值而是选用合适的量化参数
卷积层的量化(带bias):
conv: a = ∑ i N w i x i + b a=\sum_i^Nw_ix_i+b a=iNwixi+b
量化后的Conv: S a ( Q a − Z a ) = ∑ i N S w ( Q w − Z w ) S x ( Q x − Z x ) + S b ( Q b − Z b ) S_a(Q_a-Z_a)=\sum_i^NS_w(Q_w-Z_w)S_x(Q_x-Z_x)+S_b(Q_b-Z_b) Sa(QaZa)=iNSw(QwZw)Sx(QxZx)+Sb(QbZb)
=> Q a = S w S x S a ∑ i N ( Q w − Z w ) ( Q x − Z x ) + S b S a ( Q b − Z b ) + Z a Q_a=\frac{S_wS_x}{S_a}\sum_i^N(Q_w-Z_w)(Q_x-Z_x)+\frac{S_b}{S_a}(Q_b-Z_b)+Z_a Qa=SaSwSx

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值