本文來自AI新媒體量子位(QbitAI)
在移動端本地運作神經網絡成了明顯的趨勢,Google還為此推出了MobileNet架構。
MobileNet架構怎麼用?Coastline Automation創始人Matt Harvey最近在Medium上釋出了一份教程,教你用MobileNet來識别道路。
Coastline是一家用深度學習來監測行車情況、防止車禍的公司。以下是Matt Harvey的教程:
作為卷積神經網絡中的新成員,MobileNet有着很多令人驚豔的表現,今天我們就用資料集訓練一個試試。
MobileNet具有以下酷炫的特點:
1. 它們非常非常小
2. 它們非常非常快
3. 它們非常非常準
4. 它們很容易調試
這些特點是非常重要的。
目前,很多移動端上的深度學習任務都是在雲端完成的。當你想要讓手機識别一張圖檔,程式會先把這張圖檔通過網絡發送到遠端伺服器上進行分類,随後再将結果發送回手機上。
随着手機計算能力的迅猛增加,加上SqueezeNet和MobileNet等架構讓計算機視覺所需要的網絡複雜度快速下降,深度學習計算很快就能完全在裝置本地完成。
移動裝置本地的深度學習,除了能在沒有網絡連接配接的情況下正常運作之外,另一個長處是節省時間,比如說一個車輛安全應用,對反應速度要求非常高,把圖檔傳送到雲端處理顯然是不現實的。
是以,本文按照以下的順序來介紹MobileNet:
1. MobileNet是什麼?
2. 怎樣搭建自己的資料集,在TensorFlow下訓練MobileNet?
3. 怎樣用TensorFlow訓練一個在ImageNet上訓練過的模型?
4. 跟Inception V3相比,MobileNet的表現怎麼樣?
5. 怎樣使用再訓練(retrained)的MobileNet來識别圖檔?

