當前位置:
首頁 > 知識 > 極致的優化:智能手機是如何處理大型神經網路的

極致的優化:智能手機是如何處理大型神經網路的

選自HeartBeat

作者:Julien Despois

機器之心編譯

參與:Pedro、張倩、劉曉坤

運行深度神經網路對計算能力、能耗及磁碟空間要求甚高,智能手機的計算資源十分有限,需要多種優化才能高效運行深度學習應用。本文介紹了如何在移動設備的各種指標之間取得平衡,在避免大幅度降低準確性的前提下構造更加輕便的神經網路,使得在移動設備上快速、準確地運行神經網路成為可能。

電腦擁有大容量硬碟和強大的 CPU 與 GPU,但智能手機沒有。為了彌補這些硬體上的不足,智能手機需要一些特殊手段才能高效地運行深度學習應用。

智能手機有辦法與這些強大的伺服器集群競爭嗎?還是完全沒有希望?

引言

深度學習是一種功能十分多樣和強大的技術,但是運行神經網路對計算能力、能耗及磁碟空間要求甚高。這對於在具有大型硬碟和多個 GPU 的伺服器上運行的雲應用來說一般不是問題。

不幸的是,在移動設備上運行神經網路並非易事。事實上,儘管智能手機的功能越來越強大,它們的計算能力、電池壽命及可用的磁碟空間依然十分有限,特別是那些非常依賴輕便性的應用。把應用做得輕便可以加快下載速度,減少更新,並且延長電池壽命,而這些都是用戶迫切需要的。

為了執行圖像分類、人像模式攝影、文本預測以及其他幾十項任務,智能手機需要使用特殊方法來快速、準確地運行神經網路,且不佔用過多內存空間。

在這篇文章中,我們將會了解一些最有效的、能讓神經網路在手機上實時運行的技術。

能使神經網路更小更快的技術

基本上來講,我們只對三個指標感興趣:模型的準確率、速度、在手機中佔用的內存。天下沒有免費的午餐,因此我們不得不在這些指標之間作出一些權衡。

對於大部分技術來說,我們一邊要關注指標,一邊還要尋找一個叫做「飽和點」(saturation point)的東西。達到這個點之後,利用其他指標的損失實現某個指標的增益將不再可行。在到達飽和點前保持優化值,可以在兩個指標上取得最佳結果。

在這個例子中,我們可以在不增加誤差的情況下顯著減少代價昂貴的運算。但是,在超過飽和點之後,誤差的嚴重程度高到不可接受。

記住這個方法,讓我們開始吧!

1. 避免全連接層

全連接層是神經網路中最常見的部分,它們通常能發揮很大作用。然而,由於每一個神經元都和前一層的所有神經元相連接,因此它們需要存儲和更新大量參數,這對速度和磁碟空間都很不利。

卷積層是利用輸入(通常是圖像)中局部一致性的層。每一個神經元不再與前一層的所有神經元相連。這有助於網路在保持高度準確性的同時減少連接/權重的數量。

全連接層的連接/權重數量要遠遠多於卷積層。

使用少連接或非全連接的層能縮小模型的體積,同時保持其高準確性。這種方法可以提高速度,同時減少磁碟使用量。

在上面提到的構造中,一個擁有 1024 個輸入、 512 個輸出的全連接層大約有 500k 個參數。而一個擁有相同特徵以及 32 個特徵圖的卷積層只需要大約 50k 個參數。這是一個 10 倍的提升。

2. 減少通道數量與卷積核大小

這一步展現了在模型複雜度與速度之間作出的一個非常直接的權衡。擁有大量通道的卷積層能使網路提取相關信息,但也要付出相應的代價。剔除一些特徵圖是一個節約空間、加速模型的簡單方法。

我們可以運用卷積運算的感受野來做同樣的事情。通過縮小卷積核大小,卷積對局部模式的感知減少,但涉及的參數也減少了。

縮小感受野/卷積核大小可以降低計算成本,但是傳遞的信息會變少。

在這兩種情況下,我們通過找到飽和點來選擇特徵圖的數量/卷積核大小,以保證準確性不會下降太多。

3. 優化降採樣

對於固定數量的層和固定數量的池化操作,神經網路可能會表現得天差地別。這是由於數據的表徵以及計算量大小取決於這些池化操作於何處完成。

如果池化操作較早完成,數據的維數會減少。維數越少,網路的處理速度越快,但信息量會減少,準確性也會降低。

如果網路中的池化操作完成較晚,那麼大部分信息會被保留下來,因此準確度高。然而這也意味著計算是在多維對象上完成的,這會導致計算成本的增加。

