吳衛(wèi)賢,趙 鳴,黃曉丹
(長江大學 計算機科學學院,湖北 荊州 434023)
近年來,卷積神經(jīng)網(wǎng)絡已成為各種計算機視覺任務的主導方法,如圖像分類、目標檢測、語義分割。大規(guī)模數(shù)據(jù)集、高端現(xiàn)代GPU 和新的網(wǎng)絡體系結構允許開發(fā)前所未有的大型CNN模型。例如,AlexNet[1]、VGGNet[2]、GoogleNet[3]和Resnet[4],目標檢測任務中的Rcnn[5]、FastRcnn[6]、FasterRcnn[7],以及最近熱門的YOLOv3[8]所使用的darknet 模型。圖像網(wǎng)絡分類的卷積神經(jīng)網(wǎng)絡模型已經(jīng)從8 層發(fā)展到100 多層甚至更多層[9]。從一個大型的網(wǎng)絡開始訓練很重要,因為這種模型具有一定的高性能,可以安全地刪除一組冗余參數(shù)而不會顯著地損失準確率[10]。相比從頭開始訓練一個小的網(wǎng)絡模型,這通常是一種更好的方法,因此目前常見的用于模式識別的卷積神經(jīng)網(wǎng)絡模型越來越大型化。在一個152 層卷積層的Resnet 模型中有6 000 萬以上的參數(shù),在輸入一個224*224 的圖像時,其計算量超過了20G FLOPs,這對于移動端和物聯(lián)網(wǎng)設備應用是負擔不起的[11]。因此,需要對這些大型卷積神經(jīng)網(wǎng)絡模型進行壓縮,降低其體積和計算成本,并且在此基礎上對其精度進行一定程度的提升。
卷積神經(jīng)網(wǎng)絡模型剪枝方法分為結構化和非結構化剪枝。結構化是修剪整個過濾器,非結構化剪枝則是直接對每層參數(shù)進行單獨剪枝。為了解決卷積神經(jīng)網(wǎng)絡模型占用空間和計算量過大的問題,不少研究者想通過對神經(jīng)網(wǎng)絡進行剪枝以盡可能地壓縮體積、提升速度。早期,Hassibi[12]利用二階泰勒展開選擇參數(shù)并進行剪枝,以改善訓練和泛化能力;Han 等[13]通過權值大小確定修剪訓練后網(wǎng)絡中的不重要連接,以減少網(wǎng)絡所需參數(shù);CP 算法采用LASSO 回歸方式選擇剪枝通道并進行逐層剪枝[14];SFP 采用動態(tài)剪枝方法,主要依靠權重的范數(shù),保留BN 層的偏置系數(shù)[15]。上述剪枝方法中都出現(xiàn)了剪枝后模型精度下降的問題,使得模型在剪枝后的識別效果不佳。
鑒于此,本文提出一種結合剪枝和數(shù)據(jù)量化的模型壓縮方法。該方法首先通過對卷積神經(jīng)網(wǎng)絡中常見的卷積層和全連接層中訓練后的權值進行重要性評價;然后,對權值及相應通道進行剪枝以達到降低卷積神經(jīng)網(wǎng)絡模型體積的目的;最后,對剩余權值進行量化處理,降低卷積神經(jīng)網(wǎng)絡計算成本,并對量化后的模型進行一定微調,以恢復精度。
目前,針對卷積神經(jīng)網(wǎng)絡的剪枝方法主要分為兩種:權值剪枝和濾波器剪枝。兩個方法都是針對卷積層中的卷積通道進行剪枝,但判定方法不同,一個是通過權值判定,另一個是通過濾波器判定。網(wǎng)絡模型優(yōu)化通常是針對模型占用空間大小、模型識別準確率、模型識別速度3 個目標。在目前圖形識別的CNN 網(wǎng)絡剪枝方法中,最為典型的是將CNN 網(wǎng)絡BN 層中的γ 參數(shù)作為網(wǎng)絡剪枝的縮放因子[16]。由于BN 層具有加速訓練和有效減少過擬合現(xiàn)象的作用,因此已經(jīng)被大部分常用的圖像識別卷積神經(jīng)網(wǎng)絡模型所使用。在引入縮放因子γ 之后,通過對每個卷積通道后特征圖的特征值γ 進行排序,然后根據(jù)排序結果設定剪枝的閾值。即當前通道特征圖的γ 參數(shù)小于該閾值,則對當前特征圖對應的卷積核進行剪枝處理??s放因子扮演的是通道選擇的角色,縮放因子的正則項和權重損失函數(shù)聯(lián)合優(yōu)化,網(wǎng)絡自動鑒別不重要的通道并將其移除掉,幾乎不影響網(wǎng)絡的泛化性能。這樣可以人為設定對整個卷積神經(jīng)網(wǎng)絡模型的剪枝幅度。例如,設定的閾值在所有卷積核的所有閾值中排列第60%,則可以減掉60%卷積核,只保留γ 參數(shù)大于60%的特征圖所對應的卷積核。對于不同的圖像識別和不同的神經(jīng)網(wǎng)絡模型,閾值設定會有很大區(qū)別。然而,這種全局閾值設定方法有一定的局限性。當剪枝百分比數(shù)值設定過小,則節(jié)省資源非常有限,剪枝效果不佳;當剪枝百分比數(shù)值設定過大,則會出現(xiàn)準確率大幅度下降的現(xiàn)象,這種準確率的損失無法通過后期微調加以恢復。
在神經(jīng)網(wǎng)絡模型壓縮加速方法中,通過對參數(shù)的量化壓縮參數(shù)量,并達到加速神經(jīng)網(wǎng)絡、減少計算成本的目的[17]。然而在量化過程中參數(shù)的壓縮會導致準確率下降。為了減少參數(shù)量化帶來的準確率損失,Han 等[13]提出了一種共享權重和通過權重進行索引編碼以減小權重數(shù)量和存儲空間的方法。該方法是指定一系列權值,然后將這些權值進行數(shù)值共享,最后所有的權值都只能從指定的權值中進行選擇,而這些指定的權值則通過K-means 聚類初始化質心。K-means 質心的初值對最終結果影響較大,通過實驗對比最終選擇均勻量化方法完成質心初始化。均勻量化的結果輸出是通過所有權值的最大值和最小值之間的均勻間隔實現(xiàn)。確定質心之后再確定量化閾值,一個權值簇里的所有權值都由這個質心代替,最后對質心進行微調以恢復精度。參數(shù)量化之后對于神經(jīng)網(wǎng)絡的壓縮有一定效果,但是在量化質心的確定方法上仍有不適用的網(wǎng)絡。一些神經(jīng)網(wǎng)絡模型可能更適合按密度量化,比如識別目標單一的神經(jīng)網(wǎng)絡[18]。該方法只對卷積神經(jīng)網(wǎng)絡中的參數(shù)量化方法進行了優(yōu)化,因此在選擇最優(yōu)閾值的方法中還有一定的優(yōu)化空間。
通過分析網(wǎng)絡模型中權值參數(shù)值的分布可以得知權值參數(shù)的重要程度。本文使用的評價方法是對權值參數(shù)的部分和值和標準差值進行評估。將參數(shù)值為0 的權值對應的卷積層和通道層視為對最終結果影響不大的層,再將這些層作剪枝處理。目前用于圖像識別的卷積神經(jīng)網(wǎng)絡模型中都加入BN 層以加速訓練進程[19],BN 層于2015 年被提出,具有防止梯度爆炸和加速網(wǎng)絡收斂的作用。它一般位于卷積層之后,可以對卷積層之后的特征圖進行歸一化操作。如果BN 層只是單單在卷積層之后作歸一化,然后直接將數(shù)據(jù)送入下一層,網(wǎng)絡將無法學習特征分布。因為BN 層之后還有激活層,如果BN 層之后的數(shù)據(jù)大部分小于0,則經(jīng)過RELU 激活層之后將失去大部分特征值。因此,BN 層通過優(yōu)化縮放系數(shù)γ和偏移系數(shù)β對數(shù)據(jù)進行歸一化處理,使得網(wǎng)絡能夠學習輸出的特征分布。BN 層的實現(xiàn)方式是讓Zin和Zout作為BN 層的輸入和輸出,β表示當前最小塊,BN 層執(zhí)行以下轉換:
其中,μβ和σ2分別為當前層中輸入值的均值和方差,即:
最后可以得到一組均值為β的新數(shù)據(jù)。因為BN 層中的γ 縮放因子對應每個卷積層中的特征圖都有一個不同的值,因此BN 層中的γ縮放因子可以當作當前層對于整個模型準確率貢獻的評價系數(shù)。γ值越大,說明當前層對于模型的準確率貢獻越大,反之貢獻越小。實際上,γ可以視為BN 層每個通道的權重。如果當前輸入通道對應的權重γ出現(xiàn)γ=0 或γ≈0 的情況,特征圖對應的輸出通道即全為常數(shù)0,不會再對接下來的運算產(chǎn)生影響。因此,可以通過對BN 層中的縮放因子γ的數(shù)值評估,進而衡量特征圖中每個通道對于模型整體精準度的貢獻,當γ=0 或者γ≈0 時,可以認為當前通道對模型的影響可以忽略,即可剪去γ對應特征圖的通道,最終剪去γ=0 對應的上下卷積層的卷積核,同時壓縮模型體積,減少計算量。
上述方式獲得的γ值可能會因為準確率的要求高而導致剪枝率較低,因此對于剩余的權值參數(shù)需作進一步壓縮處理。目前用于圖像識別的卷積神經(jīng)網(wǎng)絡模型使用的參數(shù)一般為32 位浮點數(shù)型。而高精度浮點數(shù)型的計算成本大于整型數(shù)據(jù),因此可以選用對剩余參數(shù)進行量化的方法,大幅度壓縮剩余權值參數(shù)量,減少計算成本。神經(jīng)網(wǎng)絡對量化的實現(xiàn)需要將卷積、矩陣乘法、激活函數(shù)、池化、拼接等操作轉換為等價的8 位整數(shù)操作,然后在操作的前后分別加上量化和反量化操作,將input 從浮點數(shù)轉換成8位整數(shù),反量化操作將output 從8 位整數(shù)轉回浮點數(shù)。
將剩余的網(wǎng)絡權值由高精度的32 位浮點float32 轉化成低精度的8 位定點數(shù)int8,使得模型大小有效變小,但是精度影響不大,運行速度加快。具體做法是將傳入的float32 型數(shù)據(jù)轉換為int8 傳入卷積層,對應卷積層中的權值也轉換成int8 類型。并且,在此過程中還可以同時將BN層融入卷積層,一起作量化處理。量化操作需要將一組float 輸入轉換成uint8(0~255),先求出這組輸入的最小值min 和最大值max,然后對每個輸入數(shù)據(jù),可根據(jù)如下公式求出其量化值與反量化值。
量化后引入的量化誤差為(max -min)/255。本文將float32 數(shù)據(jù)類型量化成定點數(shù)據(jù)類型的公式如下:
其中,s是量化間隔,n是量化的bit 數(shù),φx是=0 時對應的量化值,即零點。rfmax和rfmin是float 型數(shù)據(jù)的最大值和最小值。在tensorflow 的框架中,[]表示取整函數(shù):
卷積神經(jīng)網(wǎng)絡設計卷積計算,卷積神經(jīng)網(wǎng)絡經(jīng)過量化之后,卷積操作計算原理如下:
其中,xq、ωq、ɑq分別是量化之后的輸入、權重、卷積輸出;sx、sω、sɑ分別是輸入、權重、卷積輸出的尺度因子;φx、φω、φɑ分別是輸入、權重、卷積輸出的零點。
對于真實值0 的量化誤差問題,其解決方式是直接量化成一個整數(shù)qzero表示,如果量化值qzero所表示的值和真實值0 之間有一定誤差,則對一些操作有較大影響。在卷積或者池化層進行padding 時需要在邊緣補0,Relu 激活層需要截斷小于0 的輸入,對于不同的庫,所使用的量化策略會不同。Tensorflow 庫中量化方法分為有符號輸入和無符號輸入兩種情況。有符號輸入則調整min 和max,max=MAX(-min,max),min=-max,這樣范圍就會成為對稱的形式,[min,max]被量化至[-127,127]。無符號則min=0,將[0,max]量化至[0,255]。在nnlib 中因為不區(qū)分是否為有符號,因此統(tǒng)一量化到0~255。
本文提出的結合剪枝和參數(shù)量化的模型壓縮剪枝方法為:先通過訓練集將模型訓練至收斂,然后通過BN 層參數(shù)和整個網(wǎng)絡結構中的卷積層和全連接層中的權值對整個網(wǎng)絡結構進行剪枝,再對剪枝之后剩余參數(shù)進行量化操作。具體流程為:①設置網(wǎng)絡模型訓練集;②將對應的網(wǎng)絡模型訓練至收斂;③將收斂的網(wǎng)絡模型進行基于BN 層參數(shù)和基于整個網(wǎng)絡結構中卷積層和全連接層的權值參數(shù)剪枝;④對剪枝之后剩余參數(shù)進行量化操作;⑤微調訓練,以恢復精度;⑥對最后得到的模型輸出相關數(shù)據(jù)并檢測精度。
為了最大程度地降低網(wǎng)絡模型的準確率損失,需要對模型中的所有γ 參數(shù)進行排序并設定一個閾值。對低于閾值的γ 參數(shù)對應的特征圖和卷積核進行剪枝處理。而這里需要一個對閾值進行設定的最佳值,使得該閾值能夠對整個網(wǎng)絡模型在剪枝程度最大化的同時還能保留網(wǎng)絡模型的精確度。針對這一問題,在進行不同閾值設定后,得到不同閾值所對應的網(wǎng)絡模型大小和準確率,設定全部γ 值的3%為步長。對網(wǎng)絡模型精確度與網(wǎng)絡模型剪枝程度取一個中間值,使得該閾值既能夠滿足剪枝目標還保留有一定的準確率。該閾值的獲取方式是通過設定一個目標準確率,舍棄低于目標準確率的閾值,然后在符合目標準確率結果的閾值中取最大值為設定閾值。具體流程如圖1 所示。
Fig.1 Pruning process圖1 剪枝流程
剩余參數(shù)的量化過程為:首先輸入float 型的參數(shù),然后獲得參數(shù)的最大最小值,根據(jù)其最大最小值對參數(shù)進行量化,然后使用量化后的參數(shù)對整個卷積層、全連接層、池化層,以及批量歸一化層中的數(shù)據(jù)進行計算操作,對最終獲得的輸出值進行反量化操作,最后將其輸出。量化訓練流程如圖2 所示。
Fig.2 Quantitative training process圖2 量化訓練流程
構建的卷積神經(jīng)網(wǎng)絡是以Lenet 為基準,有3 個卷積層,2 個全連接層。其中,每個卷積層之間由一個池化層相連,第3 個池化層和第1 個全連接層之間通過Flatten 相連。Flatten 函數(shù)的作用是將池化層輸入過來的多維數(shù)據(jù)轉化成一維數(shù)據(jù)并輸入到全連接層,使用最大池化的方式建立池化層。全連接層所有節(jié)點都與上層節(jié)點連接,然后綜合其提取的特征圖。由于全連接的特性需要,全連接層也含有最大參數(shù)量。全連接層主要負責邏輯推斷,參數(shù)經(jīng)過訓練后進行調整以達到最后收斂效果。全連接層會鏈接卷積層的輸出,然后通過將三維矩陣轉變成向量的方法去除空間信息,是一種全卷積操作。其中,全連接層和卷積層中的Kernel 都使用L1 正則化方法,以防止過擬合。卷積層將輸入數(shù)據(jù)加權后進行卷積計算,加上偏置參數(shù)biases,經(jīng)過Relu 激活函數(shù)轉化成輸出值輸入到下一層。卷積層推理如圖3 所示。
Fig.3 Convolutional inference process圖3 卷積推理過程
此外,在每個全連接層和全連接層的激活函數(shù)之間,加入一個BN 層,對數(shù)據(jù)進行批量標準化,防止數(shù)據(jù)收斂過快導致神經(jīng)元出現(xiàn)大規(guī)模死亡現(xiàn)象。經(jīng)過卷積層和全連接層計算后的數(shù)據(jù)會經(jīng)過Dropout 層,防止模型參數(shù)與訓練數(shù)據(jù)出現(xiàn)過擬合現(xiàn)象。輸出的數(shù)據(jù)經(jīng)過Logits 層調整輸入Softmax 函數(shù)進行分類輸出處理后,得到最終分類結果和最后的卷積神經(jīng)網(wǎng)絡模型。整體卷積神經(jīng)網(wǎng)絡結構如圖4 所示。
Fig.4 Lenet structure圖4 Lenet 結構
本次實驗中,CPU 是i5-4210H,無顯卡加速。使用MNIST 手寫數(shù)字集進行訓練,構建成的卷積神經(jīng)網(wǎng)絡以Lenet 為基準,增加了卷積層和池化層的結構,有3 個卷積層,2 個全連接層。
對每個卷積層和全連接層中的權值參數(shù)進行剪枝,需先對訓練完成后模型中的各卷積層和全連接層的權值進行重要性評估。因此,分別獲取covn1、covn2、covn3、fc1、fc2 中權值的各系數(shù)值分布圖,以便對各層中的權值進行評估。在進行權值重要性評估后,一部分低于閾值的權重會在模型中刪除,這些權重對應的卷積通道也會在訓練過程中被忽略掉。方法是將其中的數(shù)據(jù)直接置0 處理,得到各卷積層和全連接層中的權值在訓練完成后的分布圖,如圖5—圖9 所示。
Fig.5 Weight distribution of convolution layer 1圖5 卷積層1 權值分布
Fig.6 Weight distribution of convolution layer 2圖6 卷積層2 權值分布
Fig.7 Weight distribution of convolution layer 3圖7 卷積層3 權值分布
Fig.8 Weight distribution of fully connected layer 1圖8 全連接層1 權值分布
Fig.9 Weight distribution of fully connected layer 2圖9 全連接層2 權值分布
根據(jù)各卷積層和全連接層中的權值分布情況分別進行不同的通道剪枝處理??梢缘弥?,Conv1 中有10 個Kernel 的權重和為0,可以認定這部分對整個模型無貢獻,可以將這部分Kernel 刪除,為了保證Kernel 數(shù)為4 的倍數(shù),刪除8 個Kernel。同理,在Conv2 中刪除16 個Kernel。在Conv3中由于權重和都很小,故做剪枝的依據(jù)是Conv3 中的權重標準差,根據(jù)Conv3 中標準差的分布,刪除8 個低于閾值的Kernel。后面的全連接層fc1 和fc2 層進行同樣操作,再根據(jù)BN 層的γ 值進行剪枝,最后對所有剪枝結果進行求和,并將所有需要剪枝的通道進行剪枝。權值標準偏差分布如圖10—圖12 所示。
Fig.10 Standard deviation distribution of weights(1)圖10 權值標準偏差分布(1)
Fig.11 Weight standard deviation distribution(2)圖11 權值標準偏差分布(2)
Fig.12 Weight standard deviation distribution(3)圖12 權值標準偏差分布(3)
完成剪枝后對權值數(shù)據(jù)進行量化操作,將原數(shù)據(jù)類型為float32 的權值量化為int8 類型,進行模型計算后再還原成float32 類型數(shù)據(jù)。得到的網(wǎng)絡模型精確度和原模型相當,但速度上相對原模型提升了。對比方法中,CP 算法采用LASSO 回歸方式進行逐層剪枝,精度下降很多。SFP 采用的是動態(tài)剪枝方法,主要依靠權重范數(shù),保留了BN 層的偏置系數(shù),也會引起精度下降[20-21]。各剪枝方法結果如表1 所示。
Table 1 Results of each pruning method表1 各剪枝方法結果
本文主要針對卷積神經(jīng)網(wǎng)絡提出了一種剪枝和權值量化的方法。該方法主要對卷積神經(jīng)網(wǎng)絡中常見的卷積層和全連接層中訓練后的權值大小進行判別,然后通過對權值及相應通道的剪枝以達到降低卷積神經(jīng)網(wǎng)絡模型體積的目的。在進行權值剪枝和通道修剪后對剩余權值進行量化處理,降低卷積神經(jīng)網(wǎng)絡計算成本,并對量化后的模型進行一定微調,以恢復精度,使得模型精度不變但計算速度提升,從而實現(xiàn)了模型計算成本低于原模型并且計算效率高于原模型。剪枝方法基于模型卷積層和全連接層中的權重分布以及BN 層的縮放因子進行,而量化則是在剪枝過程后對所有參數(shù)和數(shù)據(jù)進行數(shù)據(jù)量化,將數(shù)據(jù)類型簡化,從而降低計算成本。這樣雙層壓縮后的模型能更加適用于移動端和嵌入式設備,相對于其他傳統(tǒng)方法,其在模型大小壓縮、準確率及推理時間上均有一定提升。但此方法依然存在一些不足:在卷積層和全連接層中對需要剪枝的Kernel 進行篩選的方法依然存在改善空間,例如可以使用濾波器排序或者濾波器聚類,對相似度高的濾波器卷積層進行剪枝,使用權值共享方法減少模型計算量。量化方法中如何在盡量壓縮數(shù)據(jù)大小的情況下依然使得模型識別精度保持不變尚有優(yōu)化空間,有待進一步研究。