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