Incremental Network Quantization
思想
- 将32位浮点数的权值量化成低精度的权值(2的幂次或者0)
- 低精度是指相邻的两个权值之间还有多少个数。参考刻度尺的精度。
- 量化成2的幂次方之后一方面是作乘法的时候就变成移位操作,另一方面量化成低精度的权值可以通过编码来存储,从而减少模型在嵌入式设备的存储大小。
算法
- 先将预训练好的模型的权值进行分组,第一组是准备进行量化的,第二组是需要重新训练以弥补量化权值带来的精度损失。
- 将第一组进行量化,使第一组的权值量化成(2的幂次方或者0)
- 将量化之后的权值矩阵(包含量化后的第一组已经需要重新训练的第二组)重新训练,更新第二组的权值以此弥补第一组量化后带来的精度损失。
- 重复上述步骤直到所有权值都被量化。
fig1:第一个图中黑色是需要量化的,白色的是需要重新训练的,经过量化和重新训练之后的结果如第三个图所示,绿色的为量化后的结果,灰色的需要进行分组、量化和重新训练的操作。
具体实现
-
分组
- 原始权重模型
{Wl:1<=l<=L} ,其中,l 代表第l 层,它是一个四维张量,N∗C∗H∗W ,N 代表l+1 层的通道数C 代表l 层的通道数,H∗W 代表卷积核的大小,如果是全链接层的话,则权重矩阵为二维的张量。 - 将原始权重矩阵分成
A(1)l (即将量化),A(2)l (需要重新训练的) ,为了进行分组,定义一个二值矩阵(为了更好的实现这个分组算法),当A(1)l⋃A(2)l={Wl(i,j)},A(1)l⋂A(2)l=∅, 同理,Wl(i,j)∈A(1)l,Tl(i,j)=0 Wl(i,j)∈A(2)l,Tl(i,j)=1 - 分组策略,采取修剪激励策略,即具有较大的绝对值的权值更重要,换句话说就是具有较大的绝对值的权值已经奠定了网络的整体精度的基础,较小绝对值的权值是在这个基础上进行修修补补,因此,可以将这些具有较大绝对值的权值划分到即将量化的权值矩阵中,具有较小的绝对值的权值划分到需要重新训练的矩阵中。具体实现要参考github上的代码。
-
量化
- 最终目的是将
Wl 量化成低精度的Wˆl ,其中,Wˆl 的每个元素都来自Pl={±2n1,⋯,±2n2,0} - 将第
n 次分组好的权值矩阵表示为W(n)l=Tl∗W(n−1)l ,然后量化的位宽b ,,这个位宽指的是编码存储权值的位长,实际上这个是指量化后的权值存放在嵌入式上所需要的位宽,并不是指跑完INQ网络后,原来的vgg_caffemodel为537.2M会变小,因为量化后权值在计算机的存储还是双精度浮点型,因此量化后的vgg_caffemodel还是537.2M。 - 定好
b 之后,需要计算n1 ,,以此可以得到n1=floor(log2(4s/3),s=max(abs(Wl)) n2=n1+1−2(b−1)/2 也就是说Pl 定下来了。 - 对第i阶段分好组得权值矩阵进行量化
Wˆ(n)l(i,j)={βsgn(W(n)l(i,j)),3n+1,if (α+β)/2≤abs(W(n)l(i,j)<3β/2otherwise
其中,α 和β 是Pl 排序之后相邻的两个元素。
- 最终目的是将
-
重新训练
-
INQ重训练的目的是将由量化造成的损失降至最低值,用数学式子来表达就是:
minWl=L(Wl)+λR(Wl) s.t.Wl(i,j)∈Pl,ifTl(i,j)=0,1≤l≤L
使用SGD算法更新权值可以表示如下:
Wl(i,j)←Wl(i,j)−γdEdWl(i,j)Tl(i,j) 前面提到当
Wl(i,j) 需要量化的话Tl(i,j)=0 ,否则Tl(i,j)=1 ,因此从上面的式子可以知道权重更新只更新需要重新训练的权值。 -
- 原始权重模型
整体算法
- 输入:训练数据
X ,预训练模型{Wl:1≤l≤L} ,量化权值占的累计比重σn 。 -
输出:量化后的权值矩阵
{Wlˆ:1≤l≤L} ,Wlˆ 中每个数值都为2的幂次方或者0。1.初始化
A(1)l←∅ ,A(2)l←{Wl(i,j)} ,Tl←1 ,for1≤l≤L 。2.
forn=1,2,⋯,N i.设置base learning rate 和 learning policy。
ii.根据
σn 设定需要量化权值的比例更新A(1)l ,A(2)l 以及Tl 。iii.由
A(1)l 和给定的位宽b 得到相应的Pl 。iv. 量化
A(1)l 。v. 计算feed-forward loss ,更新
A(2)l 。
代码解读
- to be continued