閒話模型壓縮之網絡剪枝(Network Pruning)篇

一、背景

今天,深度學習已成爲機器學習中最主流的分支之一。它的廣泛應用不計其數,無需多言。但衆所周知深度神經網絡(DNN)有個很大的缺點就是計算量太大。這很大程度上阻礙了基於深度學習方法的產品化,尤其是在一些邊緣設備上。因爲邊緣設備大多不是爲計算密集任務設計的,如果簡單部署上去則功耗、時延等都會成爲問題。即使是在服務端,更多的計算也會直接導致成本的增加。人們正在從各個角度試圖克服這個問題,如這幾年如火如荼的各處神經網絡芯片,其思路是對於給定的計算任務用專用硬件加速。而另一個思路是考慮模型中的計算是不是都是必要?如果不是的話,有沒有可能簡化模型來減少計算量和存儲佔用。本文主要談的就是這一類方法,稱爲模型壓縮(Model compression)。它是軟件方法,應用成本低,而且與硬件加速方法並不矛盾,可以相互加成。細分來說,模型壓縮又可分很多方法,如剪枝(Pruning)、量化(Quantization)、低秩分解(Low-rank factorization)、知識蒸餾(Knowledge distillation)。每一子類方法展開都可以是很大的話題,所以我們一個個來,今天主要只限於pruning方法。

它基於一個假設,或者說目前的共識。就是DNN的過參數化(Over-parameterization)。我們知道,深度神經網絡與其它很多機器學習模型一樣,可分爲訓練和推理兩個階段。訓練階段是根據數據學習模型中的參數(對神經網絡來說主要是網絡中的權重);推理階段中將新數據喂進模型,經過計算得出結果。而過參數化是指訓練階段我們需要大量的參數來捕捉數據中的微小信息,而一旦訓練完成到了推理階段,我們並不需要這麼多的參數。這樣的假設就支持我們可以在部署前對模型進行簡化。模型壓縮中的pruning和quantization兩類方法正是基於這樣的前提。模型簡化後有很多好處,包括但不限於:1)最直接的好處就是計算量的減小,從而使計算時間更少,功耗更小。2)Memory footprint變小,可以放到更低端的設備上跑。還有個額外的性能好處是本來需要既慢又耗電的DRAM參與,現在有可能放在SRAM就搞定。3)Size更小的包有利於應用發佈和更新。如一些手機市場會對應用的大小有限制,另外也有利於車OTA升級。

有了『理論』上的啓發後,下一個問題就是how。顯然不能拿了模型瞎剪,因爲這樣精度可以會下降得很厲害以至無法接受。當然,也有情況會在pruning後精度提高的,這說明原模型過似合(overfit)了,pruning起到了regularization的作用。就一般情況下講,核心問題是成如何有效地裁剪模型且最小化精度的損失。其實這不是一個新的問題,對於神經網絡的pruning在上世紀80年代末,90年代初左右就有研究了。如論文《Comparing Biases for Minimal Network Construction with Back-Propagation》提出了magnitude-based的pruning方法,即對網絡中每個hidden unit施加與其絕對值相關的weight decay來最小化hidden unit數量。又如上世紀90年代初當時經典的論文《Optimal brain damage》與《Second order derivatives for network pruning: Optimal Brain Surgeon》分別提出OBD和OBS方法,它們基於損失函數相對於權重的二階導數(對權重向量來說即Hessian矩陣)來衡量網絡中權重的重要程度,然後對其進行裁剪。但因爲當時的大環境下,神經網絡(那時沒有deep neural network,只有neural network,或爲區分稱爲shadow neural network)並不是機器學習的一個特別主流的分支,因此之後的很長一段時間也沒有大量開枝散葉,但他們對問題的梳理定義和解決問題思路對二十多年後的很多工作產生了深遠的影響。到了2012年,我們都知道深度學習一戰成名,大放異彩。之後刷榜之風興起且愈演愈烈,大家的注意力就是提高精度。於是大趨勢就是不斷地加深加重網絡以提高精度,ImageNet準確率每年都創新高。2015-16年期間,Hang Song等人發表了一系列對深度神經網絡進行模型壓縮的工作。如《Learning both weights and connections for efficient neural networks》,《EIE: Efficient inference engine on compressed deep neural network》。其中《Deep Compression: Compressing Deep Neural Networks with Pruning, Trained Quantization and Huffman Coding》獲得了ICLR 2016的best paper。其中對當時經典網絡AlexNet和VGG進行了壓縮。結合pruning,quantization和huffman encoding等多種方法,將網絡size壓縮了幾十倍,性能獲得成倍的提升。其中對於pruning帶來的精度損失,使用了iterative pruning方法進行補償,可以讓精度幾乎沒有損失。這讓大家意識到DNN參數冗餘程度如此之大,可榨油水如此之多。之後這幾年,模型壓縮領域變得越豐富,越來越多的相關工作衍生出各種玩法。

