一些量化(quantization)技巧
對象:對權重量化,對特征圖量化(神經元輸出),對梯度量化(訓練過程中)
過程:在inference網絡前傳,在訓練過程(反傳)
一步量化(僅對權重量化),
兩步量化(對神經元與特征圖量化,第一步先對feature map進行量化,第二步再對權重量化)。
32位浮點和16位浮點存儲的時候,
第一位是符號位,中間是指數位,后面是尾數。
英特爾在NIPS2017上,提出了把前面的指數項共享的方法。
這樣可以把浮點運算,轉化為尾數的整數定點運算,加速網絡訓練。
分布式訓練梯度量化:
對權重數值進行聚類,量化的思想非常簡單。
CNN參數中數值分布在參數空間,
通過一定的划分方法,總是可以划分稱為k個類別。
通過儲存這k個類別的中心值,或者映射值,壓縮網絡的儲存。
量化可以分為
Low-Bit Quantization(低比特量化)、
Quantization for General Training Acceleration(總體訓練加速量化)和
Gradient Quantization for Distributed Training(分布式訓練梯度量化)。
由於在量化、特別是低比特量化實現過程中,由於量化函數的不連續性,在計算梯度的時候,會產生一定的困難。
對此,阿里巴巴把低比特量化,轉化成ADMM可優化的目標函數,從而由ADMM來優化。
另一個角度思考,使用哈希把二值權重量化,再通過哈希求解。
用聚類中心數值,代替原權重數值,配合Huffman編碼,具體可包括標量量化或乘積量化。
如果只考慮權重自身,容易造成量化誤差很低,但分類誤差很高的情況。
Quantized CNN優化目標是重構誤差最小化。
可以利用哈希進行編碼,映射到同一個哈希桶中的權重,共享同一個參數值。
聚類例子:
例如下面這個矩陣。
1.2 1.3 6.1
0.9 0.7 6.9
-1.0 -0.9 1.0
設定類別數k=3,通過kmeans聚類。得到:
A類中心:1.0 ,映射下標:1
B類中心:6.5 ,映射下標:2
C類中心:-0.95 ,映射下標:3
儲存矩陣可以變換為(距離哪個中心近,就用中心的下標替換):
1 1 2
1 1 2
3 3 1
提出需要對量化后的值進行重訓練,挽回一點丟失的識別率。
基本上所有壓縮方法都有損,重訓練還是比較必要的。
深度神經網絡壓縮 Deep Compression
為了進一步壓縮網絡,考慮讓若干個權值共享同一個權值,需要存儲的數據量也大大減少。
采用kmeans算法來將權值進行聚類,在每一個類中,所有的權值共享該類的聚類質心,
最終存儲一個碼書和索引表。
1.對權值聚類
采用kmeans聚類算法,通過優化所有類內元素,到聚類中心的差距(within-cluster sum of squares ),確定最終的聚類結果。
2. 聚類中心初始化
常用的初始化,包括3種:
a) 隨機初始化。
即從原始數據,隨機產生k個觀察值,作為聚類中心。
b) 密度分布初始化。
現將累計概率密度CDF的y值,分布線性划分,
根據每個划分點的y值,找到與CDF曲線的交點,再找到該交點對應的x軸坐標,作為初始聚類中心。
c) 線性初始化。
將原始數據的最小值到最大值之間的線性划分,作為初始聚類中心。
三種初始化方式的示意圖,如下所示:

由於大權值比小權值更重要(參加HanSong15年論文),線性初始化方式,能更好地保留大權值中心,文中采用這一方式,后面的實驗結果,驗證了這個結論。
3. 前向反饋和后項傳播
前向時需要將每個權值,用對應的聚類中心代替,后向計算每個類內的權值梯度,
將梯度和反傳,用來更新聚類中心。
如圖:

共享權值后,就可以用一個碼書和對應的index來表征。
假設原始權值用32bit浮點型表示,量化區間為256,即8bit,共有n個權值,量化后需要存儲n個8bit索引和256個聚類中心值,可以計算出壓縮率compression ratio:
r = 32*n / (8*n + 256*32 )≈4
如果采用8bit編碼,至少能達到4倍壓縮率。
參考鏈接:
