神經網絡模型量化方法簡介
https://chenrudan.github.io/blog/2018/10/02/networkquantization.html
2018-10-02
本文主要梳理了模型量化算法的一些文章,闡述了每篇文章主要的內核思想和量化過程,整理了一些對這些文章的分析和看法。
【轉載請注明出處】chenrudan.github.io
隨着神經網絡算法的發展,網絡性能雖然越來越強大,但是也耗費了太多的計算資源和內存,為了得到更有效率的網絡以及能部署在移動端,近幾年神經網絡的壓縮算法成了一個研究熱點,主要的網絡壓縮途徑有五種,量化、剪枝、低秩分解、教師-學生網絡、輕量化網絡設計,量化就是將以往用32bit或者64bit表達的浮點數用1bit、2bit占用較少內存空間的形式進行存儲。剪枝的目的是為了去掉一些不重要的神經元、連接、通道等,低秩分解主要是通過各種分解方法用精簡的張量來表達復雜張量,教師-學生網絡間接通過提升小網絡性能來壓縮學生網絡的規模,一般可以與其他壓縮方法同時使用,輕量化網絡設計主要是類似MobileNet這種設計的非常精簡但性能又好的網絡。幾種方法都各有特點,都是值得研究和討論的,本文主要針對量化算法近幾年的發展做一個梳理和歸納,我覺得量化算法有幾個特點,理論簡單,公式少,性能穩定且trick多。
下圖1-4我整理了本文涉及到的文章在各個開源數據集上的性能表現,由於各個文章中對比指標不是完全一致,例如MNIST、Cifar10所用到的基礎網絡不一定一樣,對性能感興趣的可以去對照原文看看。
模型量化主要包括兩個部分,一是針對權重Weight量化,一是針對激活值Activation量化,在一些文章中已經表明了將權重和激活值量化到8bit時就可以等價32bit的性能。在神經網絡中的基本操作就是權重和激活值的卷積、乘加操作,
W∗A
如果將其中一項量化到{-1,1},那么就將乘加操作簡化為了加減操作,如果兩項都量化到{-1,1},乘加操作就簡化為了按位操作,對於硬件計算是非常友好的。
BinnaryConnect
BinnaryConnect[2]是我看到的第一篇歸納出完整量化流程的文章,它提出DNN的前向和反向訓練中用1bit的二值權重替代浮點權重,能夠讓硬件計算將乘法操作簡化成簡單的累加操作,且能大量的減少存儲空間,在MNIST、CIFAR-10、SVHN上接近SOA的性能。
我們知道正是由於神經網絡參數量大,無法直接得到損失函數的最優參數,才采用了梯度下降的方式來逼近最優解,Sgd通過平均權重帶來的梯度來得到一些小的帶噪聲的步長,嘗試更新權重去搜索參數空間,因此這些梯度十分重要,要具有足夠的分辨率,sgd至少需要68bits的精度,大腦突觸的估計精度也是612bits。。如果采用量化權重,就會導致無法對權重直接求導,這種權重可以被看成是帶噪聲的權重。文章認為帶噪聲的權重往往能夠帶來正則化,使得泛化能力更好,類似dropout、dropconnect這種就是對激活值或者權重加入了噪聲,它們表明只有權重的期望值需要是高精度的,添加噪聲往往是有益處的,所以對權重進行量化理論角度是可行的,且在部分文章中發現對梯度隨機取舍能夠提供無偏離散化。
在本文中提出了BinaryConnect,在DNN的前向和反向訓練中用二值權重替代浮點權重,此處的二值權重B取值為{-1,1},文章中提出了兩種量化方法,判別式和隨機式,其中
σ(w)=clip(x+12,0,1)
,公式1通過符號函數直接取浮點權重的符號,公式2根據當前浮點權重求出一個概率,按照這個概率隨機分配正負1。
(1)wb={+1,if w≥ 0; −1,otherwise
(2)wb={+1,with probability p=σ(w); −1,with probability 1-p
完整算法流程如下圖5,C是損失函數,binarize(w)是按照上述公式二值化權重值,clip(w)是截斷權重值,L是層數。前向傳播時,只對權重做二值化,然后逐層求出二值權重得到的激活值,反向傳播時,也是在二值權重上將對每層輸入的導數傳播回來,此時的導數是浮點的,更新參數時,同樣求得的梯度也是浮點的。由於通常求得的梯度數值不是很大但是又非常重要,所以此處參數更新時還是用浮點梯度。由於權重量化時只取符號,浮點權重大於正負1,對結果沒有影響,為了限制浮點權重不會增長過於誇張以及提高正則性,使用了clip函數將浮點權重限制在正負1之間。
圖5 BinnaryConnect算法流程
圖5 BinnaryConnect算法流程
量化網絡如何inference,一是直接用二值權重。二是用浮點權重,權重二值化只用在訓練階段。三是從浮點權重和隨機二值化可以采樣出很多二值網絡,將它們的預測輸出平均一下作為輸出。論文用第三種方法,訓練過程中用隨機二值權重,測試時用浮點權重可以提升性能,證明了論文前面認為的帶噪聲的權重具有一定的正則性。
這篇文章主要貢獻在於將浮點權重量化到1bit,提出了完整的量化權重流程,且從帶噪聲的權重角度來解釋量化權重。
BNN
BNN[3]與BinnaryConnect是同一個作者,也是這個算法的擴展,在前面只將權重量化到了1bit,本文則進一步將激活值也變成1bit,即減少了內存消耗,也將許多乘加操作簡化成了按位操作XNOR-Count,二值化CNN能夠減少60%的硬件時間復雜度,訓練BNN在MNIST、CIFAR-10、SVHN上達到了SOA的性能。
權重和激活值都量化成了{-1,1},量化方式也是按照公式1和2,隨機式在硬件實現上具有一定的難度,為了加快訓練速度,文章中用的是判別式。由於符號函數的梯度都是0,離散神經元的梯度可以通過straight-through estimator[25]來解決,即浮點數的梯度等於量化數的梯度
gr=gq1|r|≤1
,但是如果浮點權重數值過大,一般要舍棄掉這個梯度。
在訓練過程中,需要保存二值權重和浮點權重,在前向后向計算中用二值權重,計算出來的梯度保存成浮點,且更新到浮點權重上。前向傳播時,先對
Wk
做二值化,然后與當前的二值輸入
ak−1b
,相乘得到
sk
,再經過BatchNorm,得到輸出即下一層的輸入
akb
。反向傳播時,對二值激活值的的梯度等於對浮點激活值的梯度,計算對上一層輸入的梯度時用的是二值權重,計算對二值權重的梯度時用的是上一層的二值激活值。在更新梯度時,梯度更新在浮點權重上,並將新一輪的
Wkt+1
限制在-1~1之間。
文章中提出了第一個卷積層參數普遍較少,所以第一個卷積層輸入量化到8bit,后面很多論文也采用同樣的策略。與1bit權重相乘方式如公式3,
xn
代表的是用8bit表示方法第n位的取值。
(3)s=∑n=182n−1(xn⋅wb)
BNN算法主要貢獻在於同時對權重和激活值量化到1bit,不僅從實驗角度證明量化算法的可行,還分析針對低bit如何進行更有效的計算,整理出了同時量化權重和激活值到1bit的算法流程,且針對內部的硬件計算,給出了具體實現,例如Shift-based Batch Normalization、XNOR-Count,最終訓練能減少60%的時間,32倍的存儲空間。
XNOR-Net
這篇文章[15]提出了兩個網絡Binary-Weight-Networks(BWN)和XNOR-Net,BWN只將權重量化為二值,XNOR權重和激活值都是二值,速度快了58x,內存節省32x。當AlexNet壓縮成BWN時,性能與浮點網絡一致。
在對浮點值進行量化時,加入了一個scaling factor,例如權重量化中
W=αB
,
α
是一個浮點實數,所以在BWN中權重取值就是
−α,+α
,所以量化變成了一個優化問題,這個優化問題是公式4,找到最優的
α
使得量化權重與浮點權重之間差距最小。
(4)J(B,α)=||W−αB||2 α∗,B∗=argminα,BJ(B,α)
將公式4對
α
求導再設為0,得到alpha的解析解
α∗=WTB∗n
,其中包含了二值權重B,如果假設B通過符號函數來求解,那么可以推導出
α∗=1n||W||l1
。
XNOR-Net中對激活值也量化
X=βH
,其中H也是{-1,1},
β
是它的尺度系數,卷積包括重復shift操作和點乘,shift指的是filter在輸入圖上進行移動,當輸入輸出都變為二值時,將權重和激活值的尺度系數提取出來之后,卷積可以變成xnor-bitcounting操作。
Cnn訓練分為三個部分,前向傳播、后向傳播、參數更新,在前向后向的計算中使用量化權重,更新時如果直接更新量化權重,那么梯度可能不夠大到改變量化權重的取值,所以還是讓浮點權重進行更新。
XNOR-Net文章主要貢獻在於提出了一個更好的擬合浮點數的方法,即給二值數增加一個尺度因子,而不是簡單的取符號,在alexnet上將權重量化到1bit時能夠達到跟浮點權重一樣的性能。
TWN
前幾篇文章都是將浮點數直接量化到了1bit,TWN[4]則提出將權重量化成2bit,雖然2bit能表達四個數,但是只取了三個數{-1,0,1},在mnist和cifar10數據集上三值權重性能比二值權重好很多,通過2bit表達,可以達到16x到32x的模型壓縮比例。
一般卷積kernel的尺寸是3x3,針對二值權重,表達能力是2^(33)=512種配置,而三值權重3^(33)=19683種配置,所以說三值權重比二值權重的表達能力要高很多。三值權重取值上多了一個0,實際計算中,由於0值處不需要進行相乘累加,對硬件也是十分友好。
量化公式如公式5,也使用到了尺度因子來擬合浮點權重,最小化量化權重TWN和浮點權重FPWN之間的L2距離。
(5)α∗,Wt∗=argminα,WtJ(α,Wt)=||W−αWt||2 s.t. α≥0,Wit∈−1,0,1
優化問題就變成了如何求出
α
和
Wt
,同樣對
α
求梯度且令梯度為0,可以得到
α
的解析解,求出來的
Wt
和
α
是相互關聯的,所以無法直接得出,文章就提出了一種量化方法,首先需要一個閾值
Δ
,這個閾值用來區分浮點權值映射到正負1、0上,如公式6。然后求出的
αΔ∗=1|IΔ|∑i∈Δ|Wi|
。
(6)Wit=+1,:::if::Wi>Δ0,:::if::|Wi|≤Δ−1,:::if::Wi<−Δ
求閾值則無法直接去求解,因此假設權重服從幾個分布來分析這個閾值的求解途徑,例如假設權重服從均勻分布[-a,a],閾值
Δ=1/3∗a
,例如服從高斯分布,閾值
Δ=0.6σ
,所以作者歸納出了一個經驗公式用於求解
Δ∗=0.7n∑i=1n|Wi|
,然后求出對應
α
。訓練網絡的方式與之前的文章一致。
TWN的主要貢獻通過2bit來近似浮點權重,相比於二值權重性能有較明顯的提升,但由於取值也限於正負1和0,對硬件計算沒有額外的負擔。
BWNH
[5]認為量化的過程可以看成一個hash映射,目標就變成了交替優化方法來學習哈希碼。
在之前文章中的量化優化問題都是找到最優的量化數值來擬合浮點數值,本文中考慮的是最小化內積的量化誤差。本文中是將權重量化到1bit,內積指的是權重和激活值之間相乘,也稱為輸入X和權重W的相似性矩陣
S=XTW
,將浮點權重映射到量化權重的哈希函數為
B=g(W)
,哈希函數
X=h(X)
,h是恆等映射函數。
(7)minL(B)=||XTW−XTB||F2:::s.t.B∈{+1,−1}S×N
g(W)=BA
,A是對角矩陣,每個元素是一個scaling factor,所以目標函數也可以寫成
minL(A,B)=∑iN||Si−αi⋅XTBi||F2
,計算每個
α
、輸入、二值權重之間的乘積來擬合浮點權重與輸入乘積,要求的是哈希映射g,將浮點權重映射到正負1、0這樣的hash code上。
此處對A和B求梯度設為0,可以推導出帶有輸入數據關於
α
和B的求解公式8,在更新A時將B固定不動,更新B時固定A不動,且更新每一個B時還要固定剩下的B,即通過這種交替優化的方式來進行更新。且由於二值權重的量化error是網絡層與層從頭到尾一直在累加的,因而考慮分層量化,例如先對前l個層做二值化,讓整個網絡逐漸的適應二值權重,再去量化第二個部分。
(8)αi=SiTXTBi||XTBi||F2 b=sign(qj−Bi‘TZ‘v)
在具體算法流程中,逐層的對每一層的權值做二值化,每一層量化時初始化時B取浮點權重的符號,而A取權重平均絕對值,接着就按照公式8進行交替的優化A和B。最后再對整個網絡進行finetuing。
BWNH只對權重進行了量化,算法主要貢獻在於從哈希角度來解決量化問題,並且提出了逐層的交替更新,相對於之前的二值權重量化方法性能有着較為明顯的提升。
FFN
FFN[16]中只將浮點權重量化到2bit,通過定點化分解方式來求解量化后權重,由於三值權重只有正負1和0,即可以消除最耗費資源的multiply-accumulate operations(MAC)操作,FFN可以得到浮點網絡性能相當的網絡,且乘法運算僅為浮點網絡的千分之一。
通過semidiscrete decomposition(SDD)半離散分解將浮點權重W分解成定點化方式
W=XDYT
,中D是一個非負對角矩陣,X和Y每個元素取值為{-1,0,1},所以一個正常的卷積n*c*h*w會被分解成三個步驟,卷積有n個輸出channel,拆成三個后,第一個可看成有k個輸出channel的卷積,即k*c*h*w,第二個步驟相當於每個特征圖都乘以一個尺度因子,最后一個也可以看成卷積層大小是n*1*1*k。
圖6 FFN分解
圖6 FFN分解
為了更好的恢復浮點權重,算法中保留了X和Y對應的浮點數值
X^
和
Y^
,且浮點數值被限制在-1.5~1.5,根據取值落在哪個區間量化到哪個數值,而在梯度更新時,更新的對象是
X^
和
Y^
。
FFN只針對權重做了量化,提出了將浮點權重矩陣用矩陣分解的方式分解成三個簡單矩陣,其中兩個矩陣元素取值為正負1和0,從而間接完成量化的功能。
INQ
INQ[17]提出增量網絡量化方法,通過權重分組、按組量化、重新訓練三個操作將浮點網絡量化到低bit網絡,在resnet18上量化權重后,4bit、3bit、2bit能夠達到甚至超過浮點權重。
文章從網絡剪枝算法中得到靈感,逐步的從已經訓練好的網絡中移除掉不那么重要的權重,最終性能也不會有明顯下降,所以說權重是存在不同的重要性的,但是之前的方法沒有考慮到這點,而是同時將高精度浮點數轉化為低精度數值,因此改變網絡權重的重要性對於減少量化網絡的損失很重要。
本文中低bit權重需要一個符號位,至少從2bit開始,b是比特數,取值范圍是
Pl=±2n1,…,±2n2,0
,由兩個整數n1n2定義
n2=n1+1−2b−12
,通過經驗公式可以計算出n1n2。量化公式9中的
α
和
β
就是
Pl
中相鄰的兩項。
(9)Wl^(i,j)=βsgn(Wl(i,j))::::if(α+β)/2≤abs(Wl(i,j))<3β/2 0,otherwise
網絡訓練過程中,將權重分割到兩個不相交的組中,第一個組
Al(1)
中的權重基於公式4進行組內量化,另一個組$A_l^{(2)}中權重保持浮點精度,自適應的彌補量化模型造成的loss,且在反向re-training更新權重時,通過一個mask來判斷屬於哪個組,屬於第一個組的量化權重就不更新,只更新第二個組的浮點權重。然后針對第二個組的浮點權重做重復的三步操作,直到所有權重被量化完成。
圖7 INQ算法
圖7 INQ算法
INQ算法對權重進行了量化,通過逐步增量式的將權重量化,通過保留一部分浮點權重來恢復模型的性能,精度損失得到了一定的遏止。
SQ-B(T)WN
SQ-B(T)WN[6]也是一種增量式量化算法,它從不同權重會導致不同量化誤差角度,在近似實數權重時,可能只是針對部分filter量化error大,部分filter量化error小,文章提出了隨機選擇部分filter量化STOCHASTIC QUANTIZATION,逐漸增加量化比例最終完成全部權重量化。
一層的權重按照輸出channel作為一組數據
W=W1,…,Wm
,其中m等於輸出channel數量,第i個filter權重是
Wi
。也是將這一層的權重划分成兩個不相交的集合
Gq
和
Gr
,將
Gq
中權重量化到低bit,而
Gr
權重還是浮點,
Gq
有
Nq=r∗m
個filter,而
Gq
有
Nq=(1−r)∗m
個。其中r就是隨機量化SQ比例,r在逐漸增加,最終增加到1。
針對每一個filter
Wi
都有自己的一個量化概率
pi
,表明第i個filter被量化的概率,量化概率的取值由量化誤差決定。當量化誤差小時,量化當前的這個channel就會造成較少不同的信息損失,那么就能給這個channel賦予較大的量化概率。首先定義浮點權重和量化權重的L1距離
ei=||Wi−Qi||1||Wi||1
,將它作為量化誤差,並定義一個中間變量
fi=1ei+ϵ
,從而量化概率可以有不同的求解方法,例如
pi=1/m
或者
pi=11+exp(−fi)
。
圖8 隨機channel量化
圖8 隨機channel量化
在圖8中,先計算出4個channel的量化error,假設當前r=50%,根據每個channel計算出來的量化概率挑選2個channel量化。
SQ-B(T)WN算法通過逐步量化權重,比直接全部量化產生的更加合適梯度方向,但是從算法結果上來說,看起來並不是特別好。
Deep Compression
Deep Compression算法[7]結合了剪枝、量化、哈夫曼編碼三種操作,在性能沒有降低的情況下壓縮了35x~49x,目標是減少存儲空間減少inference的耗時,從而能部署在移動設備上。
第一步是剪枝,在訓練過程中來學習各個連接的性能表現,然后裁剪掉權重較小不夠重要的連接,通過設定一個閾值,小於這個閾值移除掉,再重新訓練留下的稀疏連接。剪枝后的稀疏結構用compressed sparse row和compressed sparse row方式存儲,需要保存2a+n+1數據,a是非零值元素個數,n是行數或者列數。這一步中可以在Alexnet和VGG-16上壓縮9x~13x。
第二步是量化,通過讓多個連接共享相同權重來達到量化目的,在有限的bit數中只能表達有限的數值,所以當某些神經元取一樣的數值時,就說它們在共享這個權重。假設權重大小是4*4,權重被量化到4個bin,在相同bin中的權重取值相同,因此只需要保存bin的索引,更新的時候相同bin中的梯度加起來再更新。假如有k個bin,那么需要log2k位來對索引進行編碼,假如網絡有n個連接,每個連接由b個位表達,從而可以得到壓縮比例
r=nbnlog2(k)+kb
。通過k-means聚類來確定這些用於共享的權重,將n個權值分配到k個類中,最小化權重和類中心絕對值之差(WCSS)得到類中心
C=c1,…,ck
。嘗試了三種初始化共享權重中心C的方法,隨機、基於密度、線性初始化,隨機方法就從權重中隨機選擇k個值,基於密度會選擇一些在尖峰周圍的點,線性初始化在權重數值線性進行間隔選擇,發現線性初始化效果最好。反向傳播也跟其他量化方式是一致的。
huffman編碼是一種無損數據壓縮方法,壓縮非均勻分布的值可節省20%30%的網絡存儲。最終經過這三個操作,網絡在性能沒有降低的情況下被壓縮了35x49x。
這篇文章操作較多比較復雜,但是性能是穩定可靠的,每個壓縮操作都沒有導致性能下降。
TTQ
TTQ[8]量化浮點權重到三值權重,在開源數據集上相比浮點性能下降很少。
在之前的量化算法中,是通過一個尺度因子和三值權重相乘來擬合浮點權重,像在TWN中給出了經驗公式來計算尺度因子
α
,本文提出了通過梯度下降對
α
進行更新。
首先將浮點權重除以最大值后正則化到正負1之間,所有的層有一個相同的參數t,用來計算閾值
Δl=t×max(|w~|)
進行量化。
(10)wlt=Wlp:w~l>Δl 0:|w~l|<Δl −Wln:w~l<−Δl
這里針對正負數有不同的量化levels,即有兩個尺度因子
Wlp
和
Wln
。因此對它們計算梯度可以得到梯度下降更新公式,
∂L∂Wlp=∑i∈Ilp∂L∂wlt(i),∂L∂Wln=∑i∈Iln∂L∂wlt(i)
。在觀察尺度因子的變化情況時,針對第一個量化全局層,正負尺度因子的絕對值會變得越來越小,稀疏性降低了,針對最后一個卷積層和全連接層正負尺度因子的絕對值會變得越來越大,稀疏性提升了。
對尺度因子進行訓練的好處在於,正負尺度因子的不對稱使得模型能力更強,且針對所有層有一個常數稀疏r,調整超參數r可以調整量化閾值,能夠獲得不同稀疏度的三值網絡。
TTQ中將正負量化levels分開考慮,且作為可訓練的參數進行更新,而不是用經驗公式進行計算,性能比TWN也要好一些。
DoReFa-Net
在DoReFa-Net[9]中權重、激活值和參數梯度都設置成了低bit,優點是不只在inference時能夠加速,且訓練時由於梯度也被量化了,訓練時也能加速。所以能夠很好的在硬件平台上直接進行訓練。
當權重和激活值都量化后,就能夠用bitcount操作來計算,即x和y相與的結果后可以直接數出位置為1的個數,而之前的文章中還沒有量化過梯度到8bit以下。在BNN網絡中,浮點梯度在-1到1范圍內時等於量化梯度,超出范圍就等於0,在xnor-net中,浮點梯度直接等於量化梯度,由於加上了一個尺度因子,所以權重能夠表示的范圍就更廣了,在DoReFa-Net中權重量化方式為
ro=fwk(ri)=2quantizek(tanh(ri)2max(|tanh(ri)|)+12)−1
,其中k是指定的bit數,
fwk(ri)
取值被限制在了-1~1之間。
激活值的量化先是由一個激活函數將范圍限制在0~1之內,再量化到k bit,
fak(r)=quantizek(r)
。
在針對梯度進行量化時,隨機量化是一個比較有效的手段,且梯度是不像激活值可以被限制在某個范圍內,有的位置上梯度取值可能會比較大,激活值由於可以經過一個激活函數,所以能夠限制數值大小。梯度量化公式為
fγk(dr)=2max0(|dr|)[quantizek[dr2max0(|dr|)+12+N(k)]−12]
,本文的隨機就體現在加入了一個額外的噪聲函數
N(k)
,效果非常明顯。
所以DoReFa-Net並不是指定量化到多少bit,而是可以量化到任意的bit,由於整個網絡的輸入數據層channel較少,對於整體網絡復雜度影響較小,因此第一個卷積層的權重不進行量化,第一個卷積層的輸出激活值會被量化,如果輸出類別較少時,最后一個卷積層的權重也不進行量化,最后一層的反向梯度需要量化。
這篇文章主要就是提出對梯度也進行量化,並且支持量化到任意bit。
ABC-Net
二值權重和激活值能夠很大程度的減少內存空間,且能采用按位計算,對硬件很友好,但是現有的方法會導致性能下降,本文主要提出了ABC-net(Accurate-Binary Convolutional)線性組合多個二值權重基來擬合浮點權重,利用多個二值激活值基組合來減少信息損失。
將浮點權重用M組二值權重和尺度因子進行線性組合,
W≈α1B1+α2B2+…+αMBM
,將B表示成浮點權重與均值和方差的組合形式
Bi=Fui(W):=sign(W−mean(W)+uistd(W))
,其中有一個尺度變量
ui
,既可以由經驗公式
ui=−1+(i−1)2M−1
直接算出,也可以通過網絡訓練的方式得到。這樣去估計B的原因是,浮點權重傾向於是一個對稱、非稀疏分布,比較類似高斯分布,所以用均值和方差來估計。確定B之后,通過線性回歸來求解alpha。在增加了尺度因子后,求解反向梯度時,會增加一個
α
系數,
∂c∂W=∑m=1Mαm∂c∂Bm
。在實現中,將浮點權重按照channel區分開,用同樣的方式來估計尺度因子和二值權重,理論上能夠更加細致的擬合浮點權重。
當權重是二值的,卷積操作就沒有了乘法,只剩下加減,如果想要更高效的利用按位操作,最好是將激活值也變為二值。因此類似對權重的處理,文章首先將激活值通過一個clip函數
hv(x)=clip(x+v,0,1)
,將范圍限制在0~1之間,量化激活值取值是{-1,1},通過一個指示函數
A=Hv(R):=2Ihv(R)≥0.5−1
進行量化,量化激活值與量化權重的不同點在於,inference的階段權重是不變的,激活值則變化了,但是通過利用神經網絡激活值的統計特性能夠避免這個問題,為了保證激活值的分布相對穩定,使用了batchnorm,它能夠讓輸出保持0均值1方差的分布。用N組二值激活值和尺度因子組合成浮點激活值
R≈β1A1+β2A2+…+βNAN
,激活值量化中多了一個可以訓練的閾值
v
。卷積操作就轉化M*N個按位操作,
Conv(W,R)≈∑m=1M∑n=1NαmβnConv(Bm,An)
。
ABC-Net也是一個不限制bit數的量化算法,性能也接近浮點網絡。
HWGQ
HWGQ[11]主要針對激活值量化,利用了激活值的統計特性和batchnorm操作,在前向計算時能有效的近似浮點值的性能。
針對激活值的量化需要處理不可微的操作,主要切入點在於ReLU函數,神經網絡每個單元都計算了一個激活函數,即權重與輸入相乘后經過一個非線性變換,這個操作的多少決定了整個網絡的復雜度。
本文中估計1bit量化權重,也是基於二值權重和尺度因子相乘去擬合浮點權重,輸入I與量化權重卷積來近似I和浮點權重卷積結果,是二值權重取浮點權重的符號
B∗=sign(W)
,尺度因子是浮點權重平均絕對值
α∗=1cwh||W||1
,1bit權重能夠減少存儲空間,但是無法完全計算復雜度的問題,如果將I也變成二值的,則能夠最大程度上解決計算復雜度的問題。
在對激活值進行量化時,如果直接按照符號函數來定義量化levels,那么對量化激活值進行求導時,導數處處為0,所以有人提出,對符號函數求導如果輸入絕對值小於1則梯度為1,其他位置取0。結合relu函數,本文對激活值量化的目標是擬合relu函數的輸出。quantizer是一個分段常數函數,量化levels就是量化到的值,量化step就是兩個量化level之間的差,針對每個浮點數值,它只需要保存一個索引值i,對應到第i個量化level,非均勻量化情況下表達浮點權重需要多余
log2m
的bit數,如果是均勻量化則
log2m
個bit就夠了。激活值的統計結構傾向於對稱非稀疏分布類似高斯分布,再結合relu,就是變成了一個半波高斯量化子half-wave Gaussian quantizer。這里的量化就是變成了求針對高斯分布的量化levels和step,但是在不同層的神經元所得到的類高斯分布,它們的均值方差不一定是相同的,為了得到相同的數據分布,通過batchnorm來得到0均值1方差的分布,然后就能在神經元之間得到均勻的量化參數。以上是在解釋構造這樣的HWGQ,它是階梯常數函數,梯度處處為0,目標就變成了選哪個函數作為HWGQ在量化后才能最好的擬合relu函數的效果。
首先考慮最基本的relu函數,它對輸入的梯度等於輸出梯度,與正向的HWGQ所需要的梯度是不匹配的,特別是當輸入數值大於最大的量化level時,產生的誤差導致的反向梯度就會特別大。基於這個情況,考慮用clipped后的relu,保證最大值不超過最大的量化level,但是由於clipped的操作,丟失掉了
qm
之后的輸入信息會直接導致性能的下降,因此提出一種折中的函數公式11即長尾relu,它既能保證超過
qm
的梯度不會過大,也不會完全丟失掉大於
qm
的信息。
(11)Ql~(x)=qm+log(x−τ),x>qm x,x∈(0,qm] 0,x≤0
HWGQ主要從理論上分析如何去選擇一個激活函數,從而保證激活值量化后低bit網絡性能接近浮點網絡。
Network Sketching
本文提出了Network Sketching[19]用來尋找量化二值權重的網絡,整個過程可以看成是由粗到細的模型近似。
按照輸出channel來划分不同的filter,假設有m組基來擬合一個channel的權重,
W=∑m=0m−1αjBj
,其中
B∈{+1,−1}c×w×h×m
,而
α∈Rm
。主要想法是基於不斷擬合量化權重和浮點權重之間的殘差,即計算浮點權重減去已經累加得到的量化權重
∑k=0j−1αkBk
之間的殘差成為新的需要擬合的浮點權重,去獲得下一步的B和
α
,即公式12。
(12)Wj^=W−∑k=0j−1αkBk
具體在求B和
α
,B是取浮點權重的符號,
α
由二值權重和浮點權重內積求出來
αj=<Bj,Wj^>t
,其中
t=c×w×h
。在第一個Direct Approximation算法中就是重復m次,求出m組B和
α
。重構error以1/t的指數進行衰減,如果t取值小,重構error就會越小,t很大時,重構error的減少幅度就會很慢,就算增加m的數量,最終的近似效果可能也不夠好。所以B和
α
不一定是最優的,為了進一步優化得到更好的近似效果,在第二個Approximation with Refinement算法中給出更新公式,
aj=(BjTBj)−1BjT⋅vec(W)
,且文中進一步證明了更新公式能夠近似浮點權重,減少量化error。
本文的sketch就體現在第j個量化權重是在估計當前浮點權重的殘差,量化error越來越精細,就像在逐步的從粗到細描繪出具體的輪廓。
PQ+TS+Guided
本文[20]為了提升量化網絡訓練性能,提出了三個方法,一是兩步優化策略,先量化權重再量化激活值,其次在訓練過程中逐步減少量化位寬,第三聯合訓練浮點網絡和低精度網絡。
量化采用的是Q函數均勻量化,
zq=Q(zr)=12k−1round((2k−1)zr)
,在量化權重時,先對w做歸一化,其中tanh可以減少大值的影響,再用Q函數去量化,求解形式與DoReFa-Net是一樣的。針對激活值,先將激活值通過clip函數限制在0~1的范圍內,然后用Q量化。反向傳播更新梯度也是基於STE算法。
為了增加量化的准確性,本文首先提出了兩步優化two-stage optimization(TS),先量化權重再量化激活值,如果從K-bit的網絡量化得到k-bit的網絡,首先訓練在K-bit激活值下的k-bit權重,在k-bit權重訓練好后訓練k-bit的激活值。而由於訓練過程中近似的梯度不一定是准確的,所以會導致陷入局部最優值的情況,所以本文提出了分階段量化progressive quantization(PQ)的想法,逐步減少量化位寬的方法,例如32bit->16bit->4bit->2bit,量化n次就得完整訓練n次。第三個提升方法是基於教師-學生網絡(Guided),聯合訓練浮點網絡和低精度網絡,互相適應,因為直接用固定的預訓練好的浮點模型來指導量化網絡不一定最好,且在特征圖層面上進行遷移,為了保持浮點網絡和低精度網絡一致,在相互適應時,將浮點網絡也做同樣的量化,然后再相互遷移。
圖9 Guided訓練
圖9 Guided訓練
這個方法主要是提出一些有效的trick來輔助訓練量化網絡,且表現非常不錯。
SYQ
SYQ[21]提出了對稱量化能夠提升網絡准確率。
在SYQ中,Codebook C是量化levels的一些可能取值,例如{-1,1},或者{-1,0,1},二值化或者三值化權重時通常的方法是采用分段常數函數,並存在
η
這樣的量化閾值超參數,二值化時取為0,三值時由經驗公式
η=0.05×max(|Wl|)
得出。后來的估計方式中引入了scaling factor,提高了近似浮點數的能力,此時的codebook就變成了
−α,α
,前面提到過的TTQ就是提出可以對
α
進行訓練,且設置正負兩個尺度因子
−αln,αlp
,但是如果采用正負不同的尺度因子,那么在計算權重和激活值乘積時需要先去判斷當前二值權重或者三值權重的符號,增加了額外的判斷分支,所以本文認為對稱的codebook計算效率會更高,codebook最好是在0周圍對稱,那存儲空間可減半。
很多細粒度量化方法能夠提升近似權重分布的能力,本文實現了按像素進行縮放,假設一層權重是
K×K×N×I
,pixel-wise就是在I*N維度上將權重進行分組,此時
α
個數為
K2
,此時就是將權重分為了
K2
組,row-wise將一個kernel中行或者列組成一組,最粗粒度的是layer-wise,一層只有一個
α
。
在SYQ算法流程中,每一層首先通過
Ql=sign(Wl)⨀Ml
量化權重成二值或者三值,其中
Ml
是通過
η
計算得到,然后通過
G(x)=12ffloor((2f)x+12)
線性量化激活值,前向計算完成之后,通過
∂E∂Wli,j=αli∂E∂Qli,j
來更新權重,通過
∂E∂x=∂E∂G
更新激活值,通過
∂E∂αli=∑j∈Sli∂E∂Wli,j
更新scaling factor。
SYQ相對於TTQ沒有特別明顯的改進,增加了
α
的數量使得最終性能想比於TTQ有提升。
TSQ
之前方法中都是同時量化權重和激活值,TSQ[12]提出了先量化激活值再量化權重,針對激活值,提出了稀疏量化方法,文章認為網絡壓縮和加速中稀疏能起到很大作用,之前的文章中都很少研究這個方向,且稀疏性在特殊硬件上會更有效,而權重量化可以看成低bit非線性最小二乘回歸問題,通過迭代方式求解。
得到低比特權重是transformations,得到低比特激活值是encodings。在encodings問題中,Relu函數本身就產生了50%的稀疏性,在attention機制的基本假設中,數值較大的激活值比數值較少的激活值更重要。所以將數值較小的正值變成0,這樣量化算法能夠更能關注到較大的數值,量化的會更精細。n-bit均勻量化子quantizer將浮點激活值映射到
2n
個離散值,主要就是在於決定量化間隔
Δ
和量化范圍
ti
。之前的HWGQ方法中是通過batchnorm層,輸出分布就非常趨近於0均值1方差的高斯分布,因此每個層的
Δ
和
ti
是相同的。本文提出稀疏量化,不是將經過relu后的所有正值都進行量化,而是將不重要的數值先設置為0再量化,這個想法之前在網絡剪枝中也有類似研究,也就是大值比小值更重要。所以給出了一個稀疏閾值
ϵ
,得到新的求解激活值量化函數的公式13。
(13)Qϵ∗(x)=argmaxQϵEx∼N(0,1),x>ϵ[(Qϵ(x)−x)2]
對權重進行量化,假設上一層的輸出是X,這一層的輸出是Y,將權重量化的問題變成一個非線性最小平方回歸問題,將浮點尺度因子
α
看成一個對角矩陣,與輸入X相乘之后再經過激活值量化最終去擬合浮點輸出
minimizeα,w^||y−Qϵ(αXTw^)||
。然后引入了一個輔助變量z,將兩個量化過程區分開
minimizeα,w^,z||y−Qϵ(z)||+λ||z−αXTw^||
,權重量化去擬合輔助變量z,激活值量化去擬合浮點輸出。
在求解
α
和w時,將優化問題展開之后,對
α
進行求導且設置導數為0,可以直接得出
α
的求解公式,然后將
α
帶入展開公式同樣求出w的求解公式。由於w的維數較高,即m個像素點每個都需要進行計算,而每個可能取值又是2^n個bit,所以如果用窮舉法來找到最優的w是不可行的,還是在求解一個w時,固定剩下的w不變。在求z時,此時
α
和w是確定的,且此處將激活值量化函數條件放寬,在0~M范圍內的數值就不進行量化,所以針對不同分布得到了z的求解方式。
對權重量化時,層與層之間可以同時進行,沒有耦合關系,但是獨立進行量化時,量化誤差會在層與層之間累加,所以還是考慮通過按層量化。
TSQ通過稀疏量化激活值和引入一個中間變量z來產生新的量化方法,在alexnet上將權重激活值都量化到2bit時性能與浮點也是一致的。
LQ-Net
LQ-Net[13]目的是希望學習量化任意bit權重和激活值的quantizers,現有的量化方法都是一種人工設計的quantizers,例如均勻量化、對數量化,或者在網絡訓練之時已經計算好的quantizers(HGWQ),如果針對不同的網絡能自適應的學到不同quantizers,性能應該會有所提升,所以本文就想聯合訓練一個量化的DNN網絡和對應的quantizers。
ql
是量化levels,量化intervals指的是
tl
到
tl+1
,浮點值在
tl
到
tl+1
范圍內的會被量化到
ql
,均勻量化就是指每個
tl
到
tl+1
的范圍都是相同的,對數量化是
tl
到
tl+1
的范圍成指數關系,量化到n-bit,就有32/n或者64/n倍的壓縮比例。但是由於每個卷積層的數據分布的不同,均勻量化不一定是最優的,預先設置好的量化方式也不一定是最優的,所以考慮既訓練整個量化網絡,也訓練量化函數。如果量化函數是可以訓練的,那么它不僅能夠減少量化誤差,也能適應整體的訓練目標提升最終性能。
假設網絡被量化到K-bit,一個整數q可以通過一個k維的basis系數向量v和k個bit的二值編碼向量
el
點積表達,如公式14所示,此處的系數向量取值為整數。
(14)q=<[1 2… 2K−1],[b1b2 … bK]>
由於二值編碼向量
el
里面每個元素取值都是0和1,當k確定之后
el
所有取值可能都可以確定,例如K=2,
el
所有可能為{(-1,-1),(-1,1),(1,-1),(1,1)}。v是一個可學習的浮點basis系數向量,v值確定之后和每一組可能的二值編碼向量相乘
ql=vTel
,得到了一系列的量化levels,量化intervals就是兩個level之間的均值。
對權重和激活值都進行相同的量化操作,卷積就變成了
Qours(w,vw)TQours(a,va)=∑i=1Kw∑j=1Kaviwvja(biw⊙bja)
,其中有兩組要學習的參數,分別是
vw
和
va
,同一層的激活值量化共用一個
va
向量,一層權重對應每個輸出channel用一個
vw
向量。
在量化和更新過程中,在訓練開始之前通過一個經驗公式求出初始的v,然后先固定v更新B,此時v是已知的,可以直接計算出所有levels,對比浮點數x落在哪個區間就量化到對應的B。然后固定B更新v,通過最小化量化誤差
argmaxv,B||BTv−x||22
對v求閉式解
v∗=(BBT)−1Bx
來更新當前的v。
LQ-Net算法通過學習得到量化levels,而不是人為設計的quantizers,可以量化到任意的bit,在幾個開源數據集上都有非常不錯的性能表現。
小結
寫到后面,感覺意識有點模糊了,到現在我已經工作了一年多了,今年開始在做模型量化方面的工作,因為需要保護公司的利益,不可能在文章中聊工作的事情,所以只能分享了幾篇個人覺得做這個方向需要了解的一些文章,如果有不足的地方,希望大家批評指正,謝謝了。
[**鼓勵一下^O^**](http://chenrudan.github.io/reward/)
[1] Maxout Networks
[2] BinaryConnect: Training Deep Neural Networks with binary weights during propagations
[3] Binarized Neural Networks: Training Neural Networks with Weights and Activations Constrained to +1 or −1
[4] Ternary weight networks
[5] From Hashing to CNNs: Training Binary Weight Networks via Hashing
[6] Learning Accurate Low-Bit Deep Neural Networks with Stochastic Quantization
[7] DEEP COMPRESSION: COMPRESSING DEEP NEURAL NETWORKS WITH PRUNING, TRAINED QUANTIZATION AND HUFFMAN CODING
[8] TRAINED TERNARY QUANTIZATION
[9] DOREFA-NET: TRAINING LOW BITWIDTH CONVOLUTIONAL NEURAL NETWORKS WITH LOW BITWIDTH GRADIENTS
[10] TRAINING AND INFERENCE WITH INTEGERS IN DEEP NEURAL NETWORKS
[11] Deep Learning with Low Precision by Half-wave Gaussian Quantization
[12] Two-Step Quantization for Low-bit Neural Networks
[13] LQ-Nets: Learned Quantization for Highly Accurate and Compact Deep Neural Networks
[14] ImageNet Classification with Deep Convolutional Neural Networks
[15] XNOR-Net: ImageNet Classification Using Binary Convolutional Neural Networks
[16] Fixed-point Factorized Networks
[17] INCREMENTAL NETWORK QUANTIZATION: TOWARDS LOSSLESS CNNS WITH LOW-PRECISION WEIGHTS
[18] DOREFA-NET: TRAINING LOW BITWIDTH CONVOLUTIONAL NEURAL NETWORKS WITH LOW BITWIDTH GRADIENTS
[19] Network Sketching: Exploiting Binary Structure in Deep CNNs
[20] Towards Effective Low-bitwidth Convolutional Neural Networks
[21] SYQ: Learning Symmetric Quantization For Efficient Deep Neural Networks
[22] Very deep convolutional networks for large-scale image recognition
[23] Towards Accurate Binary Convolutional Neural Network
[24] Deep residual learning for image recognition
[25] Estimating or Propagating Gradients Through Stochastic Neurons for Conditional Computation
神經網絡模型量化方法簡介
發表於 2018-10-02 | 分類於 algorithm |
本文主要梳理了模型量化算法的一些文章,闡述了每篇文章主要的內核思想和量化過程,整理了一些對這些文章的分析和看法。
【轉載請注明出處】chenrudan.github.io
隨着神經網絡算法的發展,網絡性能雖然越來越強大,但是也耗費了太多的計算資源和內存,為了得到更有效率的網絡以及能部署在移動端,近幾年神經網絡的壓縮算法成了一個研究熱點,主要的網絡壓縮途徑有五種,量化、剪枝、低秩分解、教師-學生網絡、輕量化網絡設計,量化就是將以往用32bit或者64bit表達的浮點數用1bit、2bit占用較少內存空間的形式進行存儲。剪枝的目的是為了去掉一些不重要的神經元、連接、通道等,低秩分解主要是通過各種分解方法用精簡的張量來表達復雜張量,教師-學生網絡間接通過提升小網絡性能來壓縮學生網絡的規模,一般可以與其他壓縮方法同時使用,輕量化網絡設計主要是類似MobileNet這種設計的非常精簡但性能又好的網絡。幾種方法都各有特點,都是值得研究和討論的,本文主要針對量化算法近幾年的發展做一個梳理和歸納,我覺得量化算法有幾個特點,理論簡單,公式少,性能穩定且trick多。
下圖1-4我整理了本文涉及到的文章在各個開源數據集上的性能表現,由於各個文章中對比指標不是完全一致,例如MNIST、Cifar10所用到的基礎網絡不一定一樣,對性能感興趣的可以去對照原文看看。
圖1 Cifar10、VGG、GoogLeNet
|
圖2 AlexNet
|
圖3 ResNet18
|
圖4 ResNet34 & ResNet50
|
圖1 Cifar10、VGG、GoogLeNet
|
圖2 AlexNet
|
圖3 ResNet18
|
圖4 ResNet34 & ResNet50
|
模型量化主要包括兩個部分,一是針對權重Weight量化,一是針對激活值Activation量化,在一些文章中已經表明了將權重和激活值量化到8bit時就可以等價32bit的性能。在神經網絡中的基本操作就是權重和激活值的卷積、乘加操作,W∗AW∗A如果將其中一項量化到{-1,1},那么就將乘加操作簡化為了加減操作,如果兩項都量化到{-1,1},乘加操作就簡化為了按位操作,對於硬件計算是非常友好的。
BinnaryConnect
BinnaryConnect[2]是我看到的第一篇歸納出完整量化流程的文章,它提出DNN的前向和反向訓練中用1bit的二值權重替代浮點權重,能夠讓硬件計算將乘法操作簡化成簡單的累加操作,且能大量的減少存儲空間,在MNIST、CIFAR-10、SVHN上接近SOA的性能。
我們知道正是由於神經網絡參數量大,無法直接得到損失函數的最優參數,才采用了梯度下降的方式來逼近最優解,Sgd通過平均權重帶來的梯度來得到一些小的帶噪聲的步長,嘗試更新權重去搜索參數空間,因此這些梯度十分重要,要具有足夠的分辨率,sgd至少需要68bits的精度,大腦突觸的估計精度也是612bits。。如果采用量化權重,就會導致無法對權重直接求導,這種權重可以被看成是帶噪聲的權重。文章認為帶噪聲的權重往往能夠帶來正則化,使得泛化能力更好,類似dropout、dropconnect這種就是對激活值或者權重加入了噪聲,它們表明只有權重的期望值需要是高精度的,添加噪聲往往是有益處的,所以對權重進行量化理論角度是可行的,且在部分文章中發現對梯度隨機取舍能夠提供無偏離散化。
在本文中提出了BinaryConnect,在DNN的前向和反向訓練中用二值權重替代浮點權重,此處的二值權重B取值為{-1,1},文章中提出了兩種量化方法,判別式和隨機式,其中σ(w)=clip(x+12,0,1)σ(w)=clip(x+12,0,1),公式1通過符號函數直接取浮點權重的符號,公式2根據當前浮點權重求出一個概率,按照這個概率隨機分配正負1。
wb={+1,if w≥ 0; −1,otherwise(1)(1)wb={+1,if w≥ 0; −1,otherwise
wb={+1,with probability p=σ(w); −1,with probability 1-p(2)(2)wb={+1,with probability p=σ(w); −1,with probability 1-p
完整算法流程如下圖5,C是損失函數,binarize(w)是按照上述公式二值化權重值,clip(w)是截斷權重值,L是層數。前向傳播時,只對權重做二值化,然后逐層求出二值權重得到的激活值,反向傳播時,也是在二值權重上將對每層輸入的導數傳播回來,此時的導數是浮點的,更新參數時,同樣求得的梯度也是浮點的。由於通常求得的梯度數值不是很大但是又非常重要,所以此處參數更新時還是用浮點梯度。由於權重量化時只取符號,浮點權重大於正負1,對結果沒有影響,為了限制浮點權重不會增長過於誇張以及提高正則性,使用了clip函數將浮點權重限制在正負1之間。
圖5 BinnaryConnect算法流程
圖5 BinnaryConnect算法流程
量化網絡如何inference,一是直接用二值權重。二是用浮點權重,權重二值化只用在訓練階段。三是從浮點權重和隨機二值化可以采樣出很多二值網絡,將它們的預測輸出平均一下作為輸出。論文用第三種方法,訓練過程中用隨機二值權重,測試時用浮點權重可以提升性能,證明了論文前面認為的帶噪聲的權重具有一定的正則性。
這篇文章主要貢獻在於將浮點權重量化到1bit,提出了完整的量化權重流程,且從帶噪聲的權重角度來解釋量化權重。
BNN
BNN[3]與BinnaryConnect是同一個作者,也是這個算法的擴展,在前面只將權重量化到了1bit,本文則進一步將激活值也變成1bit,即減少了內存消耗,也將許多乘加操作簡化成了按位操作XNOR-Count,二值化CNN能夠減少60%的硬件時間復雜度,訓練BNN在MNIST、CIFAR-10、SVHN上達到了SOA的性能。
權重和激活值都量化成了{-1,1},量化方式也是按照公式1和2,隨機式在硬件實現上具有一定的難度,為了加快訓練速度,文章中用的是判別式。由於符號函數的梯度都是0,離散神經元的梯度可以通過straight-through estimator[25]來解決,即浮點數的梯度等於量化數的梯度gr=gq1|r|≤1gr=gq1|r|≤1,但是如果浮點權重數值過大,一般要舍棄掉這個梯度。
在訓練過程中,需要保存二值權重和浮點權重,在前向后向計算中用二值權重,計算出來的梯度保存成浮點,且更新到浮點權重上。前向傳播時,先對WkWk做二值化,然后與當前的二值輸入abk−1ak−1b,相乘得到sksk,再經過BatchNorm,得到輸出即下一層的輸入abkakb。反向傳播時,對二值激活值的的梯度等於對浮點激活值的梯度,計算對上一層輸入的梯度時用的是二值權重,計算對二值權重的梯度時用的是上一層的二值激活值。在更新梯度時,梯度更新在浮點權重上,並將新一輪的Wt+1kWkt+1限制在-1~1之間。
文章中提出了第一個卷積層參數普遍較少,所以第一個卷積層輸入量化到8bit,后面很多論文也采用同樣的策略。與1bit權重相乘方式如公式3,xnxn代表的是用8bit表示方法第n位的取值。
s=∑n=182n−1(xn⋅wb)(3)(3)s=∑n=182n−1(xn⋅wb)
BNN算法主要貢獻在於同時對權重和激活值量化到1bit,不僅從實驗角度證明量化算法的可行,還分析針對低bit如何進行更有效的計算,整理出了同時量化權重和激活值到1bit的算法流程,且針對內部的硬件計算,給出了具體實現,例如Shift-based Batch Normalization、XNOR-Count,最終訓練能減少60%的時間,32倍的存儲空間。
XNOR-Net
這篇文章[15]提出了兩個網絡Binary-Weight-Networks(BWN)和XNOR-Net,BWN只將權重量化為二值,XNOR權重和激活值都是二值,速度快了58x,內存節省32x。當AlexNet壓縮成BWN時,性能與浮點網絡一致。
在對浮點值進行量化時,加入了一個scaling factor,例如權重量化中W=αBW=αB,αα是一個浮點實數,所以在BWN中權重取值就是−α,+α−α,+α,所以量化變成了一個優化問題,這個優化問題是公式4,找到最優的αα使得量化權重與浮點權重之間差距最小。
J(B,α)=||W−αB||2 α∗,B∗=argminα,BJ(B,α)(4)(4)J(B,α)=||W−αB||2 α∗,B∗=argminα,BJ(B,α)
將公式4對αα求導再設為0,得到alpha的解析解α∗=WTB∗nα∗=WTB∗n,其中包含了二值權重B,如果假設B通過符號函數來求解,那么可以推導出α∗=1n||W||l1α∗=1n||W||l1。
XNOR-Net中對激活值也量化X=βHX=βH,其中H也是{-1,1},ββ是它的尺度系數,卷積包括重復shift操作和點乘,shift指的是filter在輸入圖上進行移動,當輸入輸出都變為二值時,將權重和激活值的尺度系數提取出來之后,卷積可以變成xnor-bitcounting操作。
Cnn訓練分為三個部分,前向傳播、后向傳播、參數更新,在前向后向的計算中使用量化權重,更新時如果直接更新量化權重,那么梯度可能不夠大到改變量化權重的取值,所以還是讓浮點權重進行更新。
XNOR-Net文章主要貢獻在於提出了一個更好的擬合浮點數的方法,即給二值數增加一個尺度因子,而不是簡單的取符號,在alexnet上將權重量化到1bit時能夠達到跟浮點權重一樣的性能。
TWN
前幾篇文章都是將浮點數直接量化到了1bit,TWN[4]則提出將權重量化成2bit,雖然2bit能表達四個數,但是只取了三個數{-1,0,1},在mnist和cifar10數據集上三值權重性能比二值權重好很多,通過2bit表達,可以達到16x到32x的模型壓縮比例。
一般卷積kernel的尺寸是3x3,針對二值權重,表達能力是2^(33)=512種配置,而三值權重3^(33)=19683種配置,所以說三值權重比二值權重的表達能力要高很多。三值權重取值上多了一個0,實際計算中,由於0值處不需要進行相乘累加,對硬件也是十分友好。
量化公式如公式5,也使用到了尺度因子來擬合浮點權重,最小化量化權重TWN和浮點權重FPWN之間的L2距離。
α∗,Wt∗=argminα,WtJ(α,Wt)=||W−αWt||2 s.t. α≥0,Wti∈−1,0,1(5)(5)α∗,Wt∗=argminα,WtJ(α,Wt)=||W−αWt||2 s.t. α≥0,Wit∈−1,0,1
優化問題就變成了如何求出αα和WtWt,同樣對αα求梯度且令梯度為0,可以得到αα的解析解,求出來的WtWt和αα是相互關聯的,所以無法直接得出,文章就提出了一種量化方法,首先需要一個閾值ΔΔ,這個閾值用來區分浮點權值映射到正負1、0上,如公式6。然后求出的α∗Δ=1|IΔ|∑i∈Δ|Wi|αΔ∗=1|IΔ|∑i∈Δ|Wi|。
Wti=+1,:::if::Wi>Δ0,:::if::|Wi|≤Δ−1,:::if::Wi<−Δ(6)(6)Wit=+1,:::if::Wi>Δ0,:::if::|Wi|≤Δ−1,:::if::Wi<−Δ
求閾值則無法直接去求解,因此假設權重服從幾個分布來分析這個閾值的求解途徑,例如假設權重服從均勻分布[-a,a],閾值Δ=1/3∗aΔ=1/3∗a,例如服從高斯分布,閾值Δ=0.6σΔ=0.6σ,所以作者歸納出了一個經驗公式用於求解Δ∗=0.7n∑ni=1|Wi|Δ∗=0.7n∑i=1n|Wi|,然后求出對應αα。訓練網絡的方式與之前的文章一致。
TWN的主要貢獻通過2bit來近似浮點權重,相比於二值權重性能有較明顯的提升,但由於取值也限於正負1和0,對硬件計算沒有額外的負擔。
BWNH
[5]認為量化的過程可以看成一個hash映射,目標就變成了交替優化方法來學習哈希碼。
在之前文章中的量化優化問題都是找到最優的量化數值來擬合浮點數值,本文中考慮的是最小化內積的量化誤差。本文中是將權重量化到1bit,內積指的是權重和激活值之間相乘,也稱為輸入X和權重W的相似性矩陣S=XTWS=XTW,將浮點權重映射到量化權重的哈希函數為B=g(W)B=g(W),哈希函數X=h(X)X=h(X),h是恆等映射函數。
minL(B)=||XTW−XTB||2F:::s.t.B∈{+1,−1}S×N(7)(7)minL(B)=||XTW−XTB||F2:::s.t.B∈{+1,−1}S×N
g(W)=BAg(W)=BA,A是對角矩陣,每個元素是一個scaling factor,所以目標函數也可以寫成minL(A,B)=∑Ni||Si−αi⋅XTBi||2FminL(A,B)=∑iN||Si−αi⋅XTBi||F2,計算每個αα、輸入、二值權重之間的乘積來擬合浮點權重與輸入乘積,要求的是哈希映射g,將浮點權重映射到正負1、0這樣的hash code上。
此處對A和B求梯度設為0,可以推導出帶有輸入數據關於αα和B的求解公式8,在更新A時將B固定不動,更新B時固定A不動,且更新每一個B時還要固定剩下的B,即通過這種交替優化的方式來進行更新。且由於二值權重的量化error是網絡層與層從頭到尾一直在累加的,因而考慮分層量化,例如先對前l個層做二值化,讓整個網絡逐漸的適應二值權重,再去量化第二個部分。
αi=STiXTBi||XTBi||2F b=sign(qj−B‘TiZ‘v)(8)(8)αi=SiTXTBi||XTBi||F2 b=sign(qj−Bi‘TZ‘v)
在具體算法流程中,逐層的對每一層的權值做二值化,每一層量化時初始化時B取浮點權重的符號,而A取權重平均絕對值,接着就按照公式8進行交替的優化A和B。最后再對整個網絡進行finetuing。
BWNH只對權重進行了量化,算法主要貢獻在於從哈希角度來解決量化問題,並且提出了逐層的交替更新,相對於之前的二值權重量化方法性能有着較為明顯的提升。
FFN
FFN[16]中只將浮點權重量化到2bit,通過定點化分解方式來求解量化后權重,由於三值權重只有正負1和0,即可以消除最耗費資源的multiply-accumulate operations(MAC)操作,FFN可以得到浮點網絡性能相當的網絡,且乘法運算僅為浮點網絡的千分之一。
通過semidiscrete decomposition(SDD)半離散分解將浮點權重W分解成定點化方式W=XDYTW=XDYT,中D是一個非負對角矩陣,X和Y每個元素取值為{-1,0,1},所以一個正常的卷積n*c*h*w會被分解成三個步驟,卷積有n個輸出channel,拆成三個后,第一個可看成有k個輸出channel的卷積,即k*c*h*w,第二個步驟相當於每個特征圖都乘以一個尺度因子,最后一個也可以看成卷積層大小是n*1*1*k。
圖6 FFN分解
圖6 FFN分解
為了更好的恢復浮點權重,算法中保留了X和Y對應的浮點數值X^X^和Y^Y^,且浮點數值被限制在-1.5~1.5,根據取值落在哪個區間量化到哪個數值,而在梯度更新時,更新的對象是X^X^和Y^Y^。
FFN只針對權重做了量化,提出了將浮點權重矩陣用矩陣分解的方式分解成三個簡單矩陣,其中兩個矩陣元素取值為正負1和0,從而間接完成量化的功能。
INQ
INQ[17]提出增量網絡量化方法,通過權重分組、按組量化、重新訓練三個操作將浮點網絡量化到低bit網絡,在resnet18上量化權重后,4bit、3bit、2bit能夠達到甚至超過浮點權重。
文章從網絡剪枝算法中得到靈感,逐步的從已經訓練好的網絡中移除掉不那么重要的權重,最終性能也不會有明顯下降,所以說權重是存在不同的重要性的,但是之前的方法沒有考慮到這點,而是同時將高精度浮點數轉化為低精度數值,因此改變網絡權重的重要性對於減少量化網絡的損失很重要。
本文中低bit權重需要一個符號位,至少從2bit開始,b是比特數,取值范圍是Pl=±2n1,…,±2n2,0Pl=±2n1,…,±2n2,0,由兩個整數n1n2定義n2=n1+1−2b−12n2=n1+1−2b−12,通過經驗公式可以計算出n1n2。量化公式9中的αα和ββ就是PlPl中相鄰的兩項。
Wl^(i,j)=βsgn(Wl(i,j))::::if(α+β)/2≤abs(Wl(i,j))<3β/2 0,otherwise(9)(9)Wl^(i,j)=βsgn(Wl(i,j))::::if(α+β)/2≤abs(Wl(i,j))<3β/2 0,otherwise
網絡訓練過程中,將權重分割到兩個不相交的組中,第一個組A(1)lAl(1)中的權重基於公式4進行組內量化,另一個組$A_l^{(2)}中權重保持浮點精度,自適應的彌補量化模型造成的loss,且在反向re-training更新權重時,通過一個mask來判斷屬於哪個組,屬於第一個組的量化權重就不更新,只更新第二個組的浮點權重。然后針對第二個組的浮點權重做重復的三步操作,直到所有權重被量化完成。
圖7 INQ算法
圖7 INQ算法
INQ算法對權重進行了量化,通過逐步增量式的將權重量化,通過保留一部分浮點權重來恢復模型的性能,精度損失得到了一定的遏止。
SQ-B(T)WN
SQ-B(T)WN[6]也是一種增量式量化算法,它從不同權重會導致不同量化誤差角度,在近似實數權重時,可能只是針對部分filter量化error大,部分filter量化error小,文章提出了隨機選擇部分filter量化STOCHASTIC QUANTIZATION,逐漸增加量化比例最終完成全部權重量化。
一層的權重按照輸出channel作為一組數據W=W1,…,WmW=W1,…,Wm,其中m等於輸出channel數量,第i個filter權重是WiWi。也是將這一層的權重划分成兩個不相交的集合GqGq和GrGr,將GqGq中權重量化到低bit,而GrGr權重還是浮點,GqGq有Nq=r∗mNq=r∗m個filter,而GqGq有Nq=(1−r)∗mNq=(1−r)∗m個。其中r就是隨機量化SQ比例,r在逐漸增加,最終增加到1。
針對每一個filterWiWi都有自己的一個量化概率pipi,表明第i個filter被量化的概率,量化概率的取值由量化誤差決定。當量化誤差小時,量化當前的這個channel就會造成較少不同的信息損失,那么就能給這個channel賦予較大的量化概率。首先定義浮點權重和量化權重的L1距離ei=||Wi−Qi||1||Wi||1ei=||Wi−Qi||1||Wi||1,將它作為量化誤差,並定義一個中間變量fi=1ei+ϵfi=1ei+ϵ,從而量化概率可以有不同的求解方法,例如pi=1/mpi=1/m或者pi=11+exp(−fi)pi=11+exp(−fi)。
圖8 隨機channel量化
圖8 隨機channel量化
在圖8中,先計算出4個channel的量化error,假設當前r=50%,根據每個channel計算出來的量化概率挑選2個channel量化。
SQ-B(T)WN算法通過逐步量化權重,比直接全部量化產生的更加合適梯度方向,但是從算法結果上來說,看起來並不是特別好。
Deep Compression
Deep Compression算法[7]結合了剪枝、量化、哈夫曼編碼三種操作,在性能沒有降低的情況下壓縮了35x~49x,目標是減少存儲空間減少inference的耗時,從而能部署在移動設備上。
第一步是剪枝,在訓練過程中來學習各個連接的性能表現,然后裁剪掉權重較小不夠重要的連接,通過設定一個閾值,小於這個閾值移除掉,再重新訓練留下的稀疏連接。剪枝后的稀疏結構用compressed sparse row和compressed sparse row方式存儲,需要保存2a+n+1數據,a是非零值元素個數,n是行數或者列數。這一步中可以在Alexnet和VGG-16上壓縮9x~13x。
第二步是量化,通過讓多個連接共享相同權重來達到量化目的,在有限的bit數中只能表達有限的數值,所以當某些神經元取一樣的數值時,就說它們在共享這個權重。假設權重大小是4*4,權重被量化到4個bin,在相同bin中的權重取值相同,因此只需要保存bin的索引,更新的時候相同bin中的梯度加起來再更新。假如有k個bin,那么需要log2k位來對索引進行編碼,假如網絡有n個連接,每個連接由b個位表達,從而可以得到壓縮比例r=nbnlog2(k)+kbr=nbnlog2(k)+kb。通過k-means聚類來確定這些用於共享的權重,將n個權值分配到k個類中,最小化權重和類中心絕對值之差(WCSS)得到類中心C=c1,…,ckC=c1,…,ck。嘗試了三種初始化共享權重中心C的方法,隨機、基於密度、線性初始化,隨機方法就從權重中隨機選擇k個值,基於密度會選擇一些在尖峰周圍的點,線性初始化在權重數值線性進行間隔選擇,發現線性初始化效果最好。反向傳播也跟其他量化方式是一致的。
huffman編碼是一種無損數據壓縮方法,壓縮非均勻分布的值可節省20%30%的網絡存儲。最終經過這三個操作,網絡在性能沒有降低的情況下被壓縮了35x49x。
這篇文章操作較多比較復雜,但是性能是穩定可靠的,每個壓縮操作都沒有導致性能下降。
TTQ
TTQ[8]量化浮點權重到三值權重,在開源數據集上相比浮點性能下降很少。
在之前的量化算法中,是通過一個尺度因子和三值權重相乘來擬合浮點權重,像在TWN中給出了經驗公式來計算尺度因子αα,本文提出了通過梯度下降對αα進行更新。
首先將浮點權重除以最大值后正則化到正負1之間,所有的層有一個相同的參數t,用來計算閾值Δl=t×max(|w~|)Δl=t×max(|w~|)進行量化。
wtl=Wpl:w~l>Δl 0:|w~l|<Δl −Wnl:w~l<−Δl(10)(10)wlt=Wlp:w~l>Δl 0:|w~l|<Δl −Wln:w~l<−Δl
這里針對正負數有不同的量化levels,即有兩個尺度因子WplWlp和WnlWln。因此對它們計算梯度可以得到梯度下降更新公式,∂L∂Wpl=∑i∈Ipl∂L∂wtl(i),∂L∂Wnl=∑i∈Inl∂L∂wtl(i)∂L∂Wlp=∑i∈Ilp∂L∂wlt(i),∂L∂Wln=∑i∈Iln∂L∂wlt(i)。在觀察尺度因子的變化情況時,針對第一個量化全局層,正負尺度因子的絕對值會變得越來越小,稀疏性降低了,針對最后一個卷積層和全連接層正負尺度因子的絕對值會變得越來越大,稀疏性提升了。
對尺度因子進行訓練的好處在於,正負尺度因子的不對稱使得模型能力更強,且針對所有層有一個常數稀疏r,調整超參數r可以調整量化閾值,能夠獲得不同稀疏度的三值網絡。
TTQ中將正負量化levels分開考慮,且作為可訓練的參數進行更新,而不是用經驗公式進行計算,性能比TWN也要好一些。
DoReFa-Net
在DoReFa-Net[9]中權重、激活值和參數梯度都設置成了低bit,優點是不只在inference時能夠加速,且訓練時由於梯度也被量化了,訓練時也能加速。所以能夠很好的在硬件平台上直接進行訓練。
當權重和激活值都量化后,就能夠用bitcount操作來計算,即x和y相與的結果后可以直接數出位置為1的個數,而之前的文章中還沒有量化過梯度到8bit以下。在BNN網絡中,浮點梯度在-1到1范圍內時等於量化梯度,超出范圍就等於0,在xnor-net中,浮點梯度直接等於量化梯度,由於加上了一個尺度因子,所以權重能夠表示的范圍就更廣了,在DoReFa-Net中權重量化方式為ro=fkw(ri)=2quantizek(tanh(ri)2max(|tanh(ri)|)+12)−1ro=fwk(ri)=2quantizek(tanh(ri)2max(|tanh(ri)|)+12)−1,其中k是指定的bit數,fkw(ri)fwk(ri)取值被限制在了-1~1之間。
激活值的量化先是由一個激活函數將范圍限制在0~1之內,再量化到k bit,fka(r)=quantizek(r)fak(r)=quantizek(r)。
在針對梯度進行量化時,隨機量化是一個比較有效的手段,且梯度是不像激活值可以被限制在某個范圍內,有的位置上梯度取值可能會比較大,激活值由於可以經過一個激活函數,所以能夠限制數值大小。梯度量化公式為fkγ(dr)=2max0(|dr|)[quantizek[dr2max0(|dr|)+12+N(k)]−12]fγk(dr)=2max0(|dr|)[quantizek[dr2max0(|dr|)+12+N(k)]−12],本文的隨機就體現在加入了一個額外的噪聲函數N(k)N(k),效果非常明顯。
所以DoReFa-Net並不是指定量化到多少bit,而是可以量化到任意的bit,由於整個網絡的輸入數據層channel較少,對於整體網絡復雜度影響較小,因此第一個卷積層的權重不進行量化,第一個卷積層的輸出激活值會被量化,如果輸出類別較少時,最后一個卷積層的權重也不進行量化,最后一層的反向梯度需要量化。
這篇文章主要就是提出對梯度也進行量化,並且支持量化到任意bit。
ABC-Net
二值權重和激活值能夠很大程度的減少內存空間,且能采用按位計算,對硬件很友好,但是現有的方法會導致性能下降,本文主要提出了ABC-net(Accurate-Binary Convolutional)線性組合多個二值權重基來擬合浮點權重,利用多個二值激活值基組合來減少信息損失。
將浮點權重用M組二值權重和尺度因子進行線性組合,W≈α1B1+α2B2+…+αMBMW≈α1B1+α2B2+…+αMBM,將B表示成浮點權重與均值和方差的組合形式Bi=Fui(W):=sign(W−mean(W)+uistd(W))Bi=Fui(W):=sign(W−mean(W)+uistd(W)),其中有一個尺度變量uiui,既可以由經驗公式ui=−1+(i−1)2M−1ui=−1+(i−1)2M−1直接算出,也可以通過網絡訓練的方式得到。這樣去估計B的原因是,浮點權重傾向於是一個對稱、非稀疏分布,比較類似高斯分布,所以用均值和方差來估計。確定B之后,通過線性回歸來求解alpha。在增加了尺度因子后,求解反向梯度時,會增加一個αα系數,∂c∂W=∑Mm=1αm∂c∂Bm∂c∂W=∑m=1Mαm∂c∂Bm。在實現中,將浮點權重按照channel區分開,用同樣的方式來估計尺度因子和二值權重,理論上能夠更加細致的擬合浮點權重。
當權重是二值的,卷積操作就沒有了乘法,只剩下加減,如果想要更高效的利用按位操作,最好是將激活值也變為二值。因此類似對權重的處理,文章首先將激活值通過一個clip函數hv(x)=clip(x+v,0,1)hv(x)=clip(x+v,0,1),將范圍限制在0~1之間,量化激活值取值是{-1,1},通過一個指示函數A=Hv(R):=2Ihv(R)≥0.5−1A=Hv(R):=2Ihv(R)≥0.5−1進行量化,量化激活值與量化權重的不同點在於,inference的階段權重是不變的,激活值則變化了,但是通過利用神經網絡激活值的統計特性能夠避免這個問題,為了保證激活值的分布相對穩定,使用了batchnorm,它能夠讓輸出保持0均值1方差的分布。用N組二值激活值和尺度因子組合成浮點激活值R≈β1A1+β2A2+…+βNANR≈β1A1+β2A2+…+βNAN,激活值量化中多了一個可以訓練的閾值vv。卷積操作就轉化M*N個按位操作,Conv(W,R)≈∑Mm=1∑Nn=1αmβnConv(Bm,An)Conv(W,R)≈∑m=1M∑n=1NαmβnConv(Bm,An)。
ABC-Net也是一個不限制bit數的量化算法,性能也接近浮點網絡。
HWGQ
HWGQ[11]主要針對激活值量化,利用了激活值的統計特性和batchnorm操作,在前向計算時能有效的近似浮點值的性能。
針對激活值的量化需要處理不可微的操作,主要切入點在於ReLU函數,神經網絡每個單元都計算了一個激活函數,即權重與輸入相乘后經過一個非線性變換,這個操作的多少決定了整個網絡的復雜度。
本文中估計1bit量化權重,也是基於二值權重和尺度因子相乘去擬合浮點權重,輸入I與量化權重卷積來近似I和浮點權重卷積結果,是二值權重取浮點權重的符號B∗=sign(W)B∗=sign(W),尺度因子是浮點權重平均絕對值α∗=1cwh||W||1α∗=1cwh||W||1,1bit權重能夠減少存儲空間,但是無法完全計算復雜度的問題,如果將I也變成二值的,則能夠最大程度上解決計算復雜度的問題。
在對激活值進行量化時,如果直接按照符號函數來定義量化levels,那么對量化激活值進行求導時,導數處處為0,所以有人提出,對符號函數求導如果輸入絕對值小於1則梯度為1,其他位置取0。結合relu函數,本文對激活值量化的目標是擬合relu函數的輸出。quantizer是一個分段常數函數,量化levels就是量化到的值,量化step就是兩個量化level之間的差,針對每個浮點數值,它只需要保存一個索引值i,對應到第i個量化level,非均勻量化情況下表達浮點權重需要多余log2mlog2m的bit數,如果是均勻量化則log2mlog2m個bit就夠了。激活值的統計結構傾向於對稱非稀疏分布類似高斯分布,再結合relu,就是變成了一個半波高斯量化子half-wave Gaussian quantizer。這里的量化就是變成了求針對高斯分布的量化levels和step,但是在不同層的神經元所得到的類高斯分布,它們的均值方差不一定是相同的,為了得到相同的數據分布,通過batchnorm來得到0均值1方差的分布,然后就能在神經元之間得到均勻的量化參數。以上是在解釋構造這樣的HWGQ,它是階梯常數函數,梯度處處為0,目標就變成了選哪個函數作為HWGQ在量化后才能最好的擬合relu函數的效果。
首先考慮最基本的relu函數,它對輸入的梯度等於輸出梯度,與正向的HWGQ所需要的梯度是不匹配的,特別是當輸入數值大於最大的量化level時,產生的誤差導致的反向梯度就會特別大。基於這個情況,考慮用clipped后的relu,保證最大值不超過最大的量化level,但是由於clipped的操作,丟失掉了qmqm之后的輸入信息會直接導致性能的下降,因此提出一種折中的函數公式11即長尾relu,它既能保證超過qmqm的梯度不會過大,也不會完全丟失掉大於qmqm的信息。
Ql~(x)=qm+log(x−τ),x>qm x,x∈(0,qm] 0,x≤0(11)(11)Ql~(x)=qm+log(x−τ),x>qm x,x∈(0,qm] 0,x≤0
HWGQ主要從理論上分析如何去選擇一個激活函數,從而保證激活值量化后低bit網絡性能接近浮點網絡。
Network Sketching
本文提出了Network Sketching[19]用來尋找量化二值權重的網絡,整個過程可以看成是由粗到細的模型近似。
按照輸出channel來划分不同的filter,假設有m組基來擬合一個channel的權重,W=∑m−1m=0αjBjW=∑m=0m−1αjBj,其中B∈{+1,−1}c×w×h×mB∈{+1,−1}c×w×h×m,而α∈Rmα∈Rm。主要想法是基於不斷擬合量化權重和浮點權重之間的殘差,即計算浮點權重減去已經累加得到的量化權重∑j−1k=0αkBk∑k=0j−1αkBk之間的殘差成為新的需要擬合的浮點權重,去獲得下一步的B和αα,即公式12。
Wj^=W−∑k=0j−1αkBk(12)(12)Wj^=W−∑k=0j−1αkBk
具體在求B和αα,B是取浮點權重的符號,αα由二值權重和浮點權重內積求出來αj=<Bj,Wj^>tαj=<Bj,Wj^>t,其中t=c×w×ht=c×w×h。在第一個Direct Approximation算法中就是重復m次,求出m組B和αα。重構error以1/t的指數進行衰減,如果t取值小,重構error就會越小,t很大時,重構error的減少幅度就會很慢,就算增加m的數量,最終的近似效果可能也不夠好。所以B和αα不一定是最優的,為了進一步優化得到更好的近似效果,在第二個Approximation with Refinement算法中給出更新公式,aj=(BTjBj)−1BTj⋅vec(W)aj=(BjTBj)−1BjT⋅vec(W),且文中進一步證明了更新公式能夠近似浮點權重,減少量化error。
本文的sketch就體現在第j個量化權重是在估計當前浮點權重的殘差,量化error越來越精細,就像在逐步的從粗到細描繪出具體的輪廓。
PQ+TS+Guided
本文[20]為了提升量化網絡訓練性能,提出了三個方法,一是兩步優化策略,先量化權重再量化激活值,其次在訓練過程中逐步減少量化位寬,第三聯合訓練浮點網絡和低精度網絡。
量化采用的是Q函數均勻量化,zq=Q(zr)=12k−1round((2k−1)zr)zq=Q(zr)=12k−1round((2k−1)zr),在量化權重時,先對w做歸一化,其中tanh可以減少大值的影響,再用Q函數去量化,求解形式與DoReFa-Net是一樣的。針對激活值,先將激活值通過clip函數限制在0~1的范圍內,然后用Q量化。反向傳播更新梯度也是基於STE算法。
為了增加量化的准確性,本文首先提出了兩步優化two-stage optimization(TS),先量化權重再量化激活值,如果從K-bit的網絡量化得到k-bit的網絡,首先訓練在K-bit激活值下的k-bit權重,在k-bit權重訓練好后訓練k-bit的激活值。而由於訓練過程中近似的梯度不一定是准確的,所以會導致陷入局部最優值的情況,所以本文提出了分階段量化progressive quantization(PQ)的想法,逐步減少量化位寬的方法,例如32bit->16bit->4bit->2bit,量化n次就得完整訓練n次。第三個提升方法是基於教師-學生網絡(Guided),聯合訓練浮點網絡和低精度網絡,互相適應,因為直接用固定的預訓練好的浮點模型來指導量化網絡不一定最好,且在特征圖層面上進行遷移,為了保持浮點網絡和低精度網絡一致,在相互適應時,將浮點網絡也做同樣的量化,然后再相互遷移。
圖9 Guided訓練
圖9 Guided訓練
這個方法主要是提出一些有效的trick來輔助訓練量化網絡,且表現非常不錯。
SYQ
SYQ[21]提出了對稱量化能夠提升網絡准確率。
在SYQ中,Codebook C是量化levels的一些可能取值,例如{-1,1},或者{-1,0,1},二值化或者三值化權重時通常的方法是采用分段常數函數,並存在ηη這樣的量化閾值超參數,二值化時取為0,三值時由經驗公式η=0.05×max(|Wl|)η=0.05×max(|Wl|)得出。后來的估計方式中引入了scaling factor,提高了近似浮點數的能力,此時的codebook就變成了−α,α−α,α,前面提到過的TTQ就是提出可以對αα進行訓練,且設置正負兩個尺度因子−αnl,αpl−αln,αlp,但是如果采用正負不同的尺度因子,那么在計算權重和激活值乘積時需要先去判斷當前二值權重或者三值權重的符號,增加了額外的判斷分支,所以本文認為對稱的codebook計算效率會更高,codebook最好是在0周圍對稱,那存儲空間可減半。
很多細粒度量化方法能夠提升近似權重分布的能力,本文實現了按像素進行縮放,假設一層權重是K×K×N×IK×K×N×I,pixel-wise就是在I*N維度上將權重進行分組,此時αα個數為K2K2,此時就是將權重分為了K2K2組,row-wise將一個kernel中行或者列組成一組,最粗粒度的是layer-wise,一層只有一個αα。
在SYQ算法流程中,每一層首先通過Ql=sign(Wl)⨀MlQl=sign(Wl)⨀Ml量化權重成二值或者三值,其中MlMl是通過ηη計算得到,然后通過G(x)=12ffloor((2f)x+12)G(x)=12ffloor((2f)x+12)線性量化激活值,前向計算完成之后,通過∂E∂Wli,j=αil∂E∂Qli,j∂E∂Wli,j=αli∂E∂Qli,j來更新權重,通過∂E∂x=∂E∂G∂E∂x=∂E∂G更新激活值,通過∂E∂αil=∑j∈Sil∂E∂Wli,j∂E∂αli=∑j∈Sli∂E∂Wli,j更新scaling factor。
SYQ相對於TTQ沒有特別明顯的改進,增加了αα的數量使得最終性能想比於TTQ有提升。
TSQ
之前方法中都是同時量化權重和激活值,TSQ[12]提出了先量化激活值再量化權重,針對激活值,提出了稀疏量化方法,文章認為網絡壓縮和加速中稀疏能起到很大作用,之前的文章中都很少研究這個方向,且稀疏性在特殊硬件上會更有效,而權重量化可以看成低bit非線性最小二乘回歸問題,通過迭代方式求解。
得到低比特權重是transformations,得到低比特激活值是encodings。在encodings問題中,Relu函數本身就產生了50%的稀疏性,在attention機制的基本假設中,數值較大的激活值比數值較少的激活值更重要。所以將數值較小的正值變成0,這樣量化算法能夠更能關注到較大的數值,量化的會更精細。n-bit均勻量化子quantizer將浮點激活值映射到2n2n個離散值,主要就是在於決定量化間隔ΔΔ和量化范圍titi。之前的HWGQ方法中是通過batchnorm層,輸出分布就非常趨近於0均值1方差的高斯分布,因此每個層的ΔΔ和titi是相同的。本文提出稀疏量化,不是將經過relu后的所有正值都進行量化,而是將不重要的數值先設置為0再量化,這個想法之前在網絡剪枝中也有類似研究,也就是大值比小值更重要。所以給出了一個稀疏閾值ϵϵ,得到新的求解激活值量化函數的公式13。
Q∗ϵ(x)=argmaxQϵEx∼N(0,1),x>ϵ[(Qϵ(x)−x)2](13)(13)Qϵ∗(x)=argmaxQϵEx∼N(0,1),x>ϵ[(Qϵ(x)−x)2]
對權重進行量化,假設上一層的輸出是X,這一層的輸出是Y,將權重量化的問題變成一個非線性最小平方回歸問題,將浮點尺度因子αα看成一個對角矩陣,與輸入X相乘之后再經過激活值量化最終去擬合浮點輸出minimizeα,w^||y−Qϵ(αXTw^)||minimizeα,w^||y−Qϵ(αXTw^)||。然后引入了一個輔助變量z,將兩個量化過程區分開minimizeα,w^,z||y−Qϵ(z)||+λ||z−αXTw^||minimizeα,w^,z||y−Qϵ(z)||+λ||z−αXTw^||,權重量化去擬合輔助變量z,激活值量化去擬合浮點輸出。
在求解αα和w時,將優化問題展開之后,對αα進行求導且設置導數為0,可以直接得出αα的求解公式,然后將αα帶入展開公式同樣求出w的求解公式。由於w的維數較高,即m個像素點每個都需要進行計算,而每個可能取值又是2^n個bit,所以如果用窮舉法來找到最優的w是不可行的,還是在求解一個w時,固定剩下的w不變。在求z時,此時αα和w是確定的,且此處將激活值量化函數條件放寬,在0~M范圍內的數值就不進行量化,所以針對不同分布得到了z的求解方式。
對權重量化時,層與層之間可以同時進行,沒有耦合關系,但是獨立進行量化時,量化誤差會在層與層之間累加,所以還是考慮通過按層量化。
TSQ通過稀疏量化激活值和引入一個中間變量z來產生新的量化方法,在alexnet上將權重激活值都量化到2bit時性能與浮點也是一致的。
LQ-Net
LQ-Net[13]目的是希望學習量化任意bit權重和激活值的quantizers,現有的量化方法都是一種人工設計的quantizers,例如均勻量化、對數量化,或者在網絡訓練之時已經計算好的quantizers(HGWQ),如果針對不同的網絡能自適應的學到不同quantizers,性能應該會有所提升,所以本文就想聯合訓練一個量化的DNN網絡和對應的quantizers。
qlql是量化levels,量化intervals指的是tltl到tl+1tl+1,浮點值在tltl到tl+1tl+1范圍內的會被量化到qlql,均勻量化就是指每個tltl到tl+1tl+1的范圍都是相同的,對數量化是tltl到tl+1tl+1的范圍成指數關系,量化到n-bit,就有32/n或者64/n倍的壓縮比例。但是由於每個卷積層的數據分布的不同,均勻量化不一定是最優的,預先設置好的量化方式也不一定是最優的,所以考慮既訓練整個量化網絡,也訓練量化函數。如果量化函數是可以訓練的,那么它不僅能夠減少量化誤差,也能適應整體的訓練目標提升最終性能。
假設網絡被量化到K-bit,一個整數q可以通過一個k維的basis系數向量v和k個bit的二值編碼向量elel點積表達,如公式14所示,此處的系數向量取值為整數。
q=<[1 2… 2K−1],[b1b2 … bK]>(14)(14)q=<[1 2… 2K−1],[b1b2 … bK]>
由於二值編碼向量elel里面每個元素取值都是0和1,當k確定之后elel所有取值可能都可以確定,例如K=2,elel所有可能為{(-1,-1),(-1,1),(1,-1),(1,1)}。v是一個可學習的浮點basis系數向量,v值確定之后和每一組可能的二值編碼向量相乘ql=vTelql=vTel,得到了一系列的量化levels,量化intervals就是兩個level之間的均值。
對權重和激活值都進行相同的量化操作,卷積就變成了Qours(w,vw)TQours(a,va)=∑Kwi=1∑Kaj=1vwivaj(bwi⊙baj)Qours(w,vw)TQours(a,va)=∑i=1Kw∑j=1Kaviwvja(biw⊙bja),其中有兩組要學習的參數,分別是vwvw和vava,同一層的激活值量化共用一個vava向量,一層權重對應每個輸出channel用一個vwvw向量。
在量化和更新過程中,在訓練開始之前通過一個經驗公式求出初始的v,然后先固定v更新B,此時v是已知的,可以直接計算出所有levels,對比浮點數x落在哪個區間就量化到對應的B。然后固定B更新v,通過最小化量化誤差argmaxv,B||BTv−x||22argmaxv,B||BTv−x||22對v求閉式解v∗=(BBT)−1Bxv∗=(BBT)−1Bx來更新當前的v。
LQ-Net算法通過學習得到量化levels,而不是人為設計的quantizers,可以量化到任意的bit,在幾個開源數據集上都有非常不錯的性能表現。
小結
寫到后面,感覺意識有點模糊了,到現在我已經工作了一年多了,今年開始在做模型量化方面的工作,因為需要保護公司的利益,不可能在文章中聊工作的事情,所以只能分享了幾篇個人覺得做這個方向需要了解的一些文章,如果有不足的地方,希望大家批評指正,謝謝了。
[**鼓勵一下^O^**](http://chenrudan.github.io/reward/)
[1] Maxout Networks
[2] BinaryConnect: Training Deep Neural Networks with binary weights during propagations
[3] Binarized Neural Networks: Training Neural Networks with Weights and Activations Constrained to +1 or −1
[4] Ternary weight networks
[5] From Hashing to CNNs: Training Binary Weight Networks via Hashing
[6] Learning Accurate Low-Bit Deep Neural Networks with Stochastic Quantization
[7] DEEP COMPRESSION: COMPRESSING DEEP NEURAL NETWORKS WITH PRUNING, TRAINED QUANTIZATION AND HUFFMAN CODING
[8] TRAINED TERNARY QUANTIZATION
[9] DOREFA-NET: TRAINING LOW BITWIDTH CONVOLUTIONAL NEURAL NETWORKS WITH LOW BITWIDTH GRADIENTS
[10] TRAINING AND INFERENCE WITH INTEGERS IN DEEP NEURAL NETWORKS
[11] Deep Learning with Low Precision by Half-wave Gaussian Quantization
[12] Two-Step Quantization for Low-bit Neural Networks
[13] LQ-Nets: Learned Quantization for Highly Accurate and Compact Deep Neural Networks
[14] ImageNet Classification with Deep Convolutional Neural Networks
[15] XNOR-Net: ImageNet Classification Using Binary Convolutional Neural Networks
[16] Fixed-point Factorized Networks
[17] INCREMENTAL NETWORK QUANTIZATION: TOWARDS LOSSLESS CNNS WITH LOW-PRECISION WEIGHTS
[18] DOREFA-NET: TRAINING LOW BITWIDTH CONVOLUTIONAL NEURAL NETWORKS WITH LOW BITWIDTH GRADIENTS
[19] Network Sketching: Exploiting Binary Structure in Deep CNNs
[20] Towards Effective Low-bitwidth Convolutional Neural Networks
[21] SYQ: Learning Symmetric Quantization For Efficient Deep Neural Networks
[22] Very deep convolutional networks for large-scale image recognition
[23] Towards Accurate Binary Convolutional Neural Network
[24] Deep residual learning for image recognition
[25] Estimating or Propagating Gradients Through Stochastic Neurons for Conditional Computation