【網絡優化】超輕量級網絡SqueezeNet算法詳解

轉自:
http://blog.csdn.net/shenxiaolu1984/article/details/51444525

Iandola, Forrest N., et al. “SqueezeNet: AlexNet-level accuracy with 50x fewer parameters and< 1MB model size.” arXiv preprint arXiv:1602.07360 (2016).

本文考察了深度學習中除了精度之外的另一個重要因素:模型大小。有兩處值得學習的亮點
- 給出了一個分類精度接近AlexNet1的網絡,模型縮小510倍
- 歸納了縮小模型尺寸時的設計思路

複習:卷積層的參數個數。
輸入通道ci
以AlexNet第一個卷積層爲例,參數量達到:3*11*11*96 = 34848。

作者提供的源碼請戳這裏,各個主流框架均有實現。

基礎模塊

在當下許多深度學習的文章中都使用了模塊化的設計思想,遠者有AlexNet中反覆出現的conv+relu+pool模式;近者有用於人體姿態分析的Stacked Hourglass算法(參看這篇博客

本文使用的基礎模塊稱爲fire:
這裏寫圖片描述
包含三個卷積層(藍色),步長均爲1。分爲squeeze和expand兩部分,分別壓縮和擴展數據(灰色矩形)的通道數。
expand部分中,兩個不同核尺寸的結果通過串接層(黃色)合併輸出。

fire模塊有三個可調參數
- s1: squeeze部分,1×1卷積層的通道數
- e1: expand部分,1×1卷積層的通道數
- e3: expand部分,3×3卷積層的通道數

輸入輸出尺寸相同。輸入通道數不限,輸出通道數爲e1+e3
在本文提出的SqueezeNet結構中,e1=e3=4s1

網絡結構

整個網絡包含10層。
第1層爲卷積層(藍色),縮小輸入圖像,提取96維特徵。
第2到9層爲fire模塊(紅色),每個模塊內部先減少通道數(squeeze)再增加通道數(expamd)。每兩個模塊之後,通道數會增加。
在1,4,8層之後加入降採樣的max pooling(綠色),縮小一半尺寸。
第10層又是卷積層(藍色),爲小圖的每個像素預測1000類分類得分。
最後用一個全圖average pooling(綠色)得到這張圖的1000類得分,使用softmax函數歸一化爲概率。
這裏寫圖片描述

這是一個全卷積網絡,避免瞭如今越來越不受待見的全連接層。由於最後一層提供了全圖求平均操作,可以接受任意尺寸的輸入。當然,輸入還是需要歸一化到大致相當的尺寸,保持統一尺度。

全連接層的參數多,對性能提升幫助不大,現在往往被pooling代替。

這個網絡達到了和AlexNet相當的分類精度,但模型縮小了50倍:

architecture model size top-1 accuracy top-5 accuracy
AlexNet 240MB 57.2% 80.3%
SqueezeNet 4.8MB 57.5% 80.3%

參數壓縮

在網絡結構確定的前提下,還可以進一步壓縮其中的參數。本文使用了第二作者的Deep Compression2方法,包含裁剪,量化,編碼三個手段。

AlexNet中卷積層的weight、bias以及全連層參數分佈如下所示。可以看出:全連層參數和卷積層weight佔絕大多數,卷積層的bias只佔極小部分。

這裏寫圖片描述

參數壓縮針對卷積層的weight和全連層參數。每一層的參數單獨壓縮。

裁剪

由前圖可以看出,絕大部分參數集中在0附近。

裁剪操作的第一步,把網絡中所有絕對值小於門限的參數置0;非零參數再次訓練進行優化。
這裏寫圖片描述

第二步,用下標方法表示剩餘的參數:記錄非零參數值和其在數組中的下標。

論文聲稱使用compressed sparse row方法進行壓縮,實際源碼中並沒有。

下標中相鄰元素差值不會超過數組長度。爲了進一步壓縮,把下標表示成差分形式。

例:稀疏矩陣

0500080600300000
\begin{bmatrix} 0 & 0 & 0 & 0 \\ 5 & 8 & 0 & 0 \\ 0 & 0 & 3 & 0 \\

A = [ 5 8 3 6 ], IA = [4 5 10 13]
差分形式:IA = [4 1 5 3]

差分形式的IA動態範圍大大縮小,可以用較少的比特數(4)進行編碼。
當差值超出當前比特數能表示的範圍後,在中間插入一個值爲0的“非零元素”。

量化(Quantization)

首先,用K均值把所有參數聚成2n個類。
之後,保持同一聚類內參數相等,對網絡進行調優。在梯度下降時,歸於同一類的節點的梯度相加,施加到該類的聚類中心上。
最後,使用n比特編碼的聚類中心替代原有參數。
這裏寫圖片描述

Deep Compression論文:卷積層,n=8; fc層,n=4。SqueezeNet中全部爲卷積層,n=6。

問題:同類節點的梯度爲什麼相加?不是應該求平均嗎?

編碼(Huffman Encoding)

現在需要存儲的主要數據有二:編碼爲n位的非零數據取值;編碼爲4位的非零元素下標。
這兩者的分佈都不均勻,可以使用Huffman編碼進一步壓縮存儲。源碼中沒有實現。

模型存儲結構

壓縮後的二進制模型按層存儲,當前層有nz個非零元素,分爲如下4個部分:

name type size note
codebook float32 2^n 碼書
bias float32 輸出通道數 無壓縮
spm_stream uint8 nz18/n+1 非零元素取值,n位編碼$
ind_stream uint8 nz18/4+1 非零元素下標,4位編碼$

經過Deep Compression壓縮,模型進一步縮小了10倍,仍然保持原有精度。

architecture model size top-1 accuracy top-5 accuracy
AlexNet 240MB 57.2% 80.3%
SqueezeNet 4.8MB 57.5% 80.3%
SqueezeNet+DeepCompression 0.66MB 57.5% 80.3%

設計思路

本文還花費較大篇幅介紹了設計網絡時的心得體會,頗具啓發性。

參數組合

每層fire模塊的三個參數如果單獨設計,需要嘗試的組合太多。需要使用超參數進行規劃
- 首個fire模塊中包含base個3×3核;每隔freq個fire模塊,3×3模塊增加incre個。
- expand部分中,3×3核佔expand中核總數比例爲pct
- squeeze中核數與expand中核數比例爲sr

sr和pct增大可以提升準確率,但模型尺寸增大。本文取sr=0.125,pct=0.5。

大尺度結構

在通道數相同的層之間,添加旁路相加結構可以明顯提升準確性(源碼未實現)。
這裏寫圖片描述

帶有卷積的旁路結構可以在任意層之間添加,準確性提升較小,模型增大。

這裏寫圖片描述

壓縮:有的放矢

問:如何確定哪些層不重要?
答:逐個將每一層50%參數置零,查看模型性能。對性能影響不大的層,不重要。

問:不重要的怎麼辦?
答:Deep Compression中使用較少比特數表達。

問:重要的層呢?
答:增加expand部分中的輸出通道數,進一步提升準確率。

SDS訓練法

本文還有一個神奇的發現:使用裁剪之後的模型爲初始值,再次進行訓練調優所有參數,正確率能夠提升4.3%。
稀疏相當於一種正則化,有機會把解從局部極小中解放出來。這種方法稱爲DSD(dense->sparse->dense)。


  1. A. Krizhevsky, I. Sutskever, and G. E. Hinton. Imagenet classification with deep convolutional neural networks. In NIPS, 2012.
  2. Iandola, Forrest N., et al. “SqueezeNet: AlexNet-level accuracy with 50x fewer parameters and< 1MB model size.” arXiv preprint arXiv:1602.07360 (2016).
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章