從network pruning的粒度來說,可以分爲結構化剪枝(Structured pruning)和非結構化剪枝(Unstructured pruning)兩類。早期的一些方法是基於非結構化的,它裁剪的粒度爲單個神經元。如果對kernel進行非結構化剪枝,則得到的kernel是稀疏的,即中間有很多元素爲0的矩陣。除非下層的硬件和計算庫對其有比較好的支持,pruning後版本很難獲得實質的性能提升。稀疏矩陣無法利用現有成熟的BLAS庫獲得額外性能收益。因此,這幾年的研究很多是集中在structured pruning上。Structured pruning又可進一步細分:如可以是channel-wise的,也可以是filter-wise的,還可以是在shape-wise的。

二、方法介紹

Network pruning的基本思想就是剪裁最不重要的部分。形式化地,可以表達成:
minwL(D;w)+λw0 \min_w L(D; w) + \lambda ||w||_0
或者將參數裁剪寫成約束優化形式:
minwL(D;w)s.t.w0κ \min_w L(D; w) \quad \text{s.t.} ||w||_0 \leq \kappa
由於L0範數的存在,讓該問題成爲一個組合優化問題。由於是NP-hard問題,顯然不能硬來。

分類

其中一個最簡單的思路就是貪心法,或稱爲saliency-based方法。即按重要性排序,然後將不重要的部分去除。然而問題來了,就是重要性如何衡量。

  • 一個最簡單的啓發就是按參數(或特徵輸出)絕對值大小來評估重要性,然後用貪心法將那部分幹掉,這類稱爲magnitude-based weight pruning。如2016年經典論文《Pruning Filters for Efficient ConvNets》中把權重的絕對值作爲衡量其重要性的手段。但訓練出來的權重如果不稀疏不利於pruning怎麼辦,常用的辦法是在訓練時loss中加regularizer,尤其是L1 regularizer,從而使得權重稀疏化。對於structured pruning來說,我們想獲得結構化的稀疏權重,因此常用group LASSO來得到結構化的稀疏權重,如2015-16年的論文《Learning Structured Sparsity in Deep Neural Networks》和《Sparse Convolutional Neural Networks》等。2017年論文《Learning Efficient Convolutional Networks Through Network Slimming》通過一種巧妙的方法,基於BN(Batch Normalization)層的廣泛使用,在BN層加入channel-wise scaling factor 並對之加L1 regularizer使之稀疏,然後裁剪scaling factor值小的部分對應權重。另外,重要性評估也可以針對activation(激活值,即激活函數的輸出),當然就算是針對activation最後也會體現在權重的裁剪上。一般來說,像Relu這樣的激活函數會傾向產生稀疏的activation;而權重相對而言不太容易是稀疏的(當前,如前所說,我們可以通過regularizer這種外力使它變得稀疏)。從這種意義上說,activation更適合pruning。如2016年論文《Network Trimming: A Data-Driven Neuron Pruning Approach towards Efficient Deep Architectures》中提出採用Average Percentage of Zeros,即APoZ來衡量activation的重要性。它定義爲activation中爲0的比例。

  • 上面方法有個假設就是參數絕對值越小,其對最終結果影響越小。我們稱之爲’‘smaller-norm-less-important’'準則。然而這個假設未必成立(如2018年的論文《Rethinking the Smaller-Norm-Less-Informative Assumption in Channel Pruning of Convolution Layers》有對其的討論)。第二種思路就是考慮參數裁剪對loss的影響。其實前面提到的始祖級的OBD和OBS就是屬於此類。但這兩種方法需要計算Hessian矩陣或其近似比較費時。近年來有一些基於該思路的方法被研究和提出。如2016年論文《Pruning Convolutional Neural Networks for Resource Efficient Transfer Learning》也是基於Taylor expansion,但採用的是目標函數相對於activation的展開式中一階項的絕對值作爲pruning的criteria。這樣就避免了二階項(即Hessian矩陣)的計算。2018年論文《SNIP: Single-shot Network Pruning based on Connection Sensitivity》將歸一化的目標函數相對於參數的導數絕對值作爲重要性的衡量指標。

  • 第三個思路是考慮對特徵輸出的可重建性的影響,即最小化裁剪後網絡對於特徵輸出的重建誤差。它的intuition是如果對當前層進行裁剪,然後如果它對後面輸出還沒啥影響,那說明裁掉的是不太重要的信息。典型的如2017年論文《ThiNet: A Filter Level Pruning Method for Deep Neural Network Compression》和《Channel pruning for accelerating very deep neural networks》都是通過最小化特徵重建誤差(Feature reconstruction error)來確定哪些channel需要裁剪。前者採用貪心法,後者用的LASSO regression。2017年論文《NISP: Pruning Networks using Neuron Importance Score Propagation》提出只考慮後面一兩層啥的不夠,於是提出NISP(Neuron importance score propagation)算法通過最小化分類網絡倒數第二層的重建誤差,並將重要性信息反向傳播到前面以決定哪些channel需要裁剪。2018年論文《Discrimination-aware Channel Pruning for Deep Neural Networks》提出一種比較有意思的變體。它提出DCP(Discrimination-aware channel pruning)方法一方面在中間層添加額外的discrimination-aware loss(用以強化中間層的判別能力),另一方面也考慮特徵重建誤差的loss,綜合兩方面loss對於參數的梯度信息,決定哪些爲需要被裁剪的channel。

  • 另外還有基於其它的準則對權重進行重要性排序。如2018年的論文《Filter Pruning via Geometric Median for Deep Convolutional Neural Networks Acceleration》討論了magnitude-based方法的前提與侷限(即需要其範數值方差大,且最小值接近於0)。它提出了 FPGM(Filter Pruning via Geometric Median)方法。其基本思想是基於geometric median來去除冗餘的參數。

