原文链接:https://www.yuque.com/yahei/hey-yahei/shift_quantization

移位量化也可以称为对数量化,将数值从浮点数的形式量化为一个整数或定点数,但它与线性量化不同,两个相邻数之间是在以2为底的对数域上均匀分布的,这使得实际推理当中可以直接通过移位运算来快速实现,同时也拥有随比特数增长而指数增长的大动态范围。
移位量化既可以只量化权重(对**值移位),也可以只量化**(对权重值移位),当然也可以同时量化权重和**(对值1移位)。由于涉及底层的位移运算,可以设计出各种比较花哨的近似位移或并行位移的技巧,这些方案大多更适用于FPGA。
此外,ShiftCNN也采用了一种不完全的移位相加形式来替代乘法,也算是相对折中的一种处理方案。

LogNN

论文:《Convolutional Neural Networks using Logarithmic Data Representation (2016)
移位量化(对数量化)

仅量化**

如图(b),量化**值为整数
x~i=Quantize(log2(xi))\tilde{x}_{i}=Quantize \left(\log _{2}\left(x_{i}\right)\right)
此时与权重之间的乘法计算就可以简化为移位
wTxi=1nwi×2x~i=i=1nBitshift(wi,x~i)\begin{aligned} w^{T} x & \approx \sum_{i=1}^{n} w_{i} \times 2^{\tilde{x}_{i}} \\ &=\sum_{i=1}^{n} \operatorname{Bitshift}\left(w_{i}, \tilde{x}_{i}\right) \end{aligned}


也可以量化为定点数,此时加上一个常量偏移FSRFSR,即x~i,FSR=x~i+FSR\tilde{x}_{i,FSR} = \tilde{x}_{i} + FSR
此时**值需要存储一系列的x~i,FSR\tilde{x}_{i, FSR}和一个共享的FSRFSR

