一.神經網絡壓縮
在如今人工智能的浪潮之下,深度學習在不少領域都取得了不錯的成果。但是目前在邊緣計算,物聯網設備上的算力相比於我們的台式計算機還不太充足,我們在計算機上用於擬合的神經網絡參數過多,不太適合運行在算力較弱的設備上,比如無人機,手機,平板電腦,自動駕駛汽車等等。因此我們需要將在計算機上訓練好的神經網絡通過某種技巧將其進行壓縮,減少模型的參數,這樣訓練好的模型就可以迅速在這些邊緣計算的設備上部署,同時達到和計算機上訓練模型幾乎一致的效果。比如我們常用的圖像分類的模型VGG,通過改良后的MobileNet,計算量減少了10倍,輸出的准確度結果甚至超越了AlexNet,准確率比Google InceptionNet也只少了0.7個百分點。那么我們有什么方法進行神經網絡的壓縮呢?目前比較常用的則是神經網絡的剪枝,知識蒸餾,以及模型優化設計者三個方法。
二.神經網絡剪枝
其實我們擬合的神經網絡,很多網絡的參數都過於多了,有些神經元在對結果進行的預測的時候並沒有什么用,甚至是具有負面的作用。因此我們需要將其“拆除”。
拆除網絡當中某些參數的方法如下:
1.剪掉權重weight約等於0的weight,讓兩個神經元之間失去連接
2.查看某個神經元經過activation之后的輸出是否接近於零,如果接近於零,則剪掉這個神經元
3.在修剪完整個網絡之后,識別的准確度肯定會下降,我們這時保留之前訓練好的權重,再利用訓練集訓練一次,更新當前神經網絡的參數
4.技巧:不要在一次修建當中修建過多的參數,不然的話神經網絡很難恢復到之前的准確度,總的來說修建神經網絡的流程圖如下所示:
當然在有了這個更小的神經網絡之后,我們就會想到為什么我們不直接去訓練一個更小的神經網絡呢?
原因是更小的神經網絡在進行梯度下降的時候並不一定能夠找到全局最小值,有可能連局部最小值都無法找到。而越大的神經網絡擬合的能力就越強,就越容易在梯度下降之后找到全局最小值。
備注:但是我們在訓練的時候,會遇到一些實際的問題,比如我們如果要去掉一些神經元和權重,那么我們很難用編程去實現,那我們應該怎么辦呢?很簡單,那就是把權重和神經網絡的輸出直接設置為零。這樣既能夠方便GPU進行加速計算,也能夠方便編程實現。
三.知識蒸餾
知識蒸餾的核心就是用大的神經網絡帶着小的神經網絡去訓練。也就是我們預訓練一個Teacher Net,這個模型是比較符合我們預期的。再將神經網絡修剪之后得到一個Student Net,或者自定義一個Student Net,用Teacher Net帶着Student Net去訓練。也就是我們給Student Net和Teacher Net同樣的輸入,而loss則是衡量Teacher Net和student Net之間的不同。如下圖所示:
我們不用studentNet的“標簽”輸出來做loss,比如我們輸入圖像數字‘1’,神經網絡輸出的標簽應該是“1”。不這樣干,而是用Teacher Net當中的softmax輸出是因為這樣student-net所獲得的信息更加豐富,既能夠知道輸出的標簽應該是什么,還可以知道輸出的數字是另外一個數字的相似度。假設我們輸入圖像1.輸出的softmax的概率的值1為0.5,9為0.4,3為0.1,如果只用標簽的值作為輸出,studentnet絕對不知道1和9其實長得挺像的,也就差0.1的概率而已。因此這就是使用Teacher Net帶着Student Net訓練的好處。也是知識蒸餾當中的核心思想。
四.模型優化設計
其實在神經網絡當中最常見的應該是模型的優化設計了,也是最常用對參數進行優化的方法。假設我們有一個全連接神經網絡,如下圖所示:
輸入層具有N個神經元,輸出層具有M個神經元,中間具有M*N個權重,怎么對它進行優化,減少參數呢?很簡單,那就是在中間再插入一層神經元,但是這層神經元僅僅是神經元,而不具備activation,也就是激活函數。如下圖所示:
這樣現在神經網絡的參數總量就變成了N*K+K*M,明顯小於M*N,我們下圖表示權重的多少: