摘要: 這些方法可讓深度學習跑在你的手機上!git
計算機具備高儲量的硬盤和強大的CPU和GPU。可是智能手機卻沒有,爲了彌補這個缺陷,咱們須要技巧來讓智能手機高效地運行深度學習應用程序。github
æºè½ææºè½ä¸å¼ºå¤§çæå¡å¨é群ç«äºåï¼ 服務器
介紹網絡
深度學習是一個使人難以置信的靈活且強大的技術,但運行的神經網絡能夠在計算方面須要很是大的電力,且對磁盤空間也有要求。這一般不是雲空間可以解決的問題,通常都須要大硬盤服務器上運行驅動器和多個GPU模塊。架構
不幸的是,在移動設備上運行神經網絡並不容易。事實上,即便智能手機變得愈來愈強大,它們仍然具備有限的計算能力、電池壽命和可用磁盤空間,尤爲是對於咱們但願保持儘量輕的應用程序。這樣作能夠實現更快的下載速度、更小的更新時間和更長的電池使用時間,這些都是用戶所欣賞的。學習
爲了執行圖像分類、人像模式攝影、文本預測以及其餘幾十項任務,智能手機須要使用技巧來快速,準確地運行神經網絡,而無需使用太多的磁盤空間。優化
在這篇文章中,咱們將看到一些最強大的技術,使神經網絡可以在手機上實時運行。編碼
使神經網絡變得更小更快的技術對象
基本上,咱們對三個指標感興趣:模型的準確性、速度以及它在手機上佔用的空間量。因爲沒有免費午飯這樣的好事,因此咱們必須作出妥協。blog
對於大多數技術,咱們會密切關注咱們的指標並尋找咱們稱之爲飽和點的東西。這是一個指標的收益中止而其餘指標損失的時刻。經過在飽和點以前保持優化值,咱們能夠得到最佳值。
在這個例子中,咱們能夠在不增長錯誤的狀況下顯着減小昂貴的操做次數。可是,在飽和點附近,錯誤變得過高而沒法接受。
1.避免徹底鏈接的層
徹底鏈接的層是神經網絡最多見的組成部分之一,它們曾經創造奇蹟。然而,因爲每一個神經元都鏈接到前一層的全部神經元,所以它們須要存儲和更新衆多參數。這對速度和磁盤空間是不利的。
卷積層是利用輸入中的局部一致性(一般是圖像)的層。每一個神經元再也不鏈接到前一層的全部神經元。這有助於在保持高精度的同時減小鏈接/重量的數量。
徹底鏈接層中的鏈接/權重比卷積層中多得多。
使用不多或沒有徹底鏈接的層能夠減小模型的大小,同時保持高精度。這能夠提升速度和磁盤使用率。
在上面的配置中,具備1024個輸入和512個輸出的徹底鏈接層,這個徹底鏈接層大約有500k個參數。若是是具備相同特徵和32個卷積層特徵映射,那麼它將只具備50K參數,這是一個10倍的改進!
2.減小通道數量和內核大小
這一步表明了模型複雜性和速度之間的一個很是直接的折衷。卷積層中有許多通道容許網絡提取相關信息,但需付出代價。刪除一些這樣的功能是節省空間並使模型變得更快的簡單方法。
咱們能夠用卷積運算的接受域來作一樣的事情。經過減少內核大小,卷積對本地模式的瞭解較少,但涉及的參數較少。
較小的接受區域/內核大小計算起來更便宜,但傳達的信息較少。
在這兩種狀況下,經過查找飽和點來選擇地圖/內核大小的數量,以便精度不會下降太多。
3.優化縮減採樣(Optimizing the downsampling)
對於固定數量的層和固定數量的池操做,神經網絡能夠表現得很是不一樣。這來自於一個事實,即表示該數據以及計算量的依賴於在池操做完成:
· 當池化操做提前完成時,數據的維度會下降。越小的維度意味着網絡處理速度越快,但意味着信息量越少,準確性越差。
· 當聯網操做在網絡後期完成時,大部分信息都會保留下來,從而具備很高的準確性。然而,這也意味着計算是在具備許多維度的對象上進行的,而且在計算上更昂貴。
· 在整個神經網絡中均勻分佈下采樣做爲一個經驗有效的架構,並在準確性和速度之間提供了一個很好的平衡。
早期的池化速度很快,晚期的池化是準確的,均勻間隔的池化是有點二者。
4.修剪重量(Pruning the weights)
在訓練完成的神經網絡中,一些權重對神經元的激活起着強烈做用,而另外一些權重幾乎不影響結果。儘管如此,咱們仍然對這些弱權重作一些計算。
修剪是徹底去除最小量級鏈接的過程,以便咱們能夠跳過計算。這可能會下降了準確性,但使網絡更輕、更快。咱們須要找到飽和點,以便儘量多地刪除鏈接,而不會過多地損害準確性。
除去最薄弱的鏈接以節省計算時間和空間。
5.量化權重(Quantizing the weights)
爲了將網絡保存在磁盤上,咱們須要記錄網絡中每一個單一權重的值。這意味着爲每一個參數保存一個浮點數,這表明了磁盤上佔用的大量空間。做爲參考,在C中,一個浮點佔用4個字節,即32個比特。一個參數在數億的網絡(例如GoogLe-Net或VGG-16)能夠輕鬆達到數百兆,這在移動設備上是不可接受的。
爲了保持網絡足跡儘量小,一種方法是經過量化它們來下降權重的分辨率。在這個過程當中,咱們改變了數字的表示形式,使其再也不可以取得任何價值,但至關受限於一部分數值。這使咱們只能存儲一次量化值,而後參考網絡的權重。
量化權重存儲鍵而不是浮動。
咱們將再次經過查找飽和點來肯定要使用多少個值。更多的值意味着更高的準確性,但也是更大的儲存空間。例如,經過使用256個量化值,每一個權重能夠僅使用1個字節 即 8個比特來引用。與以前(32位)相比,咱們已將大小除以4!
6.編碼模型的表示
咱們已經處理了關於權重的一些事情,可是咱們能夠進一步改進網絡!這個技巧依賴於權重不均勻分佈的事實。一旦量化,咱們就沒有相同數量的權值來承載每一個量化值。這意味着在咱們的模型表示中,一些引用會比其餘引用更頻繁地出現,咱們能夠利用它!
霍夫曼編碼是這個問題的完美解決方案。它經過將最小佔用空間的密鑰歸屬到最經常使用的值以及最小佔用空間的值來實現。這有助於減少設備上模型的偏差,最好的結果是精度沒有損失。
最頻繁的符號僅使用1 位的空間,而最不頻繁的使用3 位。這是由後者不多出如今表示中的事實所平衡的。
這個簡單的技巧使咱們可以進一步縮小神經網絡佔用的空間,一般約爲30%。
注意:量化和編碼對於網絡中的每一層都是不一樣的,從而提供更大的靈活性
7.糾正準確度損失(Correctiong the accuracy loss)
使用咱們的技巧,咱們的神經網絡已經變得很是粗糙了。咱們刪除了弱鏈接(修剪),甚至改變了一些權重(量化)。雖然這使得網絡超級輕巧,並且速度很是快,但其準確度並不是如此。
爲了解決這個問題,咱們須要在每一步迭代地從新訓練網絡。這只是意味着在修剪或量化權重後,咱們須要再次訓練網絡,以便它可以適應變化並重復這個過程,直到權重中止變化太多。
結論
雖然智能手機不具有老式桌面計算機的磁盤空間、計算能力或電池壽命,但它們仍然是深度學習應用程序很是好的目標。藉助少數技巧,並以幾個百分點的精度爲代價,如今能夠在這些多功能手持設備上運行強大的神經網絡。這爲數以千計的激動人心的應用打開了大門。
閱讀更多幹貨好文,請關注掃描如下二維碼: