模型壓縮:Deep Compression

《Deep Compression Compressing Deep Neural Networks with Pruning, Trained Quantization and Huffman coding》是ICLR-2016的 best paper,斯坦福的由HanSong等人共同發表。
arXiv(發音: 美[ˈɑ:rkaɪv]) :https://arxiv.org/abs/1510.00149

前言:

從文章標題就知道,這是一篇關於模型壓縮的論文,整體步驟分爲三部:pruning ,quantization, coding。也就是,剪枝、量化、編碼。熟悉通信理論的同學,對量化、編碼再熟悉不過了,因此,針對於網絡模型的操作僅僅體現在pruning上,而之後的量化和編碼,可以歸爲信息存儲技術。

模型壓縮最終的目的不外就兩個:
1. 存儲問題 ,在不怎麼損失網絡性能的前提下,儘可能的佔用更少的內存,以至於可以部署在移動端;
2. 速度問題 ,在不怎麼損失網絡性能的前提下,儘可能的提高inference時的速度,以達到實時處理。

然而,本文提出的方法,僅僅針對問題1.存儲問題 !對於inference的速度,並沒得到什麼提升,原文1.introduction中有一句話單獨設爲一段:
“Our goal is to reduce the storage and energy required to run inference on such large networks so they can be deployed on mobile devices.”

正文:
講解deep compression的步驟,以及實驗結果以及結論。

第一步:weight pruning

整個Pruning分三小步:

step1. 正常的訓練網絡,得到壓縮之前的pre-train model
step2. 真正意義的pruning:對權值設定一個閾值,小於閾值的權值就被置 0
step3. 重新訓練經過pruning之後的網絡

pruning的方法是對權值設置一個閾值,小於閾值的權值就“移除”,簡單除暴。但是如何設置這個閾值呢?本文中並沒有介紹,因爲這個方法是引用另外一篇論文(同樣是HanSong老師的論文)—— 《Learning both weights and connections for efficient neural networks》
因此,在研讀完本文之後,非常有必要去拜讀這篇論文。

經過權值剪枝,網絡就是一個稀疏結構的網絡了,因爲有很多權值小於設定的閾值,被置爲“0”了嘛。而針對稀疏結構,CSR (compressed sparse row) or CSC(compressed sparse column )是非常高效的存儲方式。因此,對權值剪枝之後的模型,就採用CSR的方式來存儲。