当然,实际量化还要考虑溢出问题,
{x~i=Clip(Quantize(log2(xi)),FSR,FSR+2bitwidth)x~i,FSR=x~i+FSR\begin{cases} \tilde{x}_{i} &= Clip \left( Quantize \left(\log _{2}\left(x_{i}\right)\right), -FSR, -FSR + 2^{bitwidth} \right) \\ \tilde{x}_{i,FSR} &= \tilde{x}_{i} + FSR \end{cases}


再来看看Quantize()Quantize(\cdot)

  1. 最直观:直接向上、向下或四舍五入来取整
  2. 最快(等价向下取整):如图(b),直接取二进制串中最左侧1的位置,比如x=15=0b001111x=15=0b001111量化为x~=3\tilde{x}=3

量化权重和**

权重的量化方式与**相同,此时乘法计算进一步简化为
sn=wTxi=1n2Quantize(log2(wi))+Quantize(log2(xi))=i=1nBitshift(1,w~i+x~i)\begin{aligned} s_n = w^{T} x & \approx \sum_{i=1}^{n} 2^{Quantize \left(\log _{2}\left(w_{i}\right)\right)+ Quantize \left(\log _{2}\left(x_{i}\right)\right)} \\ &=\sum_{i=1}^{n} \operatorname{Bitshift}\left(1, \tilde{w}_{i}+\tilde{x}_{i}\right) \end{aligned}
写作递推式为
sn=sn1+wnxnsn1+Bitshift(1,w~n+x~n)s_n = s_{n-1} + w_n x_n \approx s_{n-1} + \text{Bitshift} (1, \tilde{w}_n + \tilde{x}_n)
p~i=w~ix~i\tilde{p}_i = \tilde{w}_i \tilde{x}_i,则可以推导出对数域的近似累加公式,
s~n=log2snlog2(sn1+2p~n)={log2(1+2p~nlog2(sn1))+log2(sn1), if p~n<s~n1log2(2log2(sn1)p~n+1)+p~n, if p~n>s~n1={log2(1+2p~ns~n1)+s~n1, if p~n<s~n1log2(2s~n1p~n+1)+p~n, if p~n>s~n1={2p~ns~n1+s~n1, if p~n<s~n12s~n1p~n+p~n, if p~n>s~n1(... note that log2(1+z)z if 0<z<1 ...)2s~n1p~n+max(s~n1,p~n)Bitshift(1,s~n1p~n)+max(s~n1,p~n)\begin{aligned} \tilde{s}_n = log_2 s_n &\approx log_2 (s_{n-1} + 2^{ \tilde{p}_n}) \\ &= \begin{cases} log_2(1 + 2^{ \tilde{p}_n - log_2 (s_{n-1})}) + log_2(s_{n-1}), & \text{ if } \tilde{p}_n < \tilde{s}_{n-1} \\ log_2(2^{log_2 (s_{n-1}) - \tilde{p}_n} + 1) + \tilde{p}_n, & \text{ if } \tilde{p}_n > \tilde{s}_{n-1} \end{cases} \\ &= \begin{cases} log_2(1 + 2^{ \tilde{p}_n - \tilde{s}_{n-1}}) + \tilde{s}_{n-1}, & \text{ if } \tilde{p}_n < \tilde{s}_{n-1} \\ log_2(2^{\tilde{s}_{n-1} - \tilde{p}_n} + 1) + \tilde{p}_n, & \text{ if } \tilde{p}_n > \tilde{s}_{n-1} \end{cases} \\ &= \begin{cases} 2^{ \tilde{p}_n - \tilde{s}_{n-1}} + \tilde{s}_{n-1}, & \text{ if } \tilde{p}_n < \tilde{s}_{n-1} \\ 2^{\tilde{s}_{n-1} - \tilde{p}_n} + \tilde{p}_{n}, & \text{ if } \tilde{p}_n > \tilde{s}_{n-1} \end{cases} \\ &(\text{... note that } log_2(1+z) \approx z \text{ if } 0<z<1 \text{ ...}) \\ &\approx 2^{- |\tilde{s}_{n-1} - \tilde{p}_n |} + max(\tilde{s}_{n-1}, \tilde{p}_{n}) \\ &\approx \text{Bitshift} (1, -|\lfloor \tilde{s}_{n-1} \rfloor - \tilde{p}_n|) + max(\tilde{s}_{n-1}, \tilde{p}_{n}) \end{aligned}
在对数域上直接近似累加,比原始的“累加+量化”过程更加高效

ShiftCNN

论文:《ShiftCNN: Generalized Low-Precision Architecture for Inference of Convolutional Neural Networks (2017)

表示形式

为权重设置NN个子码本(codebook),每个码本包含M=2B1M=2^B-1个码字,每个码字位宽BB bits,此时量化后的权重可以如此表示:
w^i=n=1NCn[idxi(n)]Cn={0,±2n+1,±2n+2,±2nM/2+2}\hat{w}_{i}=\sum_{n=1}^{N} \mathcal{C}_{n}\left[\mathrm{idx}_{i}(n)\right] \\ C_n = \{ 0, \pm 2^{-n+1}, \pm2^{-n+2}, \pm 2^{-n - \lfloor M/2 \rfloor +2} \}
其中CnC_nNN个子码本的第nn个;idxi(n)idx_i(n)wiw_i在第nn个子码本上对应的索引;

假设N=2,B=4N=2,B=4,那么码本可以表示为
C1={0,±20,±21,±22,±23,±24,±25,±26}C2={0,±21,±22,±23,±24,±25,±26,±27}C_{1}=\{0, \pm2^0, \pm 2^{-1}, \pm 2^{-2}, \pm 2^{-3}, \pm 2^{-4}, \pm 2^{-5}, \pm 2^{-6} \} \\ C_{2}=\{0, \pm2^{-1}, \pm 2^{-2}, \pm 2^{-3}, \pm 2^{-4}, \pm 2^{-5}, \pm 2^{-6}, \pm 2^{-7} \}
显然,

  • N=1,B=1N=1,B=1且码本不包含0值时,退化为二值量化
  • N=1,B=2N=1,B=2时,退化为三值量化

移位量化(对数量化)

量化方案

移位量化(对数量化)
简单来说,就是先对权重作归一化,然后逐个码本去找误差最小的位移方案,然后保留索引idx

推理细节

本质是用移位替代乘法。
假定乘法y=wxy=wxww 已经被量化为若干2n2^n求和的形式w^\hat{w},那么乘法过程就可以被简化成移位相加的形式。

比如对于N=2N=2的码本有w^=21+22\hat{w}=2^{-1}+2^{-2}
那么乘法y=wxy=wx就优化为y^=(x>>1)+(x>>2)\hat{y}=(x>>1)+(x>>2)

考虑到多码本的情况下可能同一个数值存在多种表示的情况

比如N=2,B=3,w=0.7N=2,B=3,w=0.7
C1={0,±20,±21,±22}C2={0,±21,±22,±23}C_1 = \{ 0, \pm2^0, \pm2^{-1}, \pm2^{-2} \} \\ C_2 = \{ 0, \pm2^{-1}, \pm2^{-2}, \pm2^{-3} \}
那么既可以量化为w^=2022=0.75\hat{w}=2^0 - 2^{-2}=0.75,也可以量化为w^=21+22=0.75\hat{w} = 2^{-1}+2^{-2}=0.75但如果按照前述的算法进行量化,那么只会量化成w^=2022=0.75\hat{w}=2^0 - 2^{-2}=0.75

所以实际上只有P=M+2(N+1)P=M+2(N+1)种不同的码字,那么对于一个输入xx,它只有P1P-1种移位情况(忽略零码);
对于C×H×WC \times H \times W的输入特征图,可能存在的移位组合只有(P1)×C×H×W(P-1) \times C \times H \times W种,也就是说我们可以预设好所有情况,然后通过查表直接并行得到移位结果,直接按元素加和起来作为输出特征图。
移位量化(对数量化)
移位量化(对数量化)

INQ

论文:《Incremental Network Quantization: Towards Lossless CNNs with Low-Precision Weights (ICLR2017)
实现:https://github.com/AojunZhou/Incremental-Network-Quantization
移位量化(对数量化)

量化方案

仅量化权重。
把第ll层卷积的权重WlW_l量化为bb bits的W^l\hat{W}_l,其中1bit用来表示权重值是否为0,另外(b1)(b-1)bits用来存储非零权重的量化结果,其余量化形式与LogNN相类似,记偏移量为NN,那么W^l\hat{W}_l将在如下PlP_l里取值:
Pl={0,±2N,±2N+1,...,±2N+2b2+1}P_l = \{ 0, \pm 2^N, \pm2^{N+1}, ..., \pm 2^{N + 2^{b-2}+1} \}
接下来确定NN
N=log24max(abs(Wl))3N = \lfloor log_2 \frac{4max(abs(W_l))}{3} \rfloor
对于每个权重值,
W^l(i,j)={βsign(Wl(i,j)), if α+β2abs(Wl(i,j))<3β20,otherwise\hat{W}_l (i,j) = \begin{cases} \beta sign(W_l(i,j)), &\text{ if } \frac{\alpha+\beta}{2} \leq abs(W_l(i,j)) < \frac{3\beta}{2} \\ 0, &\text{otherwise} \end{cases}
其中α,β\alpha, \beta是排序好的PlP_l中相邻的两个值 ——(这波量化怎么有点云里雾里)

增量式量化

作者参考增量式裁剪,设计了增量式量化的方案。先对权重取绝对值,取比较大的一批先量化,其他权重值保持浮点数,然后对浮点数权重做恢复训练;如此反复,逐渐扩大量化的范围直到所有权重都完成量化(如50%->75%->87.5%->100%)。
另外按照作者的实验,根据绝对值的尺度来确定哪些权重需要量化效果要比随机挑选的好。
移位量化(对数量化)

DeepShift

论文:《DeepShift: Towards Multiplication-Less Neural Networks (2019)
参考:《把CNN里的乘法全部去掉会怎样?华为提出移动端部署神经网络新方法 | 机器之心
实现:https://github.com/mostafaelhoushi/DeepShift

也不算有很多花样,依旧是对数形式的量化,只量化权重,提出两种形式的训练过程DeepShift-Q和DeepShift-PS,但效果都差不多。但用CUDA在GPU上实现了移位版本的全连接、卷积,算是也有不少工作吧。
移位量化(对数量化)

移位量化(对数量化)

DeepShift-Q

Q指的是Quantization,也即传统的将量化操作纳入训练过程的形式。
S~=Sign(W)P~=Round(log2W)W~=S~2P~\begin{aligned} \tilde{S} &= Sign(W) \\ \tilde{P} &= Round(log_2 |W|) \\ \tilde{W} &= \tilde{S} \cdot 2^{\tilde{P}} \end{aligned}
Round()Round(\cdot)函数的求导依旧是采用STE近似,也即W~W1\frac{\partial \tilde{W}}{\partial W} \approx 1

DeepShift-PS

PS指的是Power、Sign,顾名思义,不再保留浮点数的权重WW,而是直接训练参数SSPP,训练过程中参数SSPP均用浮点数存储,训练完毕后再固定为整数。
S~={+1, if S0.50, if 0.5<S<0.51, if S0.5P~=Round(P)W~=S~2P~\begin{aligned} \tilde{S} &= \begin{cases} +1, & \text{ if } S \geq 0.5 \\ 0, & \text{ if } -0.5 < S < 0.5 \\ -1, & \text{ if } S \leq -0.5 \end{cases} \\ \tilde{P} &= Round(P) \\ \tilde{W} &= \tilde{S} \cdot 2^{\tilde{P}} \end{aligned}
注意使用L2惩罚时,惩罚项应为W2=S24P\sum W^2 = \sum S^2 4^P而不是P2+S2\sum P^2 + \sum S^2

其他

LogQuant:《A Deep Look into Logarithmic Quantization of Model Parameters in Neural Networks (IAIT2018)

相关文章:

  • 2021-12-30
  • 2021-12-13
  • 2021-10-26
  • 2021-08-07
  • 2021-10-13
  • 2021-07-24
  • 2021-10-15
猜你喜欢
  • 2022-12-23
  • 2021-10-28
  • 2021-11-28
  • 2021-09-09
  • 2022-12-23
  • 2022-12-23
相关资源
相似解决方案