當前位置:
首頁 > 新聞 > 模型剪枝,不可忽視的推斷效率提升方法

模型剪枝,不可忽視的推斷效率提升方法

選自TowardsDataScience


作者:Ranjeet Singh機器之心編譯參與:路剪枝是常用的模型壓縮方法之一,本文對剪枝的原理、效果進行了簡單介紹。

目前,深度學習模型需要大量算力、內存和電量。當我們需要執行實時推斷、在設備端運行模型、在計算資源有限的情況下運行瀏覽器時,這就是瓶頸。能耗是人們對於當前深度學習模型的主要擔憂。而解決這一問題的方法之一是提高推斷效率。


大模型 => 更多內存引用 => 更多能耗

剪枝正是提高推斷效率的方法之一,它可以高效生成規模更小、內存利用率更高、能耗更低、推斷速度更快、推斷準確率損失最小的模型,此類技術還包括權重共享和量化。深度學習從神經科學中汲取過靈感,而剪枝同樣受到生物學的啟發。

隨著深度學習的發展,當前最優的模型準確率越來越高,但這一進步伴隨的是成本的增加。本文將對此進行討論。

挑戰 1:模型規模越來越大

我們很難通過無線更新(over-the-air update)分布大模型。

模型剪枝,不可忽視的推斷效率提升方法

來自 Bill Dally 在 NIPS 2016 workshop on Efficient Methods for Deep Neural Networks 的演講。

挑戰 2:速度

模型剪枝,不可忽視的推斷效率提升方法

使用 4 塊 M40 GPU 訓練 ResNet 的時間,所有模型遵循 fb.resnet.torch 訓練。

訓練時間之長限制了機器學習研究者的生產效率。

挑戰 3:能耗

AlphaGo 使用了 1920 塊 CPU 和 280 塊 GPU,每場棋局光電費就需要 3000 美元。

模型剪枝,不可忽視的推斷效率提升方法

這對於移動設備意味著:電池耗盡

對於數據中心意味著:總體擁有成本(TCO)上升

解決方案:高效推斷演算法

  • 剪枝
  • 權重共享
  • 低秩逼近
  • 二值化網路(Binary Net)/三值化網路(Ternary Net)
  • Winograd 變換

剪枝所受到的生物學啟發

人工神經網路中的剪枝受啟發於人腦中的突觸修剪(Synaptic Pruning)。突觸修剪即軸突和樹突完全衰退和死亡,是許多哺乳動物幼年期和青春期間發生的突觸消失過程。突觸修剪從公出生時就開始了,一直持續到 20 多歲。

模型剪枝,不可忽視的推斷效率提升方法

Christopher A Walsh. Peter Huttenlocher (1931–2013). Nature, 502(7470):172–172, 2013.

修剪深度神經網路

模型剪枝,不可忽視的推斷效率提升方法

[Lecun et al. NIPS 89] [Han et al. NIPS 15]

神經網路通常如上圖左所示:下層中的每個神經元與上一層有連接,但這意味著我們必須進行大量浮點相乘操作。完美情況下,我們只需將每個神經元與幾個其他神經元連接起來,不用進行其他浮點相乘操作,這叫做「稀疏」網路。

稀疏網路更容易壓縮,我們可以在推斷期間跳過 zero,從而改善延遲情況。

如果你可以根據網路中神經元但貢獻對其進行排序,那麼你可以將排序較低的神經元移除,得到規模更小且速度更快的網路。

速度更快/規模更小的網路對於在移動設備上運行它們非常重要。

如果你根據神經元權重的 L1/L2 範數進行排序,那麼剪枝後模型準確率會下降(如果排序做得好的話,可能下降得稍微少一點),網路通常需要經過訓練-剪枝-訓練-剪枝的迭代才能恢復。如果我們一次性修剪得太多,則網路可能嚴重受損,無法恢復。因此,在實踐中,剪枝是一個迭代的過程,這通常叫做「迭代式剪枝」(Iterative Pruning):修剪-訓練-重複(Prune / Train / Repeat)。

