【技術綜述】為了壓縮CNN模型,這幾年大家都幹了什麼
本文於2017-3-12日首發於公眾號《有三AI》,很多技術已經更新了,請大家及時關注
如果從2006年算,深度學習從產生到火爆已經
十年了
,在工業界已經產生了很多落地的應用。現在網路的深度已經可達1000層以上,下面我們關注一個問題:
這些年大家是
怎麼“壓榨”CNN模型的。
首先回顧一下幾個經典模型,我們主要看看
深度和caffe模型大小。
#FormatImgID_3##FormatImgID_4#
當然,在實際應用中,各自調試出的version會有出入,網路的大小也不止和深度有關係,此處想說明的問題是:好像
模型大小(引數量)和模型的深淺並非是正相關。
下面言歸正傳,這裡要講的壓榨主要是將模型變小,以便在ARM,FPGA,ASIC等儲存空間有限的平臺應用。
從2個方面進行回顧。第一條是
經典模型的設計路線
,可以看得出本身就在不斷壓縮模型。第二條是在
網路結構基本不變
的情況下,對
模型引數的壓縮
。
1.經典模型進階路
Fully connect to local connect
這裡我們仍然放這張經典的比較圖,從最早的
全連線神經網路到卷積神經網路
本身就是一場大的引數壓縮革命。
按照全連線神經網路的思想,1000×1000的影象,如果隱藏層也是同樣大小(1000*1000個)的神經元,那麼由於神經元和影象每一個畫素連線,則會有引數1000×1000×1000×1000。光是一層網路,就已經有10^12個引數。
而如果採用卷積神經網路,則由於
權值共享
,對於同樣多的隱藏層,假如每個神經元只和輸入10×10的區域性patch相連線,且卷積核移動步長為10,則引數為:1000×1000×100,降低了4個數量級。
至於為什麼可以這麼做,讀者可以自己去關注卷積神經網路的由來,主要原理在於
影象的區域性patch可以與全圖有類似的統計特性
。
這第一招,也是最厲害的一招,一舉將神經網路的引數減小許多個數量級,才能有深度學習的發展。
#FormatImgID_7##FormatImgID_8#
NIN 1×1卷積使用
Alexnet[1]是一個8層的卷積神經網路,有約60M個引數,如果採用32bit float存下來有200M。值得一提的是,AlexNet中仍然有3個全連線層,其引數量佔比引數總量超過了90%。
NIN[2]是一個4層的網路結構,其直接對標物件就是AlexNet,那麼為什麼模型大小隻有前者的1/10呢?
除了去掉了全連線層外(
這也是模型變小的關鍵
),提出了
1×1的卷積核
,後來被廣泛用於GoogLeNet[3]和ResNet[4]。
下面舉一個例子,假如輸入為28×28×192,輸出feature map通道數為128。那麼,直接接3×3卷積,引數量為3×3×192×128=221184。
如果先用1×1卷積進行降維到96個通道,然後再用3×3升維到128,則引數量為:1×1×192×96+3×3×96×128=129024,引數量減少一半。雖然引數量減少不是很明顯,但是如果1×1輸出維度降低到48呢?則引數量又減少一半。對於上千層的大網路來說,效果還是很明顯了。
移動端對模型大小很敏感。下載一個100M的app與50M的app,首先使用者心理接受程度就不一樣。
到此你可能有一個疑問?
原則上降低通道數是會降低效能的,這裡為什麼卻可以降維呢?
筆者沒有能力去完整回答這個問題,但是我們可以從很多embedding技術,比如PCA等中得到思考,
降低一定的維度可以去除冗餘資料,損失的精度其實很多情況下都不會對我們解決問題有很大影響。
當然了該文章最重要的貢獻
應該是透過這種內嵌的結構,在通道之間組合資訊從而增強了網路的非線性表達能力
。
一句話:1×1卷積,在 GoogLeNet Inception v1[3]以及後續版本,ResNet[4]中都大量得到應用,有減少模型引數的作用。
卷積拆分
(1) VGG
VGG可以認為是AlexNet的增強版,
兩倍的深度,兩倍的引數量
。不過,也提出了一個模型壓縮的trick,後來也被廣泛借鑑。
那就是,對於5×5的卷積,使用兩個3×3的卷積串聯,可以得到同樣的感受野,但引數量卻有所降低,為3×3×2/(5×5)=0。72,同樣的道理3個3×3卷積代替一個7×7,則引數壓縮比3×3×3/(7×7)=0。55,降低一倍的引數量,也是很可觀的。
(2) GoogLeNet[3]
GoogleLet Inception v2就借鑑了VGG上面的思想。而到了Inception V3[3]網路,則更進一步,將
大卷積分解(Factorization)為小卷積
。
比如7×7的卷積,拆分成1×7和7×1的卷積後。引數量壓縮比為1×7×2/(7×7)=0。29,比上面拆分成3個3×3的卷積,更加節省引數了。
問題是這種
非對稱的拆分,居然比對稱地拆分成幾個小卷積核改進效果更明顯
,增加了特徵多樣性。
只能說
後來的Resnet就不說了,也是上面這些trick。到現在,
基本上網路中都是3×3卷積和1×1卷積
,5×5很少見,7×7幾乎不可見。
(3) SqueezeNet[7]
squeezenet將上面1×1降維的思想進一步拓展。透過減少3×3的filter數量,將其一部分替換為1×1來實現壓縮。
具體的一個子結構如下:
一個squeeze模組加上一個expand模組
,使squeeze中的通道數量,少於expand通道數量就行。
舉上面那個例子,假如輸入為M維,如果直接接3×3卷積,輸出為8個通道,則引數量:M×3×3×8。
如果按上圖的做法,則引數量為M×1×1×3+3×4×1×1+3×4×3×3,壓縮比為:(40+M)/24M, 當M比較大時,約0。04。
文章最終將
AlexNet壓縮到原來1/50
,而效能幾乎不變。
據我所知的在卷積結構上做文章的,基本上都在這裡,當然怎麼訓練出本來就小的模型不算。
2.模型引數壓縮方法
2.1 SVD分解法
有研究表明,
一層的weights,可以透過其子集進行精確預測
,所以可以使用奇異值分解(SVD分解)來對
每一層進行低秩近似
,下面只提一下基本原理和結論。
原理:對於一個m×k維的實數矩陣W,其可以進行奇異值分解為W=USV,其中U維度為m×m,S維度為m×k,V維度為k×k。S是
非負實數對角矩陣
,如果
將其對角線的值降序排列並發現其值衰減很快
,則只需要前面幾維就能保持W的絕大多數資訊不丟失,這也是PCA的原理。
假如只保留t維,那麼原來的計算複雜度為O(m×k),現在則變成了O(m×t+t×t+t×k),對於足夠小的t,O(m×t+t×t+t×k)遠小於O(m×k)。
不過這個方法實際的
模型壓縮比並不明顯
,在文章[8]中為2~3的左右,加速比也是2~3左右。所以同類的方法,就不再深究。
2.2 權重引數量化與剪枝
下面是近兩年比較有代表性的研究,主要是透過
權重剪枝,量化編碼
等方法來實現模型壓縮。其實最早也有直接對每個權重獨立量化的研究[9],但是效果顯然是不如下面的結果的。
(1) DeepCompresion
這是2016 ICLR最佳論文。文章早期的工作,是Network Pruning,就是去除網路中權重低於一定閾值的引數後,重新finetune一個稀疏網路。在這篇文章中,則進一步添加了量化和編碼,思路很清晰簡單如下。
(1) 網路剪枝:移除不重要的連線;
(2) 權重量化與共享:讓許多連線共享同一權重,使原始儲存整個網路權重變為只需要儲存碼本(有效的權重)和索引;
(3) 霍夫曼編碼:更高效利用了權重的有偏分佈;
第一部分很好理解,就是如下流程:
(1) 普通網路訓練;
(2) 刪除權重小於一定閾值的連線得到稀疏網路;
(3) 對稀疏網路再訓練;
霍夫曼編碼是一種成熟的編碼技巧與cnn無關。下面只說說第二部分,這是從文章摘取的圖,對於一個4×4的權值矩陣,量化權重為4階(-1。0,0,1。5,2。0)。
那麼索引表就是:
0:-1。0
1:0
2:1。5
3:2。0
對weights採用cluster index進行儲存後,原來需要
16個32bit float
,現在只需要
4個32bit float碼字,與16個2bit uint索引
,引數量為原來的(16×2+4×32)/(16×32)=0。31。
儲存是沒問題了,那如何對量化值進行更新呢?事實上,文中僅對碼字進行更新。如上圖:將
索引相同的地方梯度求和乘以學習率,疊加到碼字
。
這樣的效果,就等價於
不斷求取weights的聚類中心
。原來有成千上萬個weights,現在經過一個有效的聚類後,每一個weights都用其聚類中心進行替代,作者的研究表明這樣並不會降低網路的效果。而聚類的迭代過程,透過BP的反向傳播完成,不得不說,想法非常plain和beautiful,難怪能得best paper。
看下錶就知道最終的壓縮效率非常可觀,把500M的VGG幹到了11M。
文中還比較瞭如果只用剪枝或者只用量化對結果的影響,表明各自都對壓縮比低於一定閾值時很敏感,如下。而
combine兩個trick,則在壓縮比達到5%時,仍然效能不降
。當然了還有如
卷積層對壓縮比比全連線層更敏感
等結論,感興趣可以自己去讀。
(2) Binarized Neural Networks
如果說deep compression是
float到uint的壓縮
,那麼這篇就是
uint到bool
的壓縮了。前者只是將weights進行量化,而這個,權重只有+1或者-1二值。
將
權重和每層的啟用值全部
二值化。如此一來大部分數學運算都是位運算。
二值化的方法也很簡單,文章提到了兩種,第一種就是符號函式,即x>0,則f(x)=1,x<0,則f(x)=-1。另一種是以一定的機率賦值,是不是想起了dropout?文中就是,只有在啟用函式時,才採用第二種二值化方法,其餘都採用符號函式。
其實大問題就是一個,
符號函式的導數並不連續
,那怎麼進行梯度傳播?文中將sign(x)進行放鬆,在-1到1之間採用了線性函式。
f(x) = max(-1,min(1,x))
主要事項:
(1)
在訓練過程中還是需要儲存實數的引數的
。
(2)在進行
權重引數更新時,裁剪超出[-1,1]的部分
,保證權重引數始終是[-1,1]之間的實數。
而在
使用引數時,則將引數進行二值化
。
最終效果到底如何?在一些比較小的資料集,比如MNIST,CIFAR-10上,精度稍微有所下降但不明顯,模型大學降低為原來的1/32,32bit的float變成1 bit。對於時間代價可見下圖,第2個直方圖是MNIST資料集的結果,作者的最佳化將速度相對於cublas提升了約3。4倍,而精度不變(第三個直方圖)。
類似的還有什麼
XORnet,YodaNet
,感興趣的可以去選讀。
就這麼多,本文主要關注的是
模型壓縮
,這跟
計算量壓縮
不等價,
跟加速
也不等價,希望不要搞混淆。
如有疏漏,錯誤,請批評指正,謝謝!
時隔一年,以mobilenet為代表的很多技術已經更新了,我會找時間再來補上,等不及的大家自己去學習吧。
【1】Krizhevsky A, Sutskever I, Hinton G E。 Imagenet classification with deep convolutional neural networks[C]//Advances in neural information processing systems。 2012: 1097-1105。
【2】Lin M, Chen Q, Yan S。 Network in network[J]。 arXiv preprint arXiv:1312。4400, 2013。
【3】Szegedy C, Liu W, Jia Y, et al。 Going deeper with convolutions[C]//Proceedings of the IEEE Conference on Computer Vision and Pattern Recognition。 2015: 1-9。
【4】He K, Zhang X, Ren S, et al。 Deep residual learning for image recognition[C]//Proceedings of the IEEE Conference on Computer Vision and Pattern Recognition。 2016: 770-778。
【5】Simonyan K, Zisserman A。 Very deep convolutional networks for large-scale image recognition[J]。 arXiv preprint arXiv:1409。1556, 2014。
【6】Szegedy C, Vanhoucke V, Ioffe S, et al。 Rethinking the inception architecture for computer vision[C]//Proceedings of the IEEE Conference on Computer Vision and Pattern Recognition。 2016: 2818-2826。
【7】Iandola F N, Han S, Moskewicz M W, et al。 SqueezeNet: AlexNet-level accuracy with 50x fewer parameters and< 0。5 MB model size[J]。 arXiv preprint arXiv:1602。07360, 2016。
【8】Denton E L, Zaremba W, Bruna J, et al。 Exploiting linear structure within convolutional networks for efficient evaluation[C]//Advances in Neural Information Processing Systems。 2014: 1269-1277。
【9】Vanhoucke V, Senior A, Mao M Z。 Improving the speed of neural networks on CPUs[C]//Proc。 Deep Learning and Unsupervised Feature Learning NIPS Workshop。 2011, 1: 4。
【10】Han S, Mao H, Dally W J。 Deep compression: Compressing deep neural networks with pruning, trained quantization and huffman coding[J]。 arXiv preprint arXiv:1510。00149, 2015。
【11】Hubara I, Courbariaux M, Soudry D, et al。 Binarized neural networks[C]//Advances in Neural Information Processing Systems。 2016: 4107-4115。