MobileNet是由Google的研究者們設計的一類卷積神經網絡。它們在手機上運作,計算消耗小、運作速度快,是以很适合在移動端上做應用。
MobileNet和傳統的CNN在結構上的差别主要是,傳統CNN中在批規範化和ReLU(線性整流函數)前邊,是一個3×3卷積層,而MobileNet将卷積過程分為一個3×3深度方向的卷積和一個1×1點對點的卷積。如果你想了解個中細節和緣由的話,我強烈建議你讀一下他們的論文。
論文:
MobileNets: Efficient Convolutional Neural Networks for Mobile Vision Applications
https://arxiv.org/pdf/1704.04861.pdf
那麼MobileNet的短闆是什麼呢?準确性。跟我們熟悉的那些大型、消耗巨大資源的神經網絡相比,MobileNet的準确性不如前者高。但是MobileNet的長處是能夠在功耗和性能之間尋求良好的平衡點。
MobileNet擁有兩個表觀變量:width multiplier和resolution multiplier,我們可以通過調整這兩個變量值來使得模型适應具體問題。Width multiplier讓我們把網絡變得稀疏,而resolution multiplier可以改變輸入圖檔的分辨率,進而降低每層網絡間的内部表達。
Google開源了MobileNet,并随之開放了16個ImageNet checkpoint,每一個對應一種不同的參數結構。這為我們訓練自己的小又快的圖像分類器提供了一個良好的開端。
我們今天的挑戰是搭建一個能夠識别道路和非道路圖檔的分類器。這就像《矽谷》裡面的“hot dog, not hot dog”應用,把熱狗改成了道路。
為什麼選擇道路呢?因為在Coastline,我們正在基于計算機視覺開發用于汽車安全的移動應用。跟所有涉及視覺的app一樣,使用者隐私是非常需要考慮的一點。是以當使用者打開我們的app時,系統會首先檢查它看到的是否是道路。如果不是的話,那麼它就會關閉攝像頭。我們希望這個過程能夠在盡可能快速、隻占用少量資源的情況下完成。
為了解決這個問題,我們需要先為它建立資料集。我們的目标是收集10,000張圖檔,道路和非道路的圖檔大概各占50%。
我們從以下幾個來源得到相應的圖檔:
從我們自己的資料集裡,随機選取4,000張顯然是道路的圖檔;
從ImageNet裡随機選取2000張顯然不是道路的圖檔;
從網上選取3000張不那麼明顯的非道路圖檔,以防分類器學會的是區分“天空、非天空”;
從網上選取1000張不那麼明顯的道路圖檔,以防分類器把擋風玻璃上的倒影等特征錯認為道路特征。
我們将會把圖檔放進“道路”或“非道路”檔案夾,這就是我們在重新訓練網絡之前所需要的圖檔上的準備工作。
此外,從網上搜集的圖檔可以有效地增加你的資料集的多樣性,但這樣做也有一個缺點,網站上圖檔的标簽往往有些混亂。比如說,通過搜尋“道路風景(road landscape)”所得到的圖檔可能是在美美的自然風光背景下鄭重有條通向前方的道路:
或者是群山中有一條隐約可見的小路:
為解決這個問題,我們可以挨個浏覽每張圖檔然後手動進行标注,但如果是這樣那我們還要Deep learning幹嘛呢?
實際上,我們将在所有資料的基礎上重新訓練一個大型的網絡(比如Inception V3),注意要通過early stopping和heavy data augmentation等方法來防止過拟合。
然後我們讓網絡對資料集中所有的圖檔(包括之前用來訓練的圖檔)進行分類,然後記錄那些分錯類或不确定的圖檔。随後我們逐個排查這些圖檔,把它們移動到正确的分類下。
這與之前手動分類圖檔相比,需要進行的調整的圖檔數量大大減少。重複這個多次步驟,能夠讓我們的準确率比Inception提高7個百分點。
随後我們将會使用TensorFlow以及遷移學習來在我們這個特定的資料集上對MobileNet進行調整。
TensorFlow擁有一些很好的工具,你可以使用它們在不碼任何代碼的情況下就能夠重新訓練MobileNet。
TensorFlow下再訓練MobileNet詳情:
https://github.com/tensorflow/tensorflow/commit/055500bbcea60513c0160d213a10a7055f079312
你可以用TensorFlow範例檔案夾裡的腳本檔案,來在你自己的資料上重新訓練MobileNet。
等等!你應該使用哪一版的MobileNet呢?這是個好問題。讓我們先簡單訓練一下比較各個版本的表現。為了開始訓練,我們将會運作以下一段來自TensorFlow repository根目錄下的腳本:
代碼中“architecture”的标簽對應着将要重新訓練的MobileNet的版本。這裡“1.0”對應着width multiplier,取值範圍有1.0,0.75,0.50和0.25。“224”則對應着image resolution/resolution multiplier,這裡可以選擇的值有224,192,160和128。具體來說,為了訓練最小型的MobileNet,你應該用“—architecture mobilenet_0.25_128”。
代碼中所涉及的其他重要的參數有:
learning_rate:這是你需要進行調整的參數,我發現設定為0.0001有較好的訓練效果。
testing and validation percentage:這個腳本将會把你的資料分為 訓練集/驗證集/測試集 三類。網絡将會使用訓練集進行訓練,在每一個“eval_step_interval”之後使用驗證集對網絡表現的評估進行更新,最後在“how_many_training_steps”之後使用測試集進行測試,給出最終的分數。
validation_batch_size:把這項設為-1意味着讓腳本使用你所有的資料來進行驗證。當你沒有很多資料時(比如說這裡我們隻有10000張圖檔),把這項設為-1可以有效地較少評估步驟中的差異。
用這種方法訓練幾個版本的MobileNet之後,讓我們看看他們之間的比較吧。
為了得到比較的基準,我們花18分鐘對Inception進行了600步訓練,最終達到了95.9%的正确率,模型大小有84MB。
在測試對1,000張圖檔進行快速識别時發現,Inception可以在NVIDIA GeForce 960m GPU的架構上以19fps(frame per second,每秒鐘識别的圖檔數)的速度對圖檔進行識别。
當然,這個結果還有很多改進空間,但我們不打算在這上面繼續花時間了。
訓練Inception V3,隻需要将腳本中的-architecture-标簽那裡改為inception_v3即可。
旁注:為什麼準确率隻有95.9%?這看起來應該是個很好解決的問題。确實,除了我們可以對訓練參數進行充分的調試之外(我們實際上在另一次采用不同結構的訓練中取得了98.9%的準确率),其實這兩個類别之間的界定也有一些模糊。比如說:
有一張圖檔的内容是是樹林中一條不清晰的小徑。這到底是一條鐵路還是馬路?我自己都不清楚。
有一張圖檔是,在風景名勝中的遠處有條路。這到底是算作是一個風景還是一條道路?或者是算作是一張圖檔中的道路?什麼情況下我們認為這個分類會改變?
有一些偏藝術風的圖檔,是否應該算作是道路呢?
那麼,MobileNet的表現如何呢?不出意外,沒那麼好。但是,犧牲一些準确率卻在其他方面有了很大的提升。
使用最大的MobileNet(1.0, 224),我們能夠在4分鐘的訓練下達到95.5%的正确率。最終産生的模型大小也僅有17Mb,在同樣的GPU下能夠以135fps的速度運作。
與Inception相比,MobileNet訓練出的模型速度是前者的7倍,而尺寸隻有前者的四分之一,準确率上隻損失了0.4%。
那麼最小尺寸的MobileNet(0.24, 128)表現怎麼樣呢?準确率下降了更多,隻有89.2%,但是運作速度有450 fps,模型的大小僅有930kb,還不到1Mb!
現在你擁有了在你特定資料集上的重新訓練後的MobileNet,是時候來試試了。不出意外的是,TensorFlow上也有相應的腳本檔案來完成這項功能。
△ 我們的算法把這張圖檔識别為道路,雖然信心值隻有0.686811,但也很不錯了
旁注:值得說明的是,在我們這個相當簡單的兩分類問題中,準确度(與模型大小、運作速度之間)的權衡沒有這麼顯著。對于像擁有1001個分類的ImageNet來說,這個權衡就顯得非常重要了。
見Google公布的表格:
https://research.googleblog.com/2017/06/mobilenets-open-source-models-for.html
MobileNet的設計初衷是為了在移動端上運作神經網絡。
接下來,我們還會創造一些新的訓練資料,再進行精細的調試,然後将我們的再訓練的MobileNet應用到一個Android app當中去。我們将會看到在現實中它可以達到怎樣的運作速度和準确率。
【完】
本文作者:王瀚宸
原文釋出時間:2017-07-30