於神經網路中均勻布置降採樣是一種行之有效的結構(https://arxiv.org/pdf/1710.02759.pdf),而且能在準確性與速度之間保持良好的平衡。這也是一種飽和點。

較早的池化速度快,延後的池化精確性高,均勻布置池化能兼具二者的一些優點。

4. 權重修剪

在一個經過訓練的神經網路中,有些權重對於某個神經元單元的激活值至關重要,而其他的權重基本不影響結果。儘管如此,我們仍要對這些不那麼重要的權重做一些計算。

修剪(pruning)是一個完全刪除最小強度連接的過程,這樣我們就可以跳過這些計算。這會降低準確性但是能讓網路更快更精簡。我們需要找出飽和點,然後在盡量不影響準確性的情況下刪去儘可能多的連接。

刪去最弱的連接來節省計算時間與空間。

5. 離散化權重

為了在磁碟中保存神經網路,我們需要記錄網路中每一個權重的值。這意味著我們需要為每一個參數保存一個浮點數,同時也意味著大量磁碟空間的消耗。舉例說明,在 C 中一個浮點數佔據 4 個位元組,即 32 位。一個有著上億參數的網路(如 Google-Net 或 VGG-16)會輕易佔據上百兆位元組的空間,而這樣的消耗在移動設備中是不可接受的。

為了盡量減小網路存儲的量,一種方法是通過離散化權重來降低權重的精度。在這個過程當中,我們更改數字的表示使其不再表示具體值,而是限制其為數值的子集。這樣我們只需要存儲一次經過離散化的值,然後將它們映射到網路的權重上。

離散化權重存儲索引而非浮點值。

我們再次需要通過找到飽和點來決定到底使用多少個值。使用更多數值意味著準確性的提高,但也意味著更大的表徵空間。舉個例子:如果使用 256 個經過離散化的值,每一個權重只需要使用 1 個位元組(即 8 位)就能表示。相比之前(32 位),我們將其大小縮減了四倍!

6. 模型表徵的編碼

我們已經對權重作了許多處理,但是還能進一步改進網路!這個特殊技巧源於權重分布不均的事實。一旦權重被離散化,我們就會失去相同數量的對應每一個離散化值的權重。這意味著在我們的模型表徵中,某些索引的出現頻率相對更高,我們可以利用這一點!

哈夫曼編碼(Huffman coding)能完美地解決這個問題。它通過給最常用的值分配最小索引以及給最不常用的值分配最大索引來解決這些問題。這有助於減小設備上模型的體積,最關鍵的是不會降低準確性。

訪問次數最多的符號只使用 1 位的空間,而訪問次數最少的符號使用 3 位的空間。這是因為後者在數據表示中出現的次數很少,並由此可以達到一種空間上的平衡。

這個簡單的技巧使我們能夠進一步縮小神經網路佔用的空間,通常能減少 30% 左右。

注意:每一層的離散化和編碼可以是不同的,從而提供更大的靈活性。

修正準確率損失

通過我們使用的方法,神經網路已經十分精簡了。我們刪去了弱連接(修剪),甚至改變了一些權重(離散化)。在網路變得十分輕巧快速的同時,其準確率也不如以前了。

為了修正這一點,我們需要迭代地重新訓練網路的每一步。這代表我們需要在修剪和離散化操作之後,再次訓練網路使其可以擬合相應的變化,然後重複這一過程直到權重不再大幅變化為止。

結論

儘管智能手機沒有優秀的台式機那樣的磁碟空間、計算能力或者電池壽命,它們仍是深度學習應用程序的優秀實驗對象。通過一系列方法,我們現在可以在這些多功能手持設備上運行強大的神經網路,準確性只是略有下降。這為數千個優秀的應用打開了大門。

如果有興趣,你也可以了解一些面向移動設備的優秀神經網路,如 SqueezeNet(https://arxiv.org/abs/1602.07360)或 MobileNets(https://arxiv.org/abs/1704.04861)。

參考閱讀:

縱覽輕量化卷積神經網路:SqueezeNet、MobileNet、ShuffleNet、Xception

谷歌發布MobileNetV2:可做語義分割的下一代移動端計算機視覺架構

本文為機器之心編譯,轉載請聯繫本公眾號獲得授權。

------------------------------------------------

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

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


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

教程 | 從頭開始了解PyTorch的簡單實現
海康、UCLA、北理聯合提出3D DescriptorNet:可按條件生成3D形狀,克服模式崩潰

TAG:機器之心 |