前言
自從AlexNet一舉奪得ILSVRC 2012 ImageNet映像分類競賽的冠軍後,卷積神經網路(CNN)的熱潮便席捲了整個電腦視覺領域。CNN模型火速替代了傳統人工設計(hand-crafted)特徵和分類器,不僅提供了一種端到端的處理方法,還大幅度地重新整理了各個映像競賽任務的精度,更甚者超越了人眼的精度(LFWFace Service任務)。CNN模型在不斷逼近電腦視覺任務的精度極限的同時,其深度和尺寸也在成倍增長。
表1 幾種經典模型的尺寸,計算量和參數數量對比
Model
Model Size(MB)
Million
Mult-Adds
Million
Parameters
AlexNet[1]
>200
720
60
VGG16[2]
>500
15300
138
GoogleNet[3]
~50
1550
6.8
Inception-v3[4]
90-100
5000
23.2
隨之而來的是一個很尷尬的情境:如此巨大的模型只能在有限的平台下使用,根本無法移植到移動端和嵌入式晶片當中。就算想通過網路傳輸,但較高的頻寬佔用也讓很多使用者望而生畏。另一方面,大尺寸的模型也對裝置功耗和運行速度帶來了巨大的挑戰。因此這樣的模型距離實用還有一段距離。
在這樣的情形下,模型小型化與加速成了亟待解決的問題。其實早期就有學者提出了一系列CNN模型壓縮方法,包括權值剪值(prunning)和矩陣SVD分解等,但壓縮率和效率還遠不能令人滿意。
近年來,關於模型小型化的演算法從壓縮角度上可以大致分為兩類:從模型權重數值角度壓縮和從網路架構角度壓縮。另一方面,從兼顧計算速度方面,又可以劃分為:僅壓縮尺寸和壓縮尺寸的同時提升速度。
本文主要討論如下幾篇代表性的文章和方法,包括SqueezeNet[5]、DeepCompression[6]、XNorNet[7]、Distilling[8]、MobileNet[9]和ShuffleNet[10],也可按照上述方法進行大致分類:
表2 幾種經典壓縮方法及對比
Method
Compression Approach
Speed Consideration
SqueezeNet
architecture
No
Deep Compression
weights
No
XNorNet
weights
Yes
Distilling
architecture
No
MobileNet
architecture
Yes
ShuffleNet
architecture
Yes
一、SqueezeNet
1.1 設計思想
SqueezeNet是F. N. Iandola,S.Han等人於2016年的論文《SqueezeNet: AlexNet-level accuracy with 50xfewer parameters and <0.5MB model size》中提出的一個小型化的網路模型結構,該網路能在保證不損失精度的同時,將原始AlexNet壓縮至原來的510倍左右(<0.5MB)。
SqueezeNet的核心指導思想是——在保證精度的同時使用最少的參數。
而這也是所有模型壓縮方法的一個終極目標。
基於這個思想,SqueezeNet提出了3點網路結構設計策略:
策略 1.將3x3卷積核替換為1x1卷積核。
這一策略很好理解,因為1個1x1卷積核的參數是3x3卷積核參數的1/9,這一改動理論上可以將模型尺寸壓縮9倍。
策略 2.減小輸入到3x3卷積核的輸入通道數。
我們知道,對於一個採用3x3卷積核的卷積層,該層所有卷積參數的數量(不考慮偏置)為:
式中,N是卷積核的數量,也即輸出通道數,C是輸入通道數。
因此,為了保證減小網路參數,不僅僅需要減少3x3卷積核的數量,還需減少輸入到3x3卷積核的輸入通道數量,即式中C的數量。
策略 3.儘可能的將降採樣放在網路後面的層中。
在卷積神經網路中,每層輸出的特徵圖(feature map)是否下採樣是由卷積層的步長或者池化層決定的。而一個重要的觀點是:解析度越大的特徵圖(延遲降採樣)可以帶來更高的分類精度,而這一觀點從直覺上也可以很好理解,因為解析度越大的輸入能夠提供的資訊就越多。
上述三個策略中,前兩個策略都是針對如何降低參數數量而設計的,最後一個旨在最大化網路精度。
1.2 網路架構
基於以上三個策略,作者提出了一個類似inception的網路單元結構,取名為fire module。一個fire module 包含一個squeeze 卷積層(只包含1x1卷積核)和一個expand卷積層(包含1x1和3x3卷積核)。其中,squeeze層借鑒了inception的思想,利用1x1卷積核來降低輸入到expand層中3x3卷積核的輸入通道數。如圖1所示。
圖1 Fire module結構示意圖[5]
其中,定義squeeze層中1x1卷積核的數量是s1x1,類似的,expand層中1x1卷積核的數量是e1x1, 3x3卷積核的數量是e3x3。令s1x1 < e1x1+ e3x3從而保證輸入到3x3的輸入通道數減小。SqueezeNet的網路結構由若干個fire module組成,另外文章還給出了一些架構設計上的細節:
· 為了保證1x1卷積核和3x3卷積核具有相同大小的輸出,3x3卷積核採用1像素的zero-padding和步長
· squeeze層和expand層均採用RELU作為啟用函數
· 在fire9後採用50%的dropout
· 由於全串連層的參數數量巨大,因此借鑒NIN[11]的思想,去除了全串連層而改用global average pooling。
1.3 實驗結果
表3 不同壓縮方法在ImageNet上的對比實驗結果 [5]
上表顯示,相比傳統的壓縮方法,SqueezeNet能在保證精度不損(甚至略有提升)的情況下,達到最大的壓縮率,將原始AlexNet從240MB壓縮至4.8MB,而結合Deep Compression後更能達到0.47MB,完全滿足了移動端的部署和低頻寬網路的傳輸。
此外,作者還借鑒ResNet思想,對原始網路結構做了修改,增加了旁路分支,將分類精度提升了約3%。
1.4 速度考量
儘管文章主要以壓縮模型尺寸為目標,但毋庸置疑的一點是,SqueezeNet在網路結構中大量採用1x1和3x3卷積核是有利於速度的提升的,對於類似caffe這樣的深度學習架構,在卷積層的前向計算中,採用1x1卷積核可避免額外的im2col操作,而直接利用gemm進行矩陣加速運算,因此對速度的最佳化是有一定的作用的。然而,這種提速的作用仍然是有限的,另外,SqueezeNet採用了9個fire module和兩個卷積層,因此仍需要進行大量常規卷積操作,這也是影響速度進一步提升的瓶頸。
二、DeepCompression
Deep Compression出自S.Han 2016 ICLR的一篇論文《Deep Compression: Compressing Deep NeuralNetworks with Pruning, Trained Quantization and Huffman Coding》。該文章獲得了ICLR 2016的最佳論文獎,同時也具有裡程碑式的意義,引領了CNN模型小型化與加速研究方向的新狂潮,使得這一領域近兩年來湧現出了大量的優秀工作與文章。
2.1 演算法流程
與前面的“架構壓縮派”的SqueezeNet不同,Deep Compression是屬於“權值壓縮派”的。而兩篇文章均出自S.Han團隊,因此兩種方法結合,雙劍合璧,更是能達到登峰造極的壓縮效果。這一實驗結果也在上表中得到驗證。
Deep Compression的演算法流程包含三步,如圖2所示:
圖2 Deep Compression Pipeline[6]
1) Pruning(權值剪枝)
剪枝的思想其實早已在早期論文中可以窺見,LeCun等人曾經就利用剪枝來稀疏網路,減小過擬合的風險,提升網路泛化性。
圖3是MNIST上訓練得到的LeNet conv1卷積層中的參數分布,可以看出,大部分權值集中在0處附近,對網路的貢獻較小,在剪值中,將0值附近的較小的權值置0,使這些權值不被啟用,從而著重訓練剩下的非零權值,最終在保證網路精度不變的情況下達到壓縮尺寸的目的。
實驗發現模型對剪枝更敏感,因此在剪值時建議逐層迭代修剪,另外每層的剪枝比例如何自動選取仍然是一個值得深入研究的課題。
圖3 LeNet conv1層權值分布圖
2) Quantization(權值量化)
此處的權值量化基於權值聚類,將連續分布的權值離散化,從而減小需要儲存的權值數量。
· 初始化聚類中心,實驗證明線性初始化效果最好;
· 利用k-means演算法進行聚類,將權值劃分到不同的cluster中;
· 在前向計算時,每個權值由其聚類中心表示;
· 在後向計算時,統計每個cluster中的梯度和將其反傳。