我們知道貪心算法的缺點就是隻能找到局部最優解,因爲它忽略了參數間的相互關係。那自然肯定會有一些方法會嘗試考慮參數間的相互關係,試圖找導全局更優解

  • 離散空間下的搜索:如2015年的論文《Structured Pruning of Deep Convolutional Neural Networks》基於genetic algorithm與particle filter來進行網絡的pruning。2017年的論文《N2N Learning: Network to Network Compression via Policy Gradient Reinforcement Learning》嘗試將網絡的壓縮分成兩個階段-layer removal和layer shrinkage,並利用強化學習(Reinforcement learning)分別得到兩個階段的策略。
  • 規劃問題:如比較新的2019年論文《Collaborative Channel Pruning for Deep Networks》提出CCP(Collaborative channel pruning)方法,它考慮了channel間的依賴關係 ,將channel選取問題形式化爲約束下的二次規劃問題,再用SQP(Sequential quadratic programming)求解。
  • Bayesian方法:如2017年論文《Variational Dropout Sparsifies Deep Neural Networks》提出了sparse variational droput。它對variational droput進行擴展使之可以對dropout rate進行調節,最終得到稀疏解從而起到裁剪模型的效果。
  • 基於梯度的方法:回顧上面問題定義中的數學最優化問題,其最噁心的地方在於regularizer中那個L0-norm,使目標不可微,從而無法用基於梯度的方法來求解。如2017年的論文《Learning Sparse Neural Networks through L0 Regularization》的思路是用一個連續的分佈結合 hard-sigmoid recification去近似它,從而使目標函數平滑,這樣便可以用基於梯度的方法求解。
  • 基於聚類的方法:一般地,對於壓縮問題有一種方法就是採用聚類。如將圖片中的顏色進行聚類,就可以減小其編碼長度。類似地,在模型壓縮中也可以用聚類的思想。如2018年的論文《SCSP: Spectral Clustering Filter Pruning with Soft Self-adaption Manners》和《Exploring Linear Relationship in Feature Map Subspace for ConvNets Compression》分別用譜聚類和子空間聚類發掘filter和feature map中的相關信息,從而對參數進行簡化壓縮。

