一文看懂如何搭建AI应用:10周学会深度学习,还赢下5千美元
春節(jié)后第一個(gè)休息日,量子位給大家準(zhǔn)備了一個(gè)不一樣的故事。
在這個(gè)故事里,主人公David Brailovsky(就叫阿D吧)參加了一場(chǎng)計(jì)算機(jī)視覺比賽。這個(gè)挑戰(zhàn)賽要求基于卷積神經(jīng)網(wǎng)絡(luò)(CNN),做出一個(gè)識(shí)別紅綠燈的人工智能應(yīng)用模型。
于是阿D花了10周的時(shí)間,從0開始,一點(diǎn)一滴摸索著,搭建、調(diào)試、訓(xùn)練和一個(gè)深度學(xué)習(xí)系統(tǒng)。而且還在最后的比賽中一舉奪魁,贏了5000美元。
主人公把這個(gè)有點(diǎn)逆襲的過程,原原本本的寫了下來。量子位也希望對(duì)人工智能感興趣的朋友仔細(xì)看一看。不用擔(dān)心,并不是AI專家才能理解這篇文章。因?yàn)槿闹攸c(diǎn)在與搭建一個(gè)人工智能應(yīng)用模型的思路和方法,而不是拘泥于技術(shù)實(shí)現(xiàn)。
從實(shí)踐應(yīng)用的角度出發(fā),搭建一個(gè)AI模型,并不是從0開始寫代碼的過程。
最初,是選擇一些功能近似的既有模型,然后進(jìn)行微調(diào),從而把既有模型的能力,從原來的任務(wù)“遷移”到新任務(wù)上。然后使用數(shù)據(jù)進(jìn)行訓(xùn)練,訓(xùn)練過程中嘗試不同的調(diào)整,以觀察哪些調(diào)整可以起效,哪些調(diào)整沒有效果。
這個(gè)過程中重要的一步,是把幾個(gè)較低精度的模型組合在一起,反而得到了較高精度的輸出結(jié)果。隨后,測(cè)試并且獲得較好的效果。
如前所述,下文沒有過于晦澀的技術(shù)內(nèi)容,量子位選擇推薦這篇,是因?yàn)橛兄诶斫馊绾卧趯?shí)踐中利用人工智能解決問題。
那么,我們就跟著阿D的講述就開始吧。
正文分割線
△?一個(gè)基于深度學(xué)習(xí)的交通燈識(shí)別分類器Demo
左上角是根據(jù)圖片給出的判斷
挑戰(zhàn)
我最近在一個(gè)交通燈識(shí)別挑戰(zhàn)賽中贏得了第一名,這是由一家公司組織的計(jì)算機(jī)視覺競(jìng)賽。挑戰(zhàn)的目標(biāo)是識(shí)別行車載攝像頭拍下的圖像中,交通燈的狀態(tài)。
在任何給定的圖像中,要做出這樣一個(gè)人工智能應(yīng)用模型(分類器):可以輸出場(chǎng)景中是否有交通燈,以及它是紅色還是綠色。 且應(yīng)該僅識(shí)別行駛方向上的交通燈。
上面的三張圖像,就是需要預(yù)測(cè)的三類可能的情況:沒有交通燈,紅色或綠色交通燈。
挑戰(zhàn)要求解決方案基于卷積神經(jīng)網(wǎng)絡(luò),這是一種在使用深度神經(jīng)網(wǎng)絡(luò)進(jìn)行圖像識(shí)別領(lǐng)域非常流行的方法。 參賽的算法模型,會(huì)被依照準(zhǔn)確性以及模型的大小兩個(gè)維度進(jìn)行評(píng)分。 較小的模型得分更高。 此外,獲勝所需的最低準(zhǔn)確度為95%。
主辦方提供了18659個(gè)經(jīng)過標(biāo)記的圖像作為訓(xùn)練數(shù)據(jù)。每個(gè)圖像都標(biāo)記為上面提到的三個(gè)類別之一。
軟件和硬件
我用Caffe深度學(xué)習(xí)框架(可以理解為一組工具包)來訓(xùn)練模型。主要原因是Caffe里有各種各樣的預(yù)訓(xùn)練模型。
在分析結(jié)果、數(shù)據(jù)探索和特殊腳本的工作中,我使用了Python,NumPy以及Jupyter Notebook。
我還用了亞馬遜的GPU實(shí)例(g2.2xlarge)用于訓(xùn)練模型。最后的費(fèi)用是263美元之巨。用來訓(xùn)練和運(yùn)行模型的代碼和文件在GitHub上。
最終分類器
最終的分類器在主辦方的測(cè)試集上,實(shí)現(xiàn)了94.955%的精度,模型大小為7.84 MB。作為比較,GoogLeNet的模型大小為41MB,VGG-16的模型大小528MB。
主辦方大發(fā)慈悲同意把94.955%當(dāng)作95%看待,讓我通過最低要求。
追求更高精度的過程中,伴隨大量的試驗(yàn)和錯(cuò)誤。 其中一些我知道背后的邏輯,有些只是“碰碰運(yùn)氣”。我將講述一些在模型中試圖改進(jìn)的事情,有的搞定了有的沒搞定。
搞定的部分
遷移學(xué)習(xí)
我從嘗試微調(diào)一個(gè)模型起步,這是一個(gè)在ImageNet圖像數(shù)據(jù)庫(kù)上用GoogLeNet架構(gòu)預(yù)訓(xùn)練的模型。很快,這就讓我得到> 90%的準(zhǔn)確性!
不過,主辦方在挑戰(zhàn)的官方頁(yè)面中提到,通過微調(diào)GoogLeNet模型應(yīng)該可以達(dá)到93%的精度。我也不知道我哪里出了問題。
SqueezeNet
SqueezeNet:具有AlexNet(圖像分類模型)級(jí)精度,但參數(shù)少50倍,模型尺寸小于0.5MB。
由于競(jìng)爭(zhēng)獎(jiǎng)勵(lì)使用小模型的解決方案,早期我決定尋找一個(gè)緊湊的網(wǎng)絡(luò)模型,盡可能少的參數(shù),仍然可以產(chǎn)生良好的效果。 但大多數(shù)最近發(fā)布的網(wǎng)絡(luò)非常深,有很多參數(shù)。
SqueezeNet似乎是一個(gè)非常好的選擇,它也有一個(gè)在ImageNet上訓(xùn)練好的預(yù)訓(xùn)練模型,可用在Caffe的Model Zoo(類似手機(jī)上的應(yīng)用商店)中方便取用。
△?SqueezeNet網(wǎng)絡(luò)架構(gòu)
網(wǎng)絡(luò)通過以下方式保持緊湊:
-
主要使用1x1卷積過濾,輔助一些3x3
-
減少3x3過濾的輸入通道數(shù)
有關(guān)更多詳細(xì)信息,我建議閱讀Lab41的博客。
在一些來回調(diào)整學(xué)習(xí)率后,我能夠微調(diào)預(yù)訓(xùn)練模型以及從零開始訓(xùn)練,并且準(zhǔn)確度能夠達(dá)到很好的92%!很酷!
旋轉(zhuǎn)圖像
大多數(shù)圖像是水平橫置的,如上所示,但約2.4%是垂直的,另外還有好多種不同的方向。如下所示。
雖然這些在數(shù)據(jù)集中占比不大,但我們?nèi)韵M约旱哪P鸵材軐?duì)他們進(jìn)行正確分類。
不幸的是,在jpeg圖像中沒有指定方向的EXIF數(shù)據(jù)。起初,我考慮做一些啟發(fā)式算法來識(shí)別天空和相應(yīng)地翻轉(zhuǎn)圖像,但這似乎沒那么簡(jiǎn)單。
然后我改讓圖像按照固定角度旋轉(zhuǎn)。最開始我嘗試訓(xùn)練網(wǎng)絡(luò)隨機(jī)以0°,90°,180°,270°進(jìn)行旋轉(zhuǎn)。這沒什么改善。但是,當(dāng)我對(duì)每個(gè)圖像進(jìn)行四次旋轉(zhuǎn)而得的預(yù)測(cè)取平均值時(shí),改善出現(xiàn)了!
92% → 92.6%。
澄清一下:上面提到的“預(yù)測(cè)取平均值”,我的意思是平均了每個(gè)類在4個(gè)圖像變化中產(chǎn)生的模型的概率。
過采樣修剪
在訓(xùn)練期間,SqueezeNet網(wǎng)絡(luò)默認(rèn)首先在輸入圖像上執(zhí)行隨機(jī)修剪,我沒有對(duì)這個(gè)進(jìn)行改動(dòng)。 這種類型的數(shù)據(jù)增加使網(wǎng)絡(luò)更好地泛化。
類似地,當(dāng)生成預(yù)測(cè)時(shí),我對(duì)輸入圖像進(jìn)行了一些修剪以及平均結(jié)果。 我使用5個(gè)修剪:4個(gè)角和一個(gè)中心。 有現(xiàn)成的免費(fèi)Caffe代碼來完成這個(gè)任務(wù)。
92% → 92.46%
旋轉(zhuǎn)圖像與過采樣修剪帶來了非常輕微的改進(jìn)。
以較低的學(xué)習(xí)率進(jìn)行附加訓(xùn)練
所有模型在一定點(diǎn)后開始過擬合。我注意到這點(diǎn),是看到驗(yàn)證集損失開始在某一點(diǎn)上升。
40000迭代之后驗(yàn)證集損失開始上升
我在那個(gè)點(diǎn)停止了訓(xùn)練,因?yàn)槟P涂赡懿辉俜夯恕_@意味著學(xué)習(xí)率沒有時(shí)間衰減到零。 我試圖恢復(fù)訓(xùn)練過程,在模型開始過擬合時(shí),把學(xué)習(xí)率調(diào)低10倍。 這大概提高了0-0.5%的精度。
更多的訓(xùn)練數(shù)據(jù)
起初,我將數(shù)據(jù)分成3組:訓(xùn)練集(64%),驗(yàn)證集(16%)和測(cè)試集(20%)。幾天后,我認(rèn)為放棄36%的數(shù)據(jù)可能太多了。我合并了訓(xùn)練和驗(yàn)證集,并使用測(cè)試集來檢查我的結(jié)果。
我重新訓(xùn)練了一個(gè)模型,加入“圖像旋轉(zhuǎn)”和“低速率附加訓(xùn)練”,并得到了如下提升:
92.6% → 93.5%
在訓(xùn)練數(shù)據(jù)中重新標(biāo)簽錯(cuò)誤
當(dāng)分析分類器對(duì)驗(yàn)證集的錯(cuò)誤時(shí),我注意到一些錯(cuò)誤的置信度非常高。 換句話說,模型確定它是一件事(例如綠燈),而訓(xùn)練數(shù)據(jù)說明是相反的情況(例如紅燈)。
注意,在上面的圖中,最右邊的欄是相當(dāng)高的。 這意味著有大量的錯(cuò)誤有著> 95%的置信度。 當(dāng)仔細(xì)檢查這些情況時(shí),我發(fā)現(xiàn)這些通常錯(cuò)誤是源自訓(xùn)練集的地面實(shí)況(ground-truth),而不是訓(xùn)練好的模型。
我決定在訓(xùn)練集中修復(fù)這些錯(cuò)誤。 應(yīng)該是這些錯(cuò)誤混淆了模型,使其更難以進(jìn)行歸納。 即使最終測(cè)試集在地面實(shí)況中有錯(cuò)誤,一個(gè)更泛化的模型在所有圖像中,更有可能達(dá)到更高的精度。
我手動(dòng)標(biāo)記了709張圖像,當(dāng)時(shí)我的一個(gè)模型產(chǎn)生了錯(cuò)誤。 這改變了709張圖像中337張的地面實(shí)況。 這個(gè)手工活耗時(shí)一小時(shí),我還用了python腳本來提升效率。
以上是重新標(biāo)記和重新訓(xùn)練模型后的結(jié)果。看起來好多了!
這對(duì)模型的提升度為:
93.5% → 94.1%
組合模型
使用幾個(gè)模型在一起并平均其結(jié)果也提高了精度。 我在訓(xùn)練過程中對(duì)參與整體的模型進(jìn)行了不同類型的修改。 使用從頭開始訓(xùn)練的模型(即使自身準(zhǔn)確度較低),結(jié)合精細(xì)調(diào)教過的預(yù)處理模型,我們獲得了顯著改進(jìn)的結(jié)果。可能這種方式學(xué)習(xí)到了更多的特征。
最后我們組合了3個(gè)模型,精度為94.1%,94.2%和92.9%,合在一起精度為94.8%。
沒搞定的部分
沒搞定的太多了!希望其中的一些想法在別處有用。
與過擬合戰(zhàn)斗
當(dāng)試圖處理過度擬合時(shí),我嘗試了幾個(gè)事情,沒有一個(gè)產(chǎn)生顯著的改進(jìn):
-
增加網(wǎng)絡(luò)中的丟失率
-
更多數(shù)據(jù)增強(qiáng)(隨機(jī)移位,縮放,傾斜)
-
分配更多的訓(xùn)練數(shù)據(jù):使用90/10分隔而不是80/20
平衡數(shù)據(jù)集
數(shù)據(jù)集不是非常平衡:
-
19%的圖像標(biāo)有沒有交通燈
-
53%的是紅燈
-
28%的是綠燈
我試圖使用過采樣較不常見的類來平衡數(shù)據(jù)集,但沒有發(fā)現(xiàn)任何改進(jìn)。
區(qū)分晝夜
我的直覺是,識(shí)別交通燈在白天和夜間是非常不同的。我想也許我可以幫助這個(gè)模型,把它分成兩個(gè)更簡(jiǎn)單的問題。
通過觀察它們的平均像素強(qiáng)度,將圖像分為白天和黑夜是相當(dāng)容易的:
你可以看到一個(gè)非常自然的圖像分離,低平均值即暗圖像,在夜間拍攝,明亮的圖像,在白天拍攝。
我試過兩種方法,都沒有改善結(jié)果:
-
為白天圖像和夜間圖像訓(xùn)練兩個(gè)單獨(dú)的模型
-
訓(xùn)練網(wǎng)絡(luò)預(yù)測(cè)6種分類而不是3種,方法也是預(yù)測(cè)是白天還是晚上
使用SqueezeNet的更好的變體
我用兩個(gè)改進(jìn)的SqueezeNet變體進(jìn)行了一點(diǎn)嘗試。第一次使用殘留連接和第二次訓(xùn)練與密集→稀疏→密集訓(xùn)練。沒什么用。
交通燈定位
在閱讀deepsense.io的一篇關(guān)于他們?nèi)绾乌A得鯨魚識(shí)別挑戰(zhàn)的文章后,我試圖訓(xùn)練一個(gè)定位器,即首先識(shí)別交通燈在圖像中的位置,然后在一個(gè)小區(qū)域識(shí)別交通燈狀態(tài)。
我花費(fèi)數(shù)小時(shí)用sloth來注釋約2000張圖片。當(dāng)試圖訓(xùn)練一個(gè)模型,它過擬合得非常快,可能是因?yàn)闆]有足夠的標(biāo)簽數(shù)據(jù)。 也許這個(gè)方法可行,如果我能標(biāo)注更多的圖像。
在困難案例上訓(xùn)練分類器
通過挑選分類器置信度小于97%的數(shù)據(jù),我跳出30%“難度更高”的圖片。然后我試圖只用這些圖片訓(xùn)練分類器。沒什么改善。
不同的優(yōu)化算法
我短暫的使用Caffe的Adam結(jié)算期,取代線性降低學(xué)習(xí)率的SGD,但是沒有看到任何改進(jìn)。
向組合中添加更多模型
由于組合的方法證明有效,我曾嘗試把規(guī)模擴(kuò)大一倍。我試著改變不同的參數(shù)來產(chǎn)生不同的模型,并將它們添加到組合中:初始種子,dropout rate,不同的訓(xùn)練數(shù)據(jù)(分組方法不同),訓(xùn)練中不同的檢查點(diǎn)。這些都沒有帶來顯著的改善。
最終分類器細(xì)節(jié)
我的分類器,最后由三個(gè)單獨(dú)訓(xùn)練的網(wǎng)絡(luò)組合而成。它們給每個(gè)類的概率,進(jìn)行加權(quán)后的平均值作為輸出。所有這三個(gè)網(wǎng)絡(luò)都基于SqueezeNet,但各自經(jīng)過了不同的訓(xùn)練。
一號(hào)模型 - 以過采樣進(jìn)行預(yù)訓(xùn)練的網(wǎng)絡(luò)
訓(xùn)練基于重新打標(biāo)簽的訓(xùn)練集(修復(fù)地面實(shí)況錯(cuò)誤之后)。這個(gè)微調(diào)過的模型,基于ImageNet上一個(gè)預(yù)訓(xùn)練的SqueezeNet模型。
訓(xùn)練期間的數(shù)據(jù)增強(qiáng):
-
隨機(jī)水平鏡像
-
送入網(wǎng)絡(luò)之前隨機(jī)裁剪227×227大小的補(bǔ)丁
測(cè)試時(shí),對(duì)每個(gè)圖像進(jìn)行10各不同的變體預(yù)測(cè),然后取計(jì)算平均值作為最終預(yù)測(cè)。這10種不同的變體預(yù)測(cè)是:
-
5次227×227大小的裁剪:四個(gè)角各一次,圖片中央一次
-
對(duì)每一個(gè)裁剪,都生成一個(gè)水平鏡像
驗(yàn)證集的模型精度:94.21%
模型大小:~2.6 MB
二號(hào)模型 - 增加旋轉(zhuǎn)不變性
和一號(hào)模型非常類似,只不過增加的是圖像旋轉(zhuǎn)。在訓(xùn)練時(shí)間期間,圖像隨機(jī)旋轉(zhuǎn)90°,180°,270°或根本不旋轉(zhuǎn)。 在測(cè)試時(shí),一號(hào)模型中描述的10個(gè)變體中的每一個(gè)通過旋轉(zhuǎn)90°,180°和270°而產(chǎn)生三個(gè)變體。 共有40個(gè)變量被我們的模型分類和平均在一起。
驗(yàn)證集的模型精度:94.1%
模型大小:~2.6 MB
三號(hào)模型 - 從頭開始訓(xùn)練
這個(gè)模型不是微調(diào)得來,而是從零開始訓(xùn)練。即便他的準(zhǔn)確性低一些,但是從訓(xùn)練集上學(xué)到了不同的特性。用在一個(gè)組合里面時(shí),這可能是有用的。
訓(xùn)練和測(cè)試期間的數(shù)據(jù)增強(qiáng)與一號(hào)模型相同:鏡像和裁剪。
驗(yàn)證集的模型精度:92.92%
模型大小:~2.6 MB
把模型組合在一起
每個(gè)模型輸出三個(gè)值,表示圖像屬于三個(gè)類中的每一個(gè)的概率。我們用以下權(quán)重平均它們的輸出:
-
一號(hào)模型:0.28
-
二號(hào)模型:0.49
-
三號(hào)模型:0.23
我通過對(duì)可能的值進(jìn)行網(wǎng)格搜索并在驗(yàn)證集上測(cè)試來找到權(quán)重的值。它們對(duì)驗(yàn)證集,可能有點(diǎn)過度擬合,但也許不是太多,因?yàn)檫@是一個(gè)非常簡(jiǎn)單的操作。
驗(yàn)證集的模型精度:94.83%
模型大小:~7.84 MB
在Nexar測(cè)試集上的精度:94.955% [撒花]
模型錯(cuò)誤示例
棕櫚樹上因?yàn)檠9猱a(chǎn)生的綠點(diǎn),讓模型錯(cuò)誤的判斷這是一個(gè)綠燈信號(hào)。
模型把直行的紅燈判斷成綠燈。這種路口不止一個(gè)交通燈的情況有點(diǎn)棘手。
圖中右側(cè)有一個(gè)亮起綠燈的信號(hào)燈,但是模型認(rèn)為沒有交通信號(hào)燈。
結(jié)語
這是我第一次在一個(gè)實(shí)際案例中應(yīng)用深度學(xué)習(xí)!效果這么好讓我很高興。在這個(gè)過程中我學(xué)到了很多很多。以后有機(jī)會(huì)再跟大家交流更多~
除了這篇,今天還推送了另外一篇學(xué)習(xí)AI的文章,推薦繼續(xù)閱讀:
秘籍:如何用廉價(jià)硬件玩轉(zhuǎn)深度學(xué)習(xí),成本不到1000美元
One more thing …
量子位的微信群已有不少關(guān)注和研究人工智能的朋友,從中國(guó)到美國(guó),從金融到醫(yī)療……
如果你也想?yún)⑴c討論,結(jié)識(shí)同好,請(qǐng)?zhí)砑恿孔游恍≈值奈⑿盘?hào):qbitbot,然后做個(gè)自我介紹,說明職業(yè)或研究領(lǐng)域和方向,小助手會(huì)拉你進(jìn)群~
原文發(fā)布時(shí)間:2017-02-05
總結(jié)
以上是生活随笔為你收集整理的一文看懂如何搭建AI应用:10周学会深度学习,还赢下5千美元的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql运维管理-mysqldump
- 下一篇: 虚拟化容器Docker的安全性讨论