模型剪枝論文

前言

這篇文章是ICCV 2017的一篇模型壓縮論文,題目爲《 Learning Efficient Convolutional Networks through Network Slimming》。2019年有相當多的關於YOLOv3的剪枝開源工程,他們大多數的原理都來自於這篇論文,這篇論文的思想值得仔細品讀。論文原文地址和Pytorch開源代碼地址見附錄。

基礎原理

這篇文章不同於之前介紹的那篇深度學習算法優化系列一 | ICLR 2017《Pruning Filters for Efficient ConvNets》論文直接對卷積層的權重進行剪枝。而是提出了一個針對BN層的剪枝方法,論文利用BN層的權重(也就是BN層的縮放係數)來評估輸入通道的重要程度(score),然後對score低於閾值(threshold)的通道進行過濾,之後在連接成剪枝後的網絡時已經過濾的通道的神經元就不參與連接。

具體方法

論文提供了一種簡單的方法來執行通道剪枝。這一節首先討論channel-wise稀疏化的優勢和運到的挑戰,然後介紹利用BN的縮放係數來高效的鑑別和剪枝不重要的通道。

channel-wise稀疏化

稀疏化可以在不同的級別識別,即weight-level,kernel-level,layer-level。weight-level的稀疏化有最高的靈活性和泛化性能,也可以獲得更高的壓縮比例,但它通常需要特殊的軟硬件加速器才能在稀疏模型上快速推理。而layer-level稀疏化不需要特殊的包做推理加速,但是它靈活性上不如weight-level稀疏化。事實上,只有深度夠深(超過50層),移除某些層纔會很高效。相比之下,channel-wise稀疏化在靈活性和實現上做了一個平衡,它可以被應用到任何經典的CNN或者全連接層(把每一個神經元看成一個通道),由此得到的網絡本質上也是一個瘦的網絡,可以獲得推理速度的提升。

挑戰

實現通道稀疏化需要將和一個通道有關聯的所有輸入和輸出的連接都剪掉,但是對於已經預訓練好的模型來說,不太可能做到這一點。因此這個對已經預訓練好的模型做通道剪枝效率不高,比如對預訓練好的ResNet做通道剪枝,在不損傷準確率的情況下,只能減少10%的參數量。"Learning structured sparsity in deep neural networks"這項工作通過將稀疏正則化強加到訓練目標函數中,具體來講就是採用group LASSO來是的所有卷積核的同一個通道在訓練時同時趨近於0。然而,這個方法需要額外計算新引入的和所有卷積核有關的梯度項,這加重了網絡的訓練負擔。

縮放因子和稀疏性懲罰

論文的想法是對於每一個通道都引入一個縮放因子,然後和通道的輸出相乘。接着聯合訓練網絡權重和這些縮放因子,最後將小縮放因子的通道直接移除,微調剪枝後的網絡,特別地,目標函數被定義爲:其中代表訓練數據和標籤,是網絡的可訓練參數,第一項是CNN的訓練損失函數。是在縮放因子上的乘法項,是兩項的平衡因子。論文的實驗過程中選擇,即正則化,這也被廣泛的應用於稀疏化。次梯度下降法作爲不平滑(不可導)的L1懲罰項的優化方法,另一個建議是使用平滑的L1正則項取代L1懲罰項,儘量避免在不平滑的點使用次梯度。

剪掉一個通道的本質是剪掉所有和這個通道相關的輸入和輸出連接關係,然後獲得一個窄的網絡,而不需要藉助特殊的計算軟硬件。縮放因子的作用是通道選擇,因爲這裏是將縮放因子的正則項和權重損失函數聯合優化,網絡可以自動鑑別不重要的通道,然後移除掉,幾乎不損失精度。

在這裏插入圖片描述

利用BN層的縮放因子

BN層已經被大多數現代CNN廣泛採用,做爲一種標準的方法來加速網絡收斂並獲得更好的泛化性能。BN歸一化激活值的方法給了作者設計一種簡單高效的方法的靈感,即與channel-wise縮放因子的結合。尤其是,BN層使用mini-batch的統計特性對內部激活值歸一化。和分別是BN層的輸入和輸出,B指代現在的minibatch,BN層執行下面的轉換:通常的做法就是在卷積層之後插入一個BN層,引入channel-wise的縮放/平移參數。因此,論文直接將BN層的參數作爲我們網絡瘦身的縮放因子,這樣做的又是在於沒有給網絡帶來額外的開銷。事實上,這也可能是我們能夠學習到的最有意義的做通道剪枝的縮放因子,因爲1)如果我們不使用BN層,而在卷積層之後加入一個縮放層,縮放因子的值對於評估一個通道的重要性沒有任何意義,因爲卷積層和縮放層就是一種線性變換而已。我們可以通過一方面降低縮放因子的值一方面方法卷積層的權重來使最終的結果保持不變;2)如果我們在BN層之前插入一個縮放層,縮放層的影響將完全被BN層所掩蓋;3)如果在BN層之後插入一個縮放層,那麼對於每個通道將會有兩個連續的縮放因子。