Sparsity Ratio

上面的很多方法,研究的是給定裁剪量的前提下如何做pruning,如採用什麼樣的criteria去做參數選取。然而其實還有個核心問題是在哪裏裁剪多少,即sparsity ratio的確定。這裏的sparsity ratio定義爲層中爲0參數所佔比例,有些文章中也稱爲pruning rate等。從目標結構或者sparsity ratio的指定方式來說,按2018年論文《Rethinking the Value of Network Pruning》中的說法可分爲預定義(predifined)和自動(automatic)兩種方式。Predefined方法由人工指定每一層的比例進行裁剪,因此目標結構是提前確定。而automatic方法會根據所有的layer信息(即全局信息)由pruning算法確定每層裁剪比例,因此目標結構一開始並不確定。

  • 從某種意義上來說,著名的MobileNet《MobileNets: Efficient Convolutional Neural Networks for Mobile Vision Applications》中提出的multiplier參數也是一種predefined的network pruning方法。只是它比較簡單粗暴,將相同的裁剪比例用於所有層,且裁剪後權重不重用。2019年在《EfficientNet: Rethinking Model Scaling for Convolutional Neural Networks》中提出的EfficientNet將這種參數調節更進一步,提出compound scaling method將width, depth, resolution按特定比例一起調節。但它們調節參數都是針對網絡中所有層的,粒度比較粗。顯然,網絡中不同層對於pruning的敏感(sensitivity)程度是不一樣的,只有根據層的屬性爲每層設置最適合的sparsity ratio纔是最優的,這種爲每層專設的稱爲local sparsity,相對地前面那種就稱爲global sparsity。2015和2016年經典論文《Learning both Weights and Connections for Efficient Neural Networks》和《Pruning Filters for Efficient ConvNets》中對網絡中各層的敏感度進行了分析,發現卷積層比全連接層對pruning更敏感(直覺上,由於卷積層中的參數共享,所以參數量會比全連接層少得多),另外不同的卷積層之間敏感度也不一樣,如第一層卷積對pruning就相對更敏感,ResNet中每個stage中第一個和最後一個residual block比中間block更敏感等。這裏就引申出一個重要問題,就是如何確定每一層的最優的sparsity ratio。在predefined這類方式中,一種就是通過前面的提到的sensitivity analysis進而確定每一層的sparsity ratio。

  • 另觀automatic方法,如上所說,它需要pruning算法從全局信息中自動得到每層裁剪多少。上面提到過的論文《Learning Efficient Convolutional Networks through Network Slimming》就屬於此類。另外,2019年論文《Play and Prune: Adaptive Filter Pruning for Deep Model Compression》將pruning問題建模成min-max優化問題,然後通過兩個模塊交替迭代分別進行裁剪和通過調節pruning rate控制精度損失。2018年論文《ADC: Automated Deep Compression and Acceleration with Reinforcement Learning》提出ADC(Automated deep compression)方法,根據不同需求(如保證精度還是限制計算量),利用強化學習來學習每一層最優的sparsity ratio。2018年論文《“Learning-Compression” Algorithms for Neural Net Pruning》提出Learning和Compression兩步交替優化的pruning方法,在Compression操作中,通過將原參數向約束表示的可行集投影來自動找到每層的最優sparsity ratio。因爲此類方法不需要計算量較大的sensitivity analysis,也減少了超參數的引入。因此,近年來,這類方法的研究越來越多。

精度恢復

