back to index
Network Compression (1/6)

link |
那為什麼我們會在意network compression這件事情呢?因為我們知道說未來我們可能會希望把我們的deep model放在很多mobile的device上面,但是很多device它上面的資源是有限的,它可以儲存的空間是有限的,所以你就不能夠存太深或太過巨大的network。
link |
或者是這個device的computing power是有限的,所以你的network可能就不能夠太多層,你的network可能就不能夠有太多的參數,不然你的device可能就沒有辦法做real time的回應。
link |
那我們知道很多device它的computing的resource是有限的,舉例來說在這個圖上有智能手錶,有手機,有智能眼鏡,有drone,或者是未來有機器人等等,在這些device上面,它們的資源是有限的,它只有有限的儲存空間,它只有有限的computing power。
link |
而我們希望未來,為了要把這個deep mania的技術放在這些device上面,我們可以把我們的network縮小,讓它可以beat這些device上面有的運算資源。
link |
好,那今天這一堂課就是講一些可以讓network變小的方式,那這邊會講五個方向,另外一個可能其實是重新設計硬體的架構。
link |
舉例來說,我們可以為deep的network客製化硬體的架構做一些assay,就可以讓它的運算比較快一點,不過這個就不是我的專長,所以我們今天不會講到任何跟硬體方面有關的東西。
link |
我今天要講的第一個方法叫做network pruning,那你其實從它的名字就大概可以猜想說我們要做的事情就是把一個大的network,它的一些weight或者是一些neural把它剪掉,讓它變得比較小。
link |
那為什麼我們可以做network pruning這件事呢?因為我們通常相信說今天我們所churn出來的network,它是overparameterized,也就是說它裡面有很多參數是沒有用的。
link |
其實我們並不需要那麼多的參數才能夠解我們現在要解的問題,其實我們是給了network過多的參數。如果你實際上分析那些network的參數,分析那些neural的output,會發現說在testing的時候,也許很多的neural它根本就沒有用到,它的output總是零。
link |
或者是說有些weight它的值是非常接近零的,它對於network會output什麼樣的東西根本就沒有影響,所以實際churn一個network以後,你會發現說很多weight或很多neural根本是沒有用上。
link |
所以我們就可以把那些weight跟neural把它剪掉,把它從network裡面移除,這樣我們就可以得到一個比較小的network。
link |
那network pruning這個東西,它是一個非常古老的概念,至少在九零年代就已經有這樣的概念了。比如說,Yann LeCun在九零年代的時候就發表了一篇paper,這篇paper做的事情就是network pruning。
link |
它的title蠻有趣的,它的title是optimal brain damage,他就覺得network pruning這件事情像是brain damage,像是腦部有受損,但是我們今天希望這個受損是最佳的,是prune在最好的地方,讓這個損傷所造成的影響是最小的。
link |
我們知道說,人腦其實也有這種weight pruning,也有這個network pruning的機制。我以前高三的時候上生物課就有看過這個圖,剛出生的時候,嬰兒是腦袋空空的,他的神經元間的連結非常稀疏。
link |
等到六歲的時候,就有非常多非常多的連結,但是隨著年紀漸長,有很多連結就慢慢地消失了,感覺人腦好像也是在做weight pruning這件事。
link |
那weight pruning通常是怎麼做的呢?我們來講一下weight pruning通常一般在文獻上是怎麼做的。首先,你要有一個大的network,你就用你手上的訓練資料,先train好一個大的network。
link |
接下來,你要去評估說在這個大的network裡面,它的每一個weight或者是每一個neuron的重要程度。怎麼評估一個weight或neuron的重要程度呢?在文獻上就有滿坑滿谷不同的做法。
link |
舉例來說,怎麼評價一個weight它重不重要呢?你可以直接看那個weight的數值,如果那個weight的值很接近零,那它可能就是一個比較不重要的weight。如果那個weight的值非常的正或者是非常的負,那它可能就是一個重要的weight。
link |
所以你可以計算一個weight的L1或L2的數值,然後看看說這個weight是重要還是不重要。那怎麼看一個neuron它到底重不重要呢?如果今天你給定一個data set,某個neuron它的output幾乎都是零的話,那這個neuron可能就是一個不重要的neuron。
link |
那我這邊就不細講說有什麼樣的方法在文獻上,你可以想像說有各式各樣的人想了各式各樣有創意的方法來衡量一個weight或者是一個neuron它的重要性。
link |
你就把所有的weight或所有的neuron按照它的重要性做排序,接下來你就移除不重要的weight或者是不重要的neuron。移除了不重要的weight或不重要的neuron以後,你就把本來比較大的neuron變得比較小了。
link |
那當然因為你移除了一些東西,你移除了一些weight,你移除了一些neuron,所以現在的neuron變得跟原來的neuron不一樣。那你移除了一些東西,你的performance就會掉一點。
link |
那你希望說因為你移除了最不重要的東西,所以你的performance不會掉太多。那接下來呢,你可以把剛才的損傷再recover回來。
link |
怎麼把剛才損傷再recover回來呢?你現在pwn掉一些weight跟neuron以後,你把新的network拿去你原來的訓練資料上,再去finetune一下,再去update幾次參數。
link |
那往往就可以復原回來,就可以把損傷移除。
link |
好,那接下來再看說,那我剛才丟掉了一些weight,丟掉了一些neuron,那現在network的大小是不是讓我滿意。如果是的話,就結束了,你就有一個比較小的network。
link |
但是我們通常在做這個remove的時候,我們不會一次remove掉太多的東西,因為你如果一次remove掉太多的東西,可能就會損傷太嚴重,接下來就recover不回來。
link |
就你remove掉一點點,往往可以recover回來,但你remove掉太多,就recover不回來了。
link |
最常見的做法是你會iterative的做weightpwning,也就是你先pwn掉一點點,recover回來,然後看看現在這個pwn的量夠不夠,如果覺得pwn的量不夠,回頭過去再重新計算一次每一個neuron或weight的正確程度。
link |
因為你這邊有fine-tune了,所以你那個network的參數、weight都變了,所以你要重新再計算一次你的network裡面每一個weight或neuron的重要性,然後再pwn掉最不重要的,再fine-tune一下,得到一個新的network,再重新評估重要性,再remove掉一些,再fine-tune一下,你就走幾個循環,最後如果你覺得你的network夠小了,你就輸出一個小的network。