通道剪枝和微調

引入了縮放因子正則化後,訓練出來的模型許多縮放因子都會趨近於0,如Figure1所示。具體來說,假設經過卷積層之後的特徵圖維度爲,其中和分別代表特徵圖的長寬,代表特徵圖的通道數,將其送入BN層會得到歸一化後的特徵題意,特徵圖中的每一個通道都對應一組和,前面說的剪掉小的對應的通道實際上就是直接剪掉這個特徵圖對應的卷積核。至於什麼樣的算小呢?這個取決於我們爲整個網絡所有層設置的一個全局閾值,它被定義爲所有縮放因子值的一個比例,例如我們要剪掉整個網絡中70%的通道,那麼我們先對縮放因子的絕對值排個序,然後取從小到大排序的縮放因子中70%的位置的縮放因子爲閾值。這樣我們最終就可以得到一個參數較少,運行時內存小,緊湊的CNN模型了。

Muti-Pass

論文提出可以將剪枝方法從單階段的學習擴展到多階段,也即是對網絡進行多次剪枝,這樣可以得到一個壓縮程度更高的模型。

跨層連接和預激活結構怎麼處理

上面的方法可以直接用到大多數比較簡單的CNN結構,如AlexNet,VGGNet等。但對於有跨層連接和預激活設計的網絡如ResNet、DenseNet等,應該如何使用這個方法呢?對於這些網絡,每一層的輸出會作爲後續多個層的輸入,且其BN層是在卷積層之前,在這種情況下,稀疏化是在層的輸入末端得到的,一個層選擇性的接受所有通道的子集去做下一步的卷積運算。爲了在測試時節省參數和運行時間,需要放置一個通道選擇層鑑別出重要的通道。這個地方暫時沒理解不要緊,我後面會分析源碼,看到代碼就懂了。

實驗

論文分別在CIFAR、SVHN、ImageNet、MNIST數據上做了測試,訓練和測試一些細節如下:

  • 使用SGD算法從頭開始訓練網絡。

  • 在CIFAR和SVHN數據集上,minibatch爲64,epochs分別爲16020,初始的學習率爲0.1,在訓練迭代次數的50%75%時均縮小10倍。

  • 在ImageNet和MNIST數據集上,訓練的迭代次數epochs分別爲6030minibatch256,初始學習率爲0.1,在訓練迭代次數的1/32/3時縮小10倍。

  • 權重衰減率爲,所有的實驗中通道縮放因子都初始化爲0.5

  • 超參數依靠網絡搜索得到,常見的範圍是,,。對於VGG16選擇爲,對於ResNet和DenseNet,選擇爲,對於ImageNet上的,選擇爲。

  • 剪枝之後獲得了一個更窄更緊湊的模型,接下來便是微調,在CIFAR、SVHN、MNIST數據集上,微調使用和訓練相同的優化設置;在ImageNet數據集上,由於時間的限制,我們僅對剪枝後的VGG-A使用的學習率學習個epochs

CIFAR和SVHN上的結果

在這裏插入圖片描述

參數量和FLOPs

在這裏插入圖片描述

在ImageNet和MNIST上的結果

在這裏插入圖片描述

Muti-Pass結果

在這裏插入圖片描述

分析

在網絡剪枝中有2個關鍵的超參數,第一個是百分比和稀疏正則項係數,它們對模型剪枝的影響如下。

  • 剪枝百分比的影響:設置的過小,節省的資源會很有限,設置的過大,剪掉太多的通道會給準確率帶來永久性損傷,無法通過後續的微調恢復.Figure5展示了在CIFAR-10上訓練的DenseNet-40模型,。

在這裏插入圖片描述

  • 通道稀疏正則化的影響。Figure4展示的是不同取值下,縮放因子值的分佈情況。可以看到當時,幾乎所有的縮放因子值都掉到了一個接近零的區域,這個過程中可以看成是一種類似於網絡中間層的選擇過程,只有不可忽視的縮放因子對應的通道纔會被選擇。

然後論文進一步通過熱力圖對這個過程可視化,Figure6展示了VGGNet的某一層縮放因子的幅值隨着迭代次數的變化情況,每個通道開始的權重相同,縮放因子值也相同,隨着訓練的進行,一些通道的縮放因子會逐漸變大(深色),一些通道的縮放因子會逐漸變小(淺色)。

結論

這篇文章提出利用BN層的縮放係數來進行剪枝,在多個大型數據集和多個大型網絡的測試結果說明了這個方法的有效性。這個方法可以在絲毫不損失精度的條件下將分類中的SOTA網絡如VGG16,DenseNet,ResNet剪掉20倍以上的參數,是這兩天多數剪枝算法的奠基石。後面會繼續更新這個算法的一些源碼解析。

附錄

論文原文:https://arxiv.org/pdf/1708.06519.pdf

Pytorch源碼:https://github.com/Eric-mingjie/network-slimming

發佈了89 篇原創文章 · 獲贊 12 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章