當模型經過pruning,一般會帶來精度損失,因此我們在pruning的同時也需要考慮精度的恢復:

  • 前面提到的論文《Channel Pruning for Accelerating Very Deep Neural Networks》中在進行channel pruning後,直接通過least square來得到最小化特徵重建精度下的新參數,因此不需要fine-tuning來恢復精度,是一種inference-time pruning方法。它的好處是pruning過程不需要訓練環境。
  • One-shot pruning指一趟頭的裁剪,但這種往往對精度影響很大。人們發現裁完後進行fine-tuning可以彌補pruning帶來的精度損失,因此很多方法會在pruning後做fine-tuning。比較經典的是training,pruning,fine-tuning三段式。後面兩個階段交替進行,每次pruning後損失的精度可以由後面的fine-tuning來彌補,該過程也稱爲iterative pruning。簡單說就是砍一刀回點血,再砍一刀再回點血這樣,不一步到位是因爲有些實驗表明一下子砍太狠就難回血了。當然現實中可以衍生出很多玩法。而在時間維度上,每步砍多少也是有藝術的。如2017年論文《To Prune, or Not to Prune: Exploring the Efficacy of Pruning for Model Compression》提出一種automated gradual pruning算法,它基於開始階段冗餘多可以裁得快,越到後面越裁得快的指導思想,給出在n步的pruning中,如何從初始sparsity ratio漸變到目標sparsity ratio的方法。

重新審視假設

比較有意思的是,最近不少工作開始反思一些之前固有的假設。比如一開始提到的over-parameterization對訓練是否真的那麼有益,還有原網絡的權重是否在pruning中很重要。在ICLR2019的best paper《The Lottery Ticket Hypothesis: Finding Sparse, Trainable Neural Networks》提出The Lottery Ticket Hypothesis,即一個隨機初始化,密集的網絡包含一個子網絡,這個子網絡如果沿用原網絡的權重初始化,在至多同樣迭代次數訓練後就可以比肩原網絡的測試精度。同時它還給出了找這種子網絡結構的方法。文章認爲這個子結構和它的初始值對訓練的有效性至關重要,它們被稱爲『winning logttery tickets』。另一篇論文2018年的《Rethinking the Value of Network Pruning》提出不僅over-parameterization對於訓練不是重要的,而且從原網絡中重用其權重也未必是很好的選擇,它可能會使裁剪後的模型陷入局部最小。如果原網絡的權重或其初始值不重要的話,那剩下最重要的就是pruning後的網絡結構了。換句話說,某種意義上來說,pruning即是neural architecture search(NAS),只是由於 它只涉及層的維度,搜索空間相比小一些。但這也是它的優點,搜索空間小了自然搜索就高效了。

保留模型Capacity

Pruning按最初的字面意思理解就是給模型做減法。之前的主流pruning方法中,被裁剪的部分一般也就直接丟棄不會再拿回來了,即模型的capacity在iterative pruning的過程中不斷減少。這樣的話,一旦有參數被不適當地裁剪掉,便無法被恢復。而這兩年,學界正在嘗試在模型壓縮過程中保留被裁剪部分能力或者擴充能力的方法。2018年論文《Soft Filter Pruning for Accelerating Deep Convolutional Neural Networks》提出SFP(Soft filter pruning)讓被裁剪的filter在訓練中仍能被更新,這樣它仍有機會被恢復回來。2016年論文《Dynamic Network Surgery for Efficient DNNs》在pruning的基礎上加了splicing操作,避免不合適的pruning帶來的影響。2017年的論文《Morphnet: Fast & Simple Resource-Constrained Structure Learning of Deep Networks》也是基於這種思路,它會迭代地進行shrink和expand的操作。

Pruning的副作用就是可能會損害模型的capacity。儘管前面的各種方法讓該影響儘可能小,但我們往往只能在有限的數據集上做。因此,很可能對於大部分簡單的樣本pruning對其沒有影響,但對於小部分難的數據會有較大影響。那有沒有可能在保留網絡capacity的同時又能精簡計算呢?一些學者嘗試結合dynamic NN來達到該目的,即網絡執行哪些模塊由輸出決定。如2017年論文《Dynamic Deep Neural Networks: Optimizing Accuracy-Efficiency Trade-offs by Selective Execution》引入Dynamic Deep Neural Networks,對於給定輸入,哪部分神經元被執行由網絡本身中的controller module來確定。這個module通過強化學習進行訓練。另一篇2017年論文《Runtime Neural Pruning》將pruning建模爲馬爾可夫決策過程(Markov decision process)並通過強化學習來學習pruning策略。當然,這類方法也有些侷限,如由於保留了網絡原始capacity,因此size不會減少。另外由於執行哪部分是動態的,因此對於硬件加速會有影響(如算子間的fusion)。

三、小結