想更多地了解迭代式剪枝,可參考 TensorFlow 團隊的代碼:https://github.com/tensorflow/model-optimization/blob/master/tensorflow_model_optimization/g3doc/guide/pruning/pruning_with_keras.ipynb

權重修剪

將權重矩陣中的多個權重設置為 0,這對應上圖中的刪除連接。為了使稀疏度達到 k%,我們根據權重大小對權重矩陣 W 中的權重進行排序,然後將排序最末的 k% 設置為 0。

f = h5py.File("model_weights.h5","r+")for k in [.25, .50, .60, .70, .80, .90, .95, .97, .99]: ranks = {} for l in list(f[『model_weights』])[:-1]: data = f[『model_weights』][l][l][『kernel:0』] w = np.array(data) ranks[l]=(rankdata(np.abs(w),method= "dense")—1).astype(int).reshape(w.shape) lower_bound_rank = np.ceil(np.max(ranks[l])*k).astype(int) ranks[l][ranks[l]<=lower_bound_rank] = 0 ranks[l][ranks[l]>lower_bound_rank] = 1 w = w*ranks[l] data[…] = w

單元/神經元修剪

將權重矩陣中的多個整列設置為 0,從而刪除對應的輸出神經元。為使稀疏度達到 k%,我們根據 L2 範數對權重矩陣中的列進行排序,並刪除排序最末的 k%。

f = h5py.File("model_weights.h5","r+")for k in [.25, .50, .60, .70, .80, .90, .95, .97, .99]: ranks = {} for l in list(f["model_weights"])[:-1]: data = f["model_weights"][l][l]["kernel:0"] w = np.array(data) norm = LA.norm(w,axis=0) norm = np.tile(norm,(w.shape[0],1)) ranks[l] = (rankdata(norm,method="dense")—1).astype(int).reshape(norm.shape) lower_bound_rank = np.ceil(np.max(ranks[l])*k).astype(int) ranks[l][ranks[l]<=lower_bound_rank] = 0 ranks[l][ranks[l]>lower_bound_rank] = 1 w = w*ranks[l] data[…] = w

隨著稀疏度的增加、網路刪減越來越多,任務性能會逐漸下降。那麼你覺得稀疏度 vs. 性能的下降曲線是怎樣的呢?

我們來看一個例子,使用簡單的圖像分類神經網路架構在 MNIST 數據集上執行任務,並對該網路進行剪枝操作。

下圖展示了神經網路的架構:

模型剪枝,不可忽視的推斷效率提升方法

參考代碼中使用的模型架構。

模型剪枝,不可忽視的推斷效率提升方法

稀疏度 vs. 準確率。讀者可使用代碼復現上圖(https://drive.google.com/open?id=1GBLFxyFQtTTve_EE5y1Ulo0RwnKk_h6J)。

模型剪枝,不可忽視的推斷效率提升方法

總結

很多研究者認為剪枝方法被忽視了,它需要得到更多關注和實踐。本文展示了如何在小型數據集上使用非常簡單的神經網路架構獲取不錯的結果。我認為深度學習在實踐中用來解決的許多問題與之類似,因此這些問題也可以從剪枝方法中獲益。

參考資料本文相關代碼:https://drive.google.com/open?id=1GBLFxyFQtTTve_EE5y1Ulo0RwnKk_h6JTo prune, or not to prune: exploring the efficacy of pruning for model compression, Michael H. Zhu, Suyog Gupta, 2017(https://arxiv.org/pdf/1710.01878.pdf)Learning to Prune Filters in Convolutional Neural Networks, Qiangui Huang et. al, 2018(https://arxiv.org/pdf/1801.07365.pdf)Pruning deep neural networks to make them fast and small(https://jacobgil.github.io/deeplearning/pruning-deep-learning)使用 Tensorflow 模型優化工具包優化機器學習模型(https://www.tensorflow.org/model_optimization)

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 機器之心 的精彩文章:

谷歌高級研究員Nature發文:避開機器學習三大「坑」

TAG:機器之心 |