【轉載請註明出處】chenrudan.github.io
隨着神經網絡算法的發展,網絡性能雖然愈來愈強大,可是也耗費了太多的計算資源和內存,爲了獲得更有效率的網絡以及能部署在移動端,近幾年神經網絡的壓縮算法成了一個研究熱點,主要的網絡壓縮途徑有五種,量化、剪枝、低秩分解、教師-學生網絡、輕量化網絡設計,量化就是將以往用32bit或者64bit表達的浮點數用1bit、2bit佔用較少內存空間的形式進行存儲。剪枝的目的是爲了去掉一些不重要的神經元、鏈接、通道等,低秩分解主要是經過各類分解方法用精簡的張量來表達複雜張量,教師-學生網絡間接經過提高小網絡性能來壓縮學生網絡的規模,通常能夠與其餘壓縮方法同時使用,輕量化網絡設計主要是相似MobileNet這種設計的很是精簡但性能又好的網絡。幾種方法都各有特色,都是值得研究和討論的,本文主要針對量化算法近幾年的發展作一個梳理和概括,我以爲量化算法有幾個特色,理論簡單,公式少,性能穩定且trick多。
下圖1-4我整理了本文涉及到的文章在各個開源數據集上的性能表現,因爲各個文章中對比指標不是徹底一致,例如MNIST、Cifar10所用到的基礎網絡不必定同樣,對性能感興趣的能夠去對照原文看看。
![]() ![]() |
![]() |
![]() |
![]() |
![]() ![]() |
![]() |
![]() |
![]() |
模型量化主要包括兩個部分,一是針對權重Weight量化,一是針對激活值Activation量化,在一些文章中已經代表了將權重和激活值量化到8bit時就能夠等價32bit的性能。在神經網絡中的基本操做就是權重和激活值的卷積、乘加操做,W∗AW∗A若是將其中一項量化到{-1,1},那麼就將乘加操做簡化爲了加減操做,若是兩項都量化到{-1,1},乘加操做就簡化爲了按位操做,對於硬件計算是很是友好的。
BinnaryConnect
BinnaryConnect[2]是我看到的第一篇概括出完整量化流程的文章,它提出DNN的前向和反向訓練中用1bit的二值權重替代浮點權重,可以讓硬件計算將乘法操做簡化成簡單的累加操做,且能大量的減小存儲空間,在MNIST、CIFAR-十、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。
完整算法流程以下圖5,C是損失函數,binarize(w)是按照上述公式二值化權重值,clip(w)是截斷權重值,L是層數。前向傳播時,只對權重作二值化,而後逐層求出二值權重獲得的激活值,反向傳播時,也是在二值權重上將對每層輸入的導數傳播回來,此時的導數是浮點的,更新參數時,一樣求得的梯度也是浮點的。因爲一般求得的梯度數值不是很大可是又很是重要,因此此處參數更新時仍是用浮點梯度。因爲權重量化時只取符號,浮點權重大於正負1,對結果沒有影響,爲了限制浮點權重不會增加過於誇張以及提升正則性,使用了clip函數將浮點權重限制在正負1之間。
![](http://static.javashuo.com/static/loading.gif)
![](http://static.javashuo.com/static/loading.gif)
量化網絡如何inference,一是直接用二值權重。二是用浮點權重,權重二值化只用在訓練階段。三是從浮點權重和隨機二值化能夠採樣出不少二值網絡,將它們的預測輸出平均一下做爲輸出。論文用第三種方法,訓練過程當中用隨機二值權重,測試時用浮點權重能夠提高性能,證實了論文前面認爲的帶噪聲的權重具備必定的正則性。
這篇文章主要貢獻在於將浮點權重量化到1bit,提出了完整的量化權重流程,且從帶噪聲的權重角度來解釋量化權重。
BNN
BNN[3]與BinnaryConnect是同一個做者,也是這個算法的擴展,在前面只將權重量化到了1bit,本文則進一步將激活值也變成1bit,即減小了內存消耗,也將許多乘加操做簡化成了按位操做XNOR-Count,二值化CNN可以減小60%的硬件時間複雜度,訓練BNN在MNIST、CIFAR-十、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位的取值。
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,找到最優的αα使得量化權重與浮點權重之間差距最小。
將公式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距離。
優化問題就變成了如何求出αα和WtWt,一樣對αα求梯度且令梯度爲0,能夠獲得αα的解析解,求出來的WtWt和αα是相互關聯的,因此沒法直接得出,文章就提出了一種量化方法,首先須要一個閾值ΔΔ,這個閾值用來區分浮點權值映射到正負一、0上,如公式6。而後求出的α∗Δ=1|IΔ|∑i∈Δ|Wi|αΔ∗=1|IΔ|∑i∈Δ|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是恆等映射函數。
g(W)=BAg(W)=BA,A是對角矩陣,每一個元素是一個scaling factor,因此目標函數也能夠寫成minL(A,B)=∑Ni||Si−αi⋅XTBi||2FminL(A,B)=∑iN||Si−αi⋅XTBi||F2,計算每一個αα、輸入、二值權重之間的乘積來擬合浮點權重與輸入乘積,要求的是哈希映射g,將浮點權重映射到正負一、0這樣的hash code上。
此處對A和B求梯度設爲0,能夠推導出帶有輸入數據關於αα和B的求解公式8,在更新A時將B固定不動,更新B時固定A不動,且更新每個B時還要固定剩下的B,即經過這種交替優化的方式來進行更新。且因爲二值權重的量化error是網絡層與層從頭至尾一直在累加的,於是考慮分層量化,例如先對前l個層作二值化,讓整個網絡逐漸的適應二值權重,再去量化第二個部分。
在具體算法流程中,逐層的對每一層的權值作二值化,每一層量化時初始化時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。
![](http://static.javashuo.com/static/loading.gif)
![](http://static.javashuo.com/static/loading.gif)
爲了更好的恢復浮點權重,算法中保留了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中相鄰的兩項。
網絡訓練過程當中,將權重分割到兩個不相交的組中,第一個組A(1)lAl(1)中的權重基於公式4進行組內量化,另外一個組$A_l^{(2)}中權重保持浮點精度,自適應的彌補量化模型形成的loss,且在反向re-training更新權重時,經過一個mask來判斷屬於哪一個組,屬於第一個組的量化權重就不更新,只更新第二個組的浮點權重。而後針對第二個組的浮點權重作重複的三步操做,直到全部權重被量化完成。
![](http://static.javashuo.com/static/loading.gif)
![](http://static.javashuo.com/static/loading.gif)
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)。
![](http://static.javashuo.com/static/loading.gif)
![](http://static.javashuo.com/static/loading.gif)
在圖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~|)進行量化。
這裏針對正負數有不一樣的量化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的信息。
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。
具體在求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),聯合訓練浮點網絡和低精度網絡,互相適應,由於直接用固定的預訓練好的浮點模型來指導量化網絡不必定最好,且在特徵圖層面上進行遷移,爲了保持浮點網絡和低精度網絡一致,在相互適應時,將浮點網絡也作一樣的量化,而後再相互遷移。
![](http://static.javashuo.com/static/loading.gif)
![](http://static.javashuo.com/static/loading.gif)
這個方法主要是提出一些有效的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。
對權重進行量化,假設上一層的輸出是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所示,此處的係數向量取值爲整數。
因爲二值編碼向量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,在幾個開源數據集上都有很是不錯的性能表現。
小結
寫到後面,感受意識有點模糊了,到如今我已經工做了一年多了,今年開始在作模型量化方面的工做,由於須要保護公司的利益,不可能在文章中聊工做的事情,因此只能分享了幾篇我的以爲作這個方向須要瞭解的一些文章,若是有不足的地方,但願你們批評指正,謝謝了。
[1] Maxout Networks
[2] BinaryConnect: Training Deep Neural Networks with binary weights during propagations
[5] From Hashing to CNNs: Training Binary Weight Networks via Hashing
[6] Learning Accurate Low-Bit Deep Neural Networks with Stochastic Quantization
[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