和DNN訓練不同,DNN的部署有個很大的挑戰是平臺的多樣性。雲和端上的硬件平臺差異很大,端設備與端設備之間在硬件種類和能力上差異也很大。對於加速硬件的多樣性問題,業界已有諸多研究和嘗試,如像基於編譯器的TVM,和runtime+廠商backend的Android NN runtime。但計算能力的差異仍然是個大問題。如同樣是手機,計算能力可能有巨大的差異。這本質上是一個考慮性能與精度等指標的多目標優化問題,我們需要針對不同平臺在其pareto解集上找合適的trade-off 。如果要將同一DNN適用於多種平臺,需要按不同算力進行裁剪並且訓練,這個成本很大(幾乎與平臺種類線性相關),可伸縮性差。而模型壓縮成爲了解決多類型平臺統一部署方案的希望之一。像2018年論文《Slimmable Neural Networks》考慮不同移動端平臺訓練同一網絡,對於不同計算能力的平臺進行不同程度的裁剪。2019年論文《Once for All: Train One Network and Specialize it for Efficient Deployment》也是爲了類似的目標,將一個大網絡通過progressive shrinking approach訓練不同超參下的子網絡,在部署時根據不同的精度要求和資源約束搜索合適的子網絡。即一次訓練,可以適應多種平臺部署,因此稱爲Once for All(OFA)方案。它既可以說是一種模型壓縮方法,也可以說是一種神經網絡結構搜索(Neural archtecture search)。NAS相關介紹可參見之前寫的雜文神經網絡架構搜索(Neural Architecture Search)雜談。類似的,2018年論文《ProxylessNAS: Direct Neural Architecture Search on Target Task and Hardware》中其實是用pruning的方法來做NAS。

可以看到,這幾年network pruning作爲模型壓縮中的主力之一,正在受到越來越多的關注。當然,各種更好的pruning參數選取方法一定還會層出不窮。另外,從趨勢來看,以下幾個方向值得關注:

  • 如前面提到,network pruning方法與NAS的界限已經模糊了。事實上,NAS分支上也有一類搜索加速方法,如One-Shot Architecture Search是先有一個大網絡,然後做減法。NAS與模型壓縮兩個一開始看似關係不是那麼大的分支最後似乎走到一塊去了。這兩個分支今天有了更多的交集,也必將擦出更多的火花。
  • 挑戰已有的固有的假設。如前面對於over-parameterization與重用已有參數是否有有益的反思非常有意思。這樣的工作會給我們非常大的啓發,從而根本改變解決問題的思路。
  • 隨着AutoML的大潮,越來越多的東西開始自動化。模型壓縮能拉下嗎?當然不能。經過前面的介紹我們知道,像ADC,RNP,N2N Learning這些工作都是試圖將pruning中部分工作自動化。而且對於其它的模型壓縮方法,如quantization,也有一些空間可以自動化,如2018年論文《HAQ: Hardware-Aware Automated Quantization》考慮網絡中不同層信息的冗餘程度不一樣,因此可以用不同位數進行量化。
  • 這幾年機器學習最火熱的分支之一GAN,正在不斷滲透到已有領域,在pruning中也開始有它的身影。如2019年論文《Towards Optimal Structured CNN Pruning via Generative Adversarial Learning》採用了GAN的思想,讓generator生成裁剪後網絡,discrimintor來判別是否屬於原網絡還是裁剪後網絡,從而進行更有效的網絡結構化裁剪。
  • 與硬件結合,如稀疏計算的支持。現在雖然有像cuSPARSE這樣的計算庫,但底層硬件GPU本身設計並不是專門爲稀疏數據處理打造的。如果能將稀疏計算和處理能力做進芯片那必將極大提高計算效率,如早些年有像EIE這樣的嘗試。在現在神經網絡芯片的大潮下,相信這樣的案例會越來越多。
  • 如文章一開始提到的,模型壓縮方法中pruning只是其中一種,它與其它方法並不衝突,因此與其它方法,如knowledge distillation,quantization等的深度結合,是值得研究的方向。
  • 和其它機器學習分支一樣,很多人提出很多算法,各家都說自家的好。一個分支發展到一定時候,就需要benchmark來進行客觀的橫向比較。Google在2019年論文《The State of Sparsity in Deep Neural Networks》正是這方面的嘗試。相信以後也會有越來越多的benchmark,和針對性的競賽。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章