2021 神经网络压缩 (李宏毅
首先,為什么需要對(duì)神經(jīng)網(wǎng)絡(luò)模型進(jìn)行壓縮呢?我們?cè)谥暗恼n程中介紹過很多大型的深度學(xué)習(xí)模型,但當(dāng)我們想要將這些大模型放在算力比較小的邊緣設(shè)備或者其他IoT設(shè)備里面,就需要對(duì)大模型進(jìn)行壓縮。
Lower latency:低時(shí)延 Privacy:私密性
介紹5個(gè)網(wǎng)絡(luò)壓縮的方法,我們只考慮算法(軟件)層面,不考慮硬件層面的解決方法。
?
1. Network Pruning(網(wǎng)絡(luò)剪枝)
對(duì)于一個(gè)大的網(wǎng)絡(luò)來說,我們能想到的是,眾多網(wǎng)絡(luò)參數(shù)中一定會(huì)有不重要/冗余的一些參數(shù),因此我們將這些參數(shù)減掉達(dá)到網(wǎng)絡(luò)壓縮的目的。
網(wǎng)絡(luò)剪枝的步驟如下:首先,我們預(yù)訓(xùn)練一個(gè)大規(guī)模的網(wǎng)絡(luò),然后評(píng)估里面參數(shù)的重要性,包括權(quán)重(weight)的重要性和神經(jīng)元(neuron)的重要性。
- 評(píng)價(jià)weight重要性,我們可以用絕對(duì)值衡量,即絕對(duì)值越大,weight越重要,或者采用之前介紹的life long learning的想法(也許我們也可以就把每個(gè)參數(shù)的 bi 算出來、就可以知道那個(gè)參數(shù)重不重要)。
- 評(píng)價(jià)neuron重要性,我們可以用其輸出的結(jié)果為0的次數(shù)衡量,即輸出0越多越不重要。
接著我們對(duì)多余的參數(shù)的重要性評(píng)估并修剪,得到一個(gè)小的網(wǎng)絡(luò),再對(duì)里面的參數(shù)微調(diào),再評(píng)估、修剪。。。重復(fù)上述過程,直到滿足要求,完成Network pruning過程。(一次剪掉大量參數(shù)可能對(duì)network傷害太大,所以一次只剪掉一點(diǎn)參數(shù)比如10%)
剛才提到,修剪的單位有兩種,一種是以權(quán)重(weight)為單位,一種是以神經(jīng)元(neuron)為單位,這兩者有什么不同呢?實(shí)作上差別較大
首先Weight pruning,但這樣就造成network 形狀不規(guī)則(irregular),難以編程實(shí)現(xiàn)(pytorch定義network每一層有幾個(gè) Neuron/ vector),同時(shí)難以用GPU加速(矩陣乘法)。通常的做法是將冗余的weight置為0,但這樣做還是保留了參數(shù)(等于0),不是真正去除掉。
在這篇論文中有個(gè)關(guān)于參數(shù)pruning多少與訓(xùn)練速度提升關(guān)系的實(shí)驗(yàn)驗(yàn)證,其中紫色線sparsity表示參數(shù)去掉的量。可以發(fā)現(xiàn),雖然參數(shù)去掉了將近95%,但是速度依然沒有提升。
(這個(gè) Network Pruning 的方法、其實(shí)是一個(gè)非常有效率的方法、往往你可以 Prune 到 95% 以上的參數(shù)、那但是你的 Accuracy 只掉 1~2% 而已)
接著Neuron pruning,通過去除冗余的神經(jīng)元,簡化網(wǎng)絡(luò)結(jié)構(gòu)。這樣得到的網(wǎng)絡(luò)結(jié)構(gòu)是規(guī)則的,相比于Weight pruning,這種方式更好實(shí)現(xiàn),也更容易通過GPU加速。
Q&A:這個(gè) Pruning 有沒有效率是函式庫的問題?對(duì)啦 是函式庫的問題、那如果你可以想辦法寫一個(gè)、Irregular的 Network也很有效的函式庫的話、那你就可以用 Weight Pruning、但是 大家都沒有要自己寫函式庫
為什么我們先訓(xùn)練一個(gè)大的network,再壓縮成一個(gè)小的network,而不是直接訓(xùn)練一個(gè)小的network呢?一般來說,大的network更容易訓(xùn)練,如果直接訓(xùn)練小的網(wǎng)絡(luò)可能達(dá)不到大的network的訓(xùn)練效果。
why大的network比較好train?參看過去課程錄影。這里有個(gè)大樂透假說(Lottery Ticket Hypothesis)對(duì)上述觀點(diǎn)進(jìn)行了說明。
什么是大樂透假說(Lottery Ticket Hypothesis)呢?
train network是看人品的,每次 Train Network 的結(jié)果不一定會(huì)一樣,你抽到一組好的 Initial 的參數(shù),就會(huì)得到好的結(jié)果。
現(xiàn)在有一個(gè)訓(xùn)練好的大的網(wǎng)絡(luò),可以分解成若干個(gè)小的網(wǎng)絡(luò),只要某一個(gè)小的網(wǎng)絡(luò)性能與大的網(wǎng)絡(luò)相同或相似,就說明這個(gè)大的網(wǎng)絡(luò)可以壓縮。
大樂透假說在實(shí)驗(yàn)上是怎么被證實(shí)的呢?
用大樂透假說來解釋上圖的現(xiàn)象,就是大network裡面有很多 Sub-network、而這一組 Initialize 的參數(shù),就是幸運(yùn)的那一組、可以 Train 得起來的 Sub-network
大樂透假說非常知名,在ICLR2019得到 Best Paper Award
關(guān)于大樂透假說的一個(gè)后續(xù)的研究如下,“解構(gòu)大樂透假說”,通過充分的實(shí)驗(yàn)得到了一些有趣的結(jié)論:
- 第一個(gè)發(fā)現(xiàn)是,嘗試了不同的pruning strategy,發(fā)現(xiàn)如果訓(xùn)練前和訓(xùn)練后參數(shù)的差距越大,將其pruning后得到的結(jié)果越有效。
- 第二個(gè)發(fā)現(xiàn)是,到底我們今天這一組好的 Initialization好在哪里,? ?發(fā)現(xiàn)說 小的sub-network只要我們不改變參數(shù)的正負(fù)號(hào),就可以訓(xùn)練起來。說明:正負(fù)號(hào)是初始化參數(shù) 能不能夠訓(xùn)練起來的關(guān)鍵
- 第三個(gè)發(fā)現(xiàn)是,對(duì)于一個(gè)初始的大的網(wǎng)絡(luò)(因?yàn)閰?shù)隨機(jī)初始化很關(guān)鍵),有可能不訓(xùn)練就已經(jīng)有一個(gè)sub-network可以有一個(gè)比較好的效果。(其實(shí)可以得到跟supervise很接近的正確率)
但是? 大樂透假說一定是對(duì)的嗎?不一定。下面這篇文章就“打臉”了大樂透假說。實(shí)驗(yàn)是這樣的,我們用pruned完的小網(wǎng)絡(luò)隨機(jī)初始化參數(shù),再訓(xùn)練,只要多訓(xùn)練幾個(gè)epoch,就可以比不隨機(jī)初始化訓(xùn)練小網(wǎng)絡(luò)的效果要好。
當(dāng)然這篇文章的作者也給出了一些對(duì)大樂透假說的回應(yīng),大樂透假說出現(xiàn)的前提是當(dāng)learning rate很小,或者unstructured(做Weight pruning )時(shí)候才有可能出現(xiàn)大樂透假說現(xiàn)象。
所以大樂透假說,? 未來尚待更多的研究來證實(shí)
2. Knowledge Distillation
Knowledge Distillation的精神和?Network Pruning 其實(shí)也有一些類似的地方
Knowledge Distillation做法如下:首先我們先train一個(gè)大網(wǎng)絡(luò),叫Teacher Net。student network是去根據(jù)這個(gè) Teacher Network 來學(xué)習(xí)。學(xué)生 不是去看這個(gè)圖片的正確答案來學(xué)習(xí)、他把老師的輸出?就當(dāng)做正確答案。
這樣做是因?yàn)?#xff1a;直接 Train 一個(gè)小的 Network 往往結(jié)果就是沒有從大的 Pruning 來得好
Knowledge Distillation其實(shí)不是新的技術(shù),最知名的文章其實(shí)是Hinton在2015年就發(fā)表了,
Teacher Net其實(shí)會(huì)提供這個(gè) Student Network 額外的資訊
那其實(shí) Knowledge Distillation 有些神奇的地方、如果你看那個(gè) Hinton 的 Paper 裡面、它甚至可以做到? 光是 Teacher 告訴 Student 哪些數(shù)字之間、有什麼樣的關(guān)係這件事情、就可以讓 Student在完全沒有看到某些數(shù)字的訓(xùn)練資料下、就可以把那一個(gè)數(shù)字學(xué)會(huì)
這個(gè)Teacher Net不一定是一個(gè)巨大的network,也有可能是將多個(gè)network組合(ensemble)得到的。
(ensemble是機(jī)器學(xué)習(xí)比賽里一個(gè)非常常用的技巧,你就訓(xùn)練多個(gè)模型? 然後你輸出的結(jié)果就是多個(gè)模型、投票的結(jié)果就結(jié)束了。或者是把多個(gè)模型的輸出平均起來,
做個(gè)超級(jí)ensemble,訓(xùn)練個(gè)100 個(gè)模型啊1000個(gè)模型,把那麼多的模型的結(jié)果通通平均起來,往往你要在機(jī)器學(xué)習(xí)的 這種 Leaderboard 上面名列前茅,靠的就是這個(gè)技術(shù),
network output上做平均,也可以在network參數(shù)上做平均? 在translation作業(yè)里用過,這一招在translation上不知道為什么特別有用)
?關(guān)于Knowledge Distillation的一個(gè)小技巧,在softmax函數(shù)基礎(chǔ)上對(duì)每個(gè)輸出結(jié)果加一個(gè)超參數(shù)T(Temperature),這樣會(huì)對(duì)最后的預(yù)測結(jié)果進(jìn)行一個(gè)平滑處理,讓Student Net更好訓(xùn)練一些。
(softmax就是,你把每一個(gè) Neural 的輸出、都取 Exponential然后再做normalize得到最終 Network 的輸出)
還有人會(huì)拿network每一層都拿來train,比如大的有12層,小的6層,可以拿小的第6層像大的12層,小的第3層像大的第6層,往往做比較多的限制,可以得到更好的結(jié)果。
3. Parameter Quantization
Parameter Quantization參數(shù)量化,也可以稱為參數(shù)壓縮。用比較少的空間來儲(chǔ)存一個(gè)參數(shù),具體來說有如下幾種方式:
Q&A:Weight Clustering 要怎麼做 Update、每次 Update 都要重新分群嗎?
Weight Clustering其實(shí)有個(gè)簡單做法是,network訓(xùn)練完后、再直接做 Weight Clustering
但直接做,可能會(huì)導(dǎo)致?Cluster 後的參數(shù)、跟原來的參數(shù)相差太大
所以 有一個(gè)做法是? 我們?cè)谟?xùn)練的時(shí)候要求 Network 的參數(shù) 彼此之間比較接近、你可以把這個(gè)訓(xùn)練的 Quantization 當(dāng)做是Loss 的其中一個(gè)環(huán)節(jié)、直接塞到你的訓(xùn)練的過程中。讓訓(xùn)練中達(dá)到 參數(shù)有群聚的效果,
Q&A:每個(gè) Cluster 的數(shù)字要怎麼決定呢? 就是決定好每個(gè) Cluster 的區(qū)間之後取平均。
weight到底可以壓縮到什么程度呢?最終極的結(jié)果就是,每個(gè)weight只需要1bit就可以存下來,? 網(wǎng)絡(luò)中的weight要么是+1,要么是-1,像這樣Binary Weights的研究還蠻多的,可以參考的reference如圖:
那這樣訓(xùn)練出的網(wǎng)絡(luò)效果會(huì)不會(huì)不太好?這里有一篇文章是binary network里一個(gè)經(jīng)典的方法Binary Connect,
介紹了該方法用于3種數(shù)據(jù)集的圖像分類問題中,結(jié)果發(fā)現(xiàn)BinaryConnect的方法識(shí)別錯(cuò)誤率更小,原文給出的解釋是這種方法給network比較大的限制,會(huì)在一定程度上減少overfitting情況的發(fā)生。
4. Architecture Design(Depth Separable Convolution)
通過network架構(gòu)的設(shè)計(jì) 來達(dá)到減少參數(shù)量的效果,
這里介紹一種關(guān)于CNN的減少參數(shù)量的結(jié)構(gòu)化設(shè)計(jì)。
首先回顧一下CNN,在 CNN 的 Convolution Layer 裡、每一個(gè) Layer 的 Input 是一個(gè) Feature Map,? 假設(shè)輸入有2個(gè)channel,對(duì)應(yīng)的filter也是2個(gè)channel。假設(shè)有4個(gè)filter,每個(gè)filter都是3*3的,那么輸出就有4個(gè)channel。卷積層共有?3?3?2?4=72?個(gè)參數(shù)。
接著介紹Depth Separable Convolution,它分為兩個(gè)步驟:
1. Depthwise Convolution
它在做卷積的時(shí)候與傳統(tǒng)的對(duì)圖像做卷積有很大的不同。圖片有幾個(gè)channel就對(duì)應(yīng)有幾個(gè)filter,每個(gè)filter只管一個(gè)channel。
但是只做Depthwise Convolution會(huì)遇到一個(gè)問題,channel和channel之間沒有任何互動(dòng),假設(shè)某個(gè)pattern是跨channel才能看的出來,這種方法無能為力。
上述過程有?3?3?2=18?個(gè)參數(shù)。
2. Pointwise Convolution
為了解決無法學(xué)習(xí)輸入圖像channel與channel之間聯(lián)系的問題,將Depthwise Convolution的輸出結(jié)果用?1x1?的filter做卷積,以4個(gè)filter為例,效果如下:
上述過程有?2?4=8?個(gè)參數(shù)。
將標(biāo)準(zhǔn)CNN和Depth Separable Convolution參數(shù)量做對(duì)比,可以發(fā)現(xiàn)Depth Separable Convolution參數(shù)量比CNN要少很多。
那因?yàn)?O 通常是一個(gè)很大的值、你的 Channel 數(shù)目你可能開個(gè) 256 啊 512 啊。今天常用的 Kernel Size 可能是 3 x 3 或者是 2 x 2
上述方法為什么有效呢?
過去有一招Low rank approximation,來減少一層 Network 的參數(shù)量。如果神經(jīng)網(wǎng)絡(luò)某一層輸入為N,輸出為M(假設(shè)非常大),那么對(duì)應(yīng)的weight就有?N?M?個(gè)。這時(shí),如果我們?cè)贜和M中間加一層,這一層不用激活函數(shù),直接多插一層,neuron數(shù)目是K?。當(dāng)K比較小時(shí),參數(shù)量相比于?N?M?會(huì)大大減少。比如N和M都是1000,K 可以塞個(gè) 20、50。但是這樣的做法會(huì)減少W的可能性,本來W可以放任何參數(shù),拆成這樣W的rank ≤ K。
Depth Separable Convolution其實(shí)就是用了把 “1層拆成2層 ”這樣的概念,相當(dāng)于將CNN中間多加了一層,這樣就可以減少整體網(wǎng)絡(luò)的參數(shù)量。
關(guān)于網(wǎng)絡(luò)結(jié)構(gòu)設(shè)計(jì)方面還有一些文獻(xiàn)參考,感興趣可以看一下里面相關(guān)的內(nèi)容,這里就不多介紹。
5. Dynamic Computation(動(dòng)態(tài)計(jì)算)
在前幾個(gè)方法裡面想要做的事情、就是單純的把 Network 變小
而Dynamic Computation讓network可以自適應(yīng)調(diào)整計(jì)算量,比如讓神經(jīng)網(wǎng)絡(luò)自適應(yīng)不同算力的設(shè)備,或者同一設(shè)備不同電量時(shí)對(duì)算力的分配。
為什么不在一個(gè)設(shè)備上放好多個(gè)模型呢?因?yàn)樾枰几嗟目臻g。
如何自適應(yīng)調(diào)整網(wǎng)絡(luò)的計(jì)算量?讓 Network 自由調(diào)整它的深度,
這種方式效果到底如何?可以用.. 比較好一點(diǎn)的方法(MSDNet)。
讓 Network 自由決定它的寬度,。
強(qiáng)調(diào)一下:是同一個(gè) Network,可以選擇不同的寬度。標(biāo)一樣顏色的就是同一個(gè) Weight
事先決定好 在只要用 75% 參數(shù)的時(shí)候,某一些neuron不要用到,
訓(xùn)練時(shí) 就把所有的狀況一起考慮、然後所有的狀況都得到一個(gè) Output,
上述兩種方法都是人為決定根據(jù)設(shè)備不同的算力(比如電量)動(dòng)態(tài)調(diào)整網(wǎng)絡(luò)深度和寬度,
讓network自行決定、根據(jù)情景 、決定它的寬度或者是深度。比如,對(duì)于不同難度的訓(xùn)練樣本可能需要的層數(shù)也不一樣。
最后總結(jié)一下,關(guān)于神經(jīng)網(wǎng)絡(luò)壓縮(Network Compression)的這幾種方法,它們并不是互斥的,可以先用某一個(gè)方法,再接著用剩余的一個(gè)或幾個(gè)方法,直到滿足壓縮條件。
?
?
總結(jié)
以上是生活随笔為你收集整理的2021 神经网络压缩 (李宏毅的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 3D MAX入门篇(2)制作飞船绕山飞行
- 下一篇: 编程之美学习笔记--一摞烙饼的排序