0
本文作者: AI研習(xí)社-譯站 | 2018-04-20 15:30 |
雷鋒網(wǎng)按:本文為雷鋒字幕組編譯的技術(shù)博客,原標(biāo)題What I've learned building a deep learning Dog Face Recognition iOS app,作者為Octavian Costache。
翻譯 | 汪寧 王飛 劉澤晟 整理 | 凡江
我做了一個(gè)狗臉識(shí)別的深度學(xué)習(xí)ios應(yīng)用,并想跟你分享這些心得。
我是一個(gè)初創(chuàng)公司的軟件工程師。曾經(jīng)有段時(shí)間在谷歌工作,做谷歌財(cái)經(jīng)圖表和Multiple inboxes,并主管谷歌地圖的業(yè)務(wù)。最近,我開了一家叫Spring的購物公司。同時(shí),我也是一個(gè)創(chuàng)業(yè)者,在空余時(shí)間里我喜歡做一些副業(yè)。
幾個(gè)月前,我開始做一個(gè)用于狗狗拍照app的臉部過濾器。當(dāng)你將app對(duì)著你的狗時(shí),這個(gè)app就會(huì)將這個(gè)過濾器作用在狗的臉上。有9200萬張照片被標(biāo)記為dogsofinstagram——你可能會(huì)發(fā)現(xiàn)有一些用戶不在其中——?jiǎng)?chuàng)造人們想要的東西是額外的動(dòng)力:
我需要
建立一個(gè)深度學(xué)習(xí)模型,提取狗的面部特征。
在iPhone上實(shí)時(shí)視頻的頂部運(yùn)行
使用ARKit顯示3D過濾器(二維的表示不是那么酷)
從對(duì)深度學(xué)習(xí)一無所知到做出一個(gè)還不錯(cuò)的app。我想要分享我在每一步中所學(xué)到的經(jīng)驗(yàn)。
我希望那些剛接觸深度學(xué)習(xí)的人會(huì)覺得這些方法很有用。
第1步:深度學(xué)習(xí)大都是現(xiàn)成的
我需要回答的第一個(gè)問題是“這是可能的嗎?”。我的問題容易處理嗎?我應(yīng)該從哪開始?
一些簡單的搜索告訴我該學(xué)習(xí)TensorFlow對(duì)象檢測(cè)教程、研究論文,或者如何用現(xiàn)成的代碼構(gòu)建一個(gè)有邊界框的檢測(cè)器。
我的問題看起來是可以解決的(人們得到的各類結(jié)果在我所需要的范圍內(nèi)),但沒有現(xiàn)成的東西可以方便地用到我的用例中。試圖弄清楚如何修改現(xiàn)有的教程讓人惱火。
在閱讀博客文章的過程中,我開始轉(zhuǎn)向最基本的網(wǎng)絡(luò)課程,從基礎(chǔ)開始。事實(shí)證明這是一個(gè)非常好的決定。
在這個(gè)過程中,我了解到:
Andrew Ng的課程是關(guān)于卷積神經(jīng)網(wǎng)絡(luò)的課程(這是關(guān)于深度學(xué)習(xí)的一系列課程的第三部分)是學(xué)習(xí)應(yīng)用于計(jì)算機(jī)視覺的基礎(chǔ)概念和工具的一個(gè)好地方。沒有它,我什么也做不了。
Keras在TensorFlow上是一個(gè)高級(jí)的API,它是最容易使用的深度學(xué)習(xí)模型。TensorFlow本身對(duì)于初學(xué)者來說太底層,會(huì)讓初學(xué)者感到困惑。我確信Caffe/PyTorch也很棒,但是Keras真的幫了我的忙。
Conda是管理python環(huán)境的一種很好的工具。Nvidia-docker也很棒,但是只有當(dāng)你可以使用GPU的時(shí)候才有必要使用它。
剛開始時(shí),你很難從網(wǎng)絡(luò)教程中學(xué)習(xí)最基本概念。如果你從更適合你的課程或書本中學(xué)習(xí)基本的核心概念。它將使你的學(xué)習(xí)更容易。
第2步:弄清楚如何實(shí)現(xiàn)特征點(diǎn)檢測(cè)
用我最近發(fā)現(xiàn)的基本知識(shí),我已經(jīng)開始著手研究如何實(shí)現(xiàn)我的自定義模型。
“對(duì)象分類”和“對(duì)象檢測(cè)”在今天已經(jīng)是現(xiàn)成的了。我想要做的不是這些,而是后面這個(gè),在文獻(xiàn)中這個(gè)詞是“特征點(diǎn)檢測(cè)”(Landmark Detection) ,用術(shù)語概括我要做的事情會(huì)更方便一點(diǎn)。
現(xiàn)在,新的問題。什么樣的模型是好的?我需要多少數(shù)據(jù)?我該如何給數(shù)據(jù)貼上標(biāo)簽?如何去訓(xùn)練數(shù)據(jù)呢?一個(gè)好的最小可行開發(fā)工作流程又是怎什么樣?
第一個(gè)目標(biāo)是讓一些程序運(yùn)行起來。以后我可以再去做一些提升質(zhì)量方面的工作。俗話說在你跑之前先得學(xué)會(huì)走。
我的心得:
我用來標(biāo)記左眼/右眼/鼻子的工具,自己設(shè)計(jì)的,起來很糟糕,但是很實(shí)用。
建立自己的數(shù)據(jù)對(duì)用戶界面進(jìn)行標(biāo)注是一個(gè)非常好的想法。其他已有的標(biāo)簽對(duì)我來說沒用,它們只適用于Windows,要么就是做的太多了。后來,當(dāng)我需要對(duì)我所標(biāo)注的數(shù)據(jù)進(jìn)行修改(比如添加新的特征點(diǎn))時(shí),這種靈活性確實(shí)很有用。
標(biāo)記速度很重要。我每小時(shí)至少可以標(biāo)記300張照片。即每12秒就可以標(biāo)記一個(gè)圖像。標(biāo)記8000張照片只需要26小時(shí)。如果你想標(biāo)記數(shù)據(jù)的真實(shí)數(shù)量,那么每一秒都很重要。建立我自己的標(biāo)記集有一定的前期成本,但實(shí)際上幫助了你之后的工作。
手工標(biāo)記數(shù)據(jù)可以讓你很好地了解模型的內(nèi)容。
預(yù)處理圖像最初看起來像是一個(gè)細(xì)節(jié),但后來證明是很關(guān)鍵的,我花了幾天時(shí)間來理解如何修改它。查看Stack Overflow上的解答——是否在正確的位置調(diào)用preprocess_image是程序是否運(yùn)行的關(guān)鍵。
雖然并不是很精確,但程序已經(jīng)可以就位了。一個(gè)模型輸出并不離譜的東西,這讓我很開心。
這種微妙的黑盒子的感覺——在正確的地方做正確的事情時(shí)才會(huì)成功——這種感覺在幾乎每一步都存在。
跟蹤缺陷、識(shí)別問題、縮小問題的范圍——在一般軟件工程中是正常的——在今天的深度學(xué)習(xí)開發(fā)中并不那么容易。
對(duì)于像我這樣的初學(xué)者來說,弄清楚這個(gè)問題顯得夢(mèng)幻而偶然,而不是深思熟慮的結(jié)果。我不清楚這個(gè)行業(yè)里是否有人知道如何做好這一點(diǎn)——感覺更像是每個(gè)人都在試圖解決這個(gè)問題。
大約三周后,我就做成了一些事情:我可以給數(shù)據(jù)貼上標(biāo)簽,在上面訓(xùn)練模型,用一張照片在Jupyter Notebook運(yùn)行那個(gè)模型,然后得到真實(shí)的坐標(biāo)(帶有可疑的位置)作為輸出。
第3步:確保模型在iOS上運(yùn)行
現(xiàn)在有了一個(gè)簡單的工作模型,我的下一步是確保它能在一個(gè)手機(jī)上運(yùn)行,并且運(yùn)行得足夠快。
Keras/TensorFlow模型不能在iOS本地上運(yùn)行,但是蘋果有自己的神經(jīng)網(wǎng)絡(luò)運(yùn)行框架CoreML。在iOS上運(yùn)行.mlmodel 可以通過教程代碼完成。如此簡單的過程讓我被它征服了。
但是,即使是這個(gè)簡單的轉(zhuǎn)換步驟(從.h5 到.mlmodel)也不是沒有挑戰(zhàn)的。
蘋果將一個(gè).h5模型轉(zhuǎn)換成一個(gè).mlmodel模型的工具(稱為coremltools),是一個(gè)半成品。 使用pip安裝的版本在box外無法運(yùn)行,我必須使用python2.5在conda環(huán)境中從源代碼構(gòu)建它,打補(bǔ)丁。嘿,至少它有用。
弄清楚如何在手機(jī)上預(yù)先處理輸入圖像,就像模型所期望的那樣,卻出人意料的不簡單。我在stackOverflow提問,或者搜索博客文章,可什么都沒有。我最終通過給Matthijs Hollemans發(fā)送陌生郵件來找到了我的答案,讓我驚喜的是他的答案使我脫離困境!他甚至有一篇關(guān)于這個(gè)問題的博客文章。如果沒有他,我不會(huì)發(fā)現(xiàn)這篇文章。
事實(shí)證明,整個(gè)深度學(xué)習(xí)工具鏈仍在開發(fā)中。在深度學(xué)習(xí)領(lǐng)域,事物變化很快。
另一方面,我喜歡團(tuán)體小而富有活力,互幫互助的感覺。如果你像我一樣,有點(diǎn)迷糊,不要猶豫,直接發(fā)郵件問。最差也不過是沒有人回答。最好的情況卻是有個(gè)好人幫了你。就像Matthijs。感謝!
我的模型在實(shí)體機(jī)上以每秒19幀的速度運(yùn)行了,這就像一個(gè)神奇的劃時(shí)代事件。有了這個(gè)基礎(chǔ),現(xiàn)在我可以致力于提高質(zhì)量了。
第4步:讓模型運(yùn)行得更加完美
這的確需要一些時(shí)間。我該怎么做才能讓我的產(chǎn)品在深度學(xué)習(xí)模型外也表現(xiàn)良好?再多點(diǎn)數(shù)據(jù)?使用不同的頂層?使用不同的損失函數(shù)?層中使用不同的激活參數(shù)?太麻煩了!
循序漸進(jìn)似乎是最好的。不斷測(cè)試,訓(xùn)練,和前一次的運(yùn)行情況進(jìn)行比較,看看哪一個(gè)辦法起了作用。剛開始用少量的數(shù)據(jù),慢慢地?cái)U(kuò)大數(shù)據(jù)集。少量的數(shù)據(jù)意味著較短的訓(xùn)練時(shí)間。一旦利用大型數(shù)據(jù)集進(jìn)行訓(xùn)練。運(yùn)行一次得等待24小時(shí)是很常見的,這并不是真正的快速迭代。
數(shù)據(jù)擴(kuò)充是可能會(huì)出錯(cuò)的代碼。開始的時(shí)候可以略過這一部分,運(yùn)行的時(shí)候可以不運(yùn)行這一部分代碼,然后一點(diǎn)點(diǎn)增加數(shù)據(jù)擴(kuò)充部分的代碼。要保證代碼是穩(wěn)定的。你的模型應(yīng)該始會(huì)和你輸入的數(shù)據(jù)一樣好。準(zhǔn)備好時(shí)間會(huì)被浪費(fèi)掉,準(zhǔn)備好學(xué)習(xí)最優(yōu)做法需要時(shí)間。你必須要不斷往前走并且不斷往下做,不然你是不會(huì)從錯(cuò)誤中學(xué)到任何東西的。往前走,要勇于犯錯(cuò)。
這是我試著做這個(gè)項(xiàng)目的時(shí)所學(xué)到的:
這一點(diǎn)似乎顯而易見----使用TendorBoard對(duì)迭代開發(fā)能夠達(dá)到數(shù)量級(jí)的提高
從我的數(shù)據(jù)生成器中對(duì)圖像數(shù)據(jù)進(jìn)行調(diào)試,這能幫助我找到影響我模型的圖像處理的Bug。就像我對(duì)鏡像照片時(shí),雖然我并沒有交換左右眼。
和那些經(jīng)常訓(xùn)練模型、有經(jīng)驗(yàn)的人進(jìn)行交談,這節(jié)省了我很多時(shí)間。一個(gè)羅馬尼亞的機(jī)器學(xué)習(xí)團(tuán)隊(duì)和幾個(gè)慷慨的朋友證明這很重要(感謝Csomin Negruseri , Matt Slotkin , Qianyi Zhou以及Ajay Chainani)。讓別人來主動(dòng)問你遇到什么困難,這是不可能。
通常來說,不按照默認(rèn)規(guī)則來做并不是一個(gè)好主意。比如,當(dāng)我嘗試著用fisheries competition上發(fā)布的一個(gè)博客做頂層時(shí)-- 博客里面的使用了 activation='relu' ,雖然頂層呈現(xiàn)出來的結(jié)果很不錯(cuò),但是 activation='relu' 并不好。當(dāng)我試著使用我自己的L1 LOSS損失函數(shù)時(shí),呈現(xiàn)的結(jié)果比更加標(biāo)準(zhǔn)的MSE loss損失函數(shù)差很多。
編寫一個(gè)數(shù)據(jù)生成器很有必要。數(shù)據(jù)擴(kuò)充很重要。
當(dāng)你運(yùn)行教程時(shí),在幾百張圖片上學(xué)習(xí)和訓(xùn)練第一個(gè)模型,一個(gè)CPU就足夠了,使用GPU會(huì)顯得累贅。
在GPU上使用一個(gè)真實(shí)的數(shù)據(jù)集(8000張圖片)和一個(gè)數(shù)據(jù)生成器(80000張圖片)進(jìn)行訓(xùn)練十分重要,即使它要花24小時(shí)。
亞馬遜的GPU對(duì)個(gè)人開發(fā)來說比較昂貴,在24小時(shí)一次的迭代當(dāng)中,大概每小時(shí)花一美元,花費(fèi)會(huì)迅速增加。謝謝Cosmin讓我通過SSH進(jìn)入你的電腦,讓我能夠免費(fèi)使用你的GPU。
檢測(cè)有點(diǎn)不太準(zhǔn)確。當(dāng)然,這只是我測(cè)試用的狗頭,一個(gè)從亞馬遜買的狗面具。絕不會(huì)移動(dòng),總是很開心地望著照相機(jī)!
盡管并不完美,但是最后的結(jié)果表現(xiàn)得相當(dāng)好,足夠可以用來做一個(gè)app。
并且我感覺,如果我是一個(gè)全職的機(jī)器學(xué)習(xí)工程師,讓其更好是很有可能的。
但是像其他的產(chǎn)品一樣,最后的百分之二十進(jìn)程會(huì)花掉百分之八十的時(shí)間,我認(rèn)為在下一個(gè)版本中,我必須要將這部分工作納入其中。
如果你對(duì)你的產(chǎn)品羞恥感較弱,你可能會(huì)需要花很多的時(shí)間才能完成這些工作,特別是對(duì)于業(yè)余項(xiàng)目來說。
第5步:搭建iOS應(yīng)用,過濾器,然后把它們集成在一起
手上有了足夠好的模型,現(xiàn)在可以放到Swift,ARKit上,并且事實(shí)證明,SpriteKit可以用于2D內(nèi)容。iOS及其框架仍舊讓我印象深刻。如果你能正確看待它,這些天能夠在手機(jī)上做的事情的確很令人興奮。
這個(gè)應(yīng)用本身很基礎(chǔ),一個(gè)大的記錄按鈕,一個(gè)滑動(dòng)切換過濾器,一個(gè)分享按鈕。
大部分的工作是在學(xué)習(xí)ARKIT,然后弄明白它的限制。如何把3D模型放進(jìn)去,如何從場(chǎng)景,燈光,動(dòng)畫和幾何圖形中添加和移除這些模型
在這個(gè)過程中我學(xué)到的:
ARKit很好。是的,添加3D內(nèi)容很容易,很有意思,API也很棒。一旦你把某樣模型放到場(chǎng)景中,它就很馬上起作用。
ARHitTestResult表明,通過圖片中的像素,它會(huì)返回給你像素的三維坐標(biāo),確實(shí)有用但是精度不夠好。結(jié)果中百分之七十是在正確的位置,百分之三十出現(xiàn)在了錯(cuò)誤的位置。這給我把過濾器應(yīng)用在臉部識(shí)別上造成了困難。
備用計(jì)劃:構(gòu)建二維的過濾器。 SpriteKit,蘋果的二維游戲引擎,使用起來十分簡單--這個(gè)引擎有一個(gè)內(nèi)置的物理引擎。使用和學(xué)習(xí)起來很有意思(雖然表面上是這樣)。
第一代結(jié)合了CoreMl的ARKit技術(shù)讓我大開眼界。
在幾個(gè)星期之內(nèi),我就能夠在實(shí)時(shí)的照相機(jī)視頻流上運(yùn)行我的深度學(xué)習(xí)模型了,抽取出臉部特征點(diǎn),利用Arkit展示出三維的內(nèi)容,使用SceneKit展示出二維的內(nèi)容,處理的精度相當(dāng)不錯(cuò)。
僅僅在兩年前,為了相似的技術(shù)(用于人臉),SnapChat不得不花一億五千萬美元買下一個(gè)公司?,F(xiàn)在iOS免費(fèi)提供人臉標(biāo)志檢測(cè),并且不像我的ARHitTestResult的結(jié)果,它的精確度很高。這種技術(shù)迅速商品化真是太不可思議了
再過幾年,一旦iPhone背面有紅外點(diǎn),你的環(huán)境的3D映射應(yīng)該變得相當(dāng)好。
總結(jié)
對(duì)于深度學(xué)習(xí)的應(yīng)用,人工智能的熱潮和什么相關(guān),iPhone當(dāng)前所擁有的性能,以及ARkit,SpriteKit,Swift,我感覺自己對(duì)它們有了一個(gè)深刻的理解。
現(xiàn)在你還不能找到現(xiàn)成的深度學(xué)習(xí)模型,因?yàn)樯疃葘W(xué)習(xí)相關(guān)的一切都還不是很普遍,但是,在將來情況就會(huì)改善。
如果你跳過一些必要的步驟,以及一些必要的限制,對(duì)我來說就像技術(shù)在這篇博客的應(yīng)用。
我不必深入神經(jīng)網(wǎng)絡(luò)的內(nèi)部細(xì)節(jié),也不必直接觸碰任何TensorFlow相關(guān)的東西。
高層次的Keras遠(yuǎn)遠(yuǎn)夠用了。一周的關(guān)于卷積神經(jīng)網(wǎng)絡(luò)基礎(chǔ)的網(wǎng)絡(luò)課程足夠滿足我的需要了。當(dāng)然,這不會(huì)讓我成為專家 ,但這能讓我最小限度地得到一個(gè)可用的產(chǎn)品。
我開始相信蘋果公司必須在手機(jī)業(yè)務(wù)之外開發(fā)增強(qiáng)現(xiàn)實(shí)技術(shù)。當(dāng)他們推出 Magic-Leap-Equivalent產(chǎn)品時(shí),構(gòu)建增強(qiáng)現(xiàn)實(shí)會(huì)變得十分容易。ARKit已經(jīng)讓人印象深刻。
經(jīng)過這次練習(xí)后,我對(duì)深度學(xué)習(xí)的理解更加深入,特別是在計(jì)算機(jī)視覺方面,感覺就像魔法一樣。
能夠從諸如照片這樣簡單的東西中提取的結(jié)構(gòu)化數(shù)據(jù)的類型將是不可思議的。你買什么狗玩具,你還剩多少狗糧,你喜歡什么樣的狗糧,你什么時(shí)候帶狗去看獸醫(yī)。你將能夠從你的照片那樣簡單的事情中了解你與寵物(或你的寶寶,或你的伴侶)的關(guān)系的一切。
感謝閱讀,希望對(duì)你會(huì)有幫助。如果你有任何建議,不要猶豫,我很愿意讓我的的應(yīng)用程序變得更好。
在應(yīng)用商店下載這款應(yīng)用,讓我知道你的想法。 雷鋒網(wǎng)雷鋒網(wǎng)
另外, 非常感謝Cosmin Negruseri, Matt Slotkin, Qianyi Zhou 以及 Ajay Chainani ,感謝他們幫助我完成的應(yīng)用以及評(píng)閱這篇文章。感謝Andy Bons為這個(gè)應(yīng)用提供了最初的想法。
雷鋒字幕組正在招募中
掃描下方二維碼
備注“雷鋒字幕組+姓名”加入我們吧
雷峰網(wǎng)原創(chuàng)文章,未經(jīng)授權(quán)禁止轉(zhuǎn)載。詳情見轉(zhuǎn)載須知。