CSR簡介(截取自:http://blog.csdn.net/may0324/article/details/52935869):
假設有一個原始稀疏矩陣A
這裏寫圖片描述

CSR可以將原始矩陣表達爲三部分,即AA,JA,IC

這裏寫圖片描述

其中,
AA中的元素值 代表 矩陣A中所有非零元素值;

JA中的元素值表示的是序號,是矩陣A中每行第一個非零元素在AA中的位置序號(即AA中紅框標出來的元素的序號)。而A有五行,JA卻有6個元素,可以發現最後一個元素值是 14,其實就是A中非零元素個數(13)+1 ;

IC是AA中每個元素對應的列號,長度爲a=13。

注:a表示A矩陣非零元素個數,n表示矩陣行數。
所以將一個稀疏矩陣轉爲CSR表示,需要的空間爲2*a+(n+1)個 ,同理CSC也是類似。

第二步:trained quantization and weight sharing

量化,即一個數用幾個bit來表示,用的bit數越大,佔的內存越多,精度也就越高,但是到底需要多少bit就可達到我們所需的網絡性能呢?依據實驗結果是6~8bit。

weight sharing,即是將同一層當中所有的權值進行聚類(K-means聚類),屬於同一類的那些權值全部使用該類的聚類中心作爲權值。通過weight sharing,只需要存儲聚類中心,以及Index,即每個權值對應屬於哪個類。因此經過權值壓縮比率爲:
這裏寫圖片描述

其中N爲該層的連接數,也就是權值數量,b表示使用的bit數;
Nlog2(K)表示存儲所有Index所佔bit數,Kb表示存儲聚類中心所需的bit數,K即表示要聚爲多少類。
在這裏,K的選取需要通過實驗來確定,在本文實驗,AlexNet的卷積層中,K=256,即一個Index需要log2(256)=8 bit 來存儲,在全連接層中,K=32,一個Index需要佔用5 bit

經過量化和weight sharing之後,需要對網絡再進行fine-tune,fine-tune時,權值的更新是針對聚類中心進行更新,具體公式爲:

這裏寫圖片描述

其中,Iij表示Wij所屬聚類中心的Index,Ck表示第k個聚類中心。對一個聚類中心進行更新的值即對該類內的權值的梯度進行求和。

下面舉例說明量化,weight sharing, 權值更新 這三個步驟。
假設有一層4個input,4個output的全連接層,並且每個權值佔32 bit,則該層權值如下:
這裏寫圖片描述

第一步,量化,這裏假設仍舊採取32bit來存儲一個權值
**第二步,weight sharing。**weight sharing的第一步就是先聚類,這裏設K=4,也就是聚爲4類,可得:
這裏寫圖片描述

原本對每個權值需要佔用32bit,經過聚類之後,每個權值只需要記錄所屬哪一個聚類中心即可,因爲K=4,因此每個index需要 lob2(4) =2 bit; 由於仍舊採取32bit來存儲權值,則右邊的centroids(聚類中心) 共需要 4*32 = 128bit來存儲。

則經過量化和weight sharing,壓縮比率爲: 16 32 / (16 log2(4) + 16 *32 ) = 3.2倍

經過了量化和weight sharing,就需要對網絡fine-tune了,前面說到,對權值的更新是針對centroids更新,而所需要更新的值,是對屬於該centroids的權值的梯度的求和。具體如下:

這裏寫圖片描述

以index=3(藍色)爲例,index=3的權值分別是2.09、2.12、1.92、1.87,這四個權值對應的梯度爲-0.03、0.12、0.02、-0.07,對這四個梯度求和得 -0.03+0.12+0.02-0.07 = 0.04,再將0.04乘以學習率,從而得到 聚類中心index=3的修改值,則fine-tuned centroids 爲1.96

這裏還有一個問題就是,如何對聚類中心進行初始化?文假設了三種初始化方法,並且進行實驗,最終敲定,採用Linear的方法對聚類中心初始化, 另外兩種初始化方法分別是Forgy(隨機)和Density-based(基於概率)。爲什麼選用Linear?

因爲兩點:
1.權值分佈的特點;
2. 較大的權值具有較大的影響力。

先看看權值分佈的特點,權值分佈可以看到是服從高斯分佈的

這裏寫圖片描述

從圖可知,較大的權值所佔的比例是較小的,然而較大的權值具有較大的影響力,若採用Forgy或Density-based,都無法確保 大權值 保留有一定的比例。因此採用Linear方法進行初始化。

第三步: Huffman coding

哈夫曼編碼就屬於信息論裏面的內容了,哈夫曼編碼就是依據字符出現概率來編碼。
下圖爲Alexnet全連接層 權值的分佈 以及 偏置的分佈:
這裏寫圖片描述

實驗分析之壓縮幾十倍從何而來?

最後來分析一下模型壓縮的結果,看看到底怎麼把Alexnet壓縮了35倍,怎麼對VGG-16壓縮了49倍的。

先看Alexnet
這裏寫圖片描述

先看左邊黃色框,表示各層權值的數量,右邊黃色框,是經過P+Q+H後,所剩下參數所佔的存儲空間!
注意了,左邊的是權值數量,右邊表示存儲空間。

原始總計61M參數,一個權值採用32bit=4B,則共計佔61M*4B =244MB 字節 ,經過P+Q+H之後剩下 244MB* 2.88% = 7.0272MB,這個數纔是論文開篇描述的 240MB壓縮至6.9MB;

現在來看看壓縮掉的236.9728MB存儲空間當中,全連接層貢獻了多少。
這裏寫圖片描述

全連接層共計壓縮存儲空間爲: 148.3672 + 66.3272 +15.064 = 229.7584 MB
佔總壓縮存儲空間的比例爲:229.7584 / (244-7.0272) ≈ 96.96%

再看看VGG-16

這裏寫圖片描述

這裏寫圖片描述

原模型共計佔內存 138M * 4B = 552MB, 壓縮的存儲空間爲: 552 * (1- 2.05%) = 540.684
全連接層共計壓縮存儲空間爲: 407.468 + 67.15 + 15.1616 = 489.7796 MB
佔總壓縮存儲空間的比例爲:489.7796 / 540.684 ≈ 90.58%

不論AlexNet還是VGG-16,都是含有三個全連接層,尤其是FC6,均佔了總參數量的61% 以上,因此模型壓縮的倍數如此客觀,也是有原因的,畢竟 FC6 FC7太“臃腫”了!

也正因爲全連接的問題,雖然模型壓縮了幾十倍,但是速度幾乎沒有得到改善。

因此要提升inference速度,還是要在卷積層上面下功夫啊。

實驗分析之極致量化

一個權值到底應該量化至何種程度呢? 本文就conv layer及 fc layer 分別進行了 1bit 至 8bit的實驗,實驗結果如下:

這裏寫圖片描述

從圖中可發現,不論是conv layer 還是 fc layer,低於4bit,性能會迅速下降;
本文最終對conv layer 採用8bit進行編碼, fc layer採用5bit;

這裏有個小插曲,熟悉SqueezeNet的朋友,肯定被它論文標題給驚住了,
《SqueezeNet: AlexNet-level accuracy with 50x fewer parameters and <0.5MB model size

< 0.5MB, 論文一出,可是夠吸引眼球的。不過這個論文題目是V4版,再V1版當中,可不是<0.5MB的,而是 <1MB:
《SqueezeNet: AlexNet-level accuracy with 50x fewer parameters and <1MB model size

如何從<1MB 到 < 0.5MB的呢? 請看下圖:
這裏寫圖片描述

原來就是在編碼長度上下了功夫~ 從8bit縮減到6bit~~~

小結:

  1. deep compression是解決存儲問題,對於速度問題幾乎沒獲得改善;
  2. 權值剪枝還得看另外一篇論文:learning both weights and connection for efficient neural network
  3. 存儲空間問題,主要還是在全連接層,若要改善inference速度,需要在卷積層下功夫
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章