當前位置:
首頁 > 知識 > 我是這樣從零開始用深度學習做狗臉識別 iOS App 的

我是這樣從零開始用深度學習做狗臉識別 iOS App 的

本文為雷鋒字幕組編譯的技術博客,原標題 What I"ve learned building a deep learning Dog Face Recognition iOS app,作者為 Octavian Costache。

翻譯 | 汪寧 王飛 劉澤晟 整理 | 凡江

我做了一個狗臉識別的深度學習 iOS 應用,並想跟你分享這些心得。

我是一個初創公司的軟體工程師。曾經有段時間在谷歌工作,做谷歌財經圖表和Multiple inboxes,並主管谷歌地圖的業務。最近,我開了一家叫Spring的購物公司。同時,我也是一個創業者,在空餘時間裡我喜歡做一些副業。

幾個月前,我開始做一個用於狗狗拍照 app 的臉部過濾器(https://itunes.apple.com/gb/app/pupcam/id1356734305?mt=8)。當你將 app 對著你的狗時,這個 app 就會將這個過濾器作用在狗的臉上。有9200萬張照片被標記為 dogsofinstagram —— 你可能會發現有一些用戶不在其中 —— 創造人們想要的東西是額外的動力:

我需要

建立一個深度學習模型,提取狗的面部特徵。

在 iPhone 上實時視頻的頂部運行

使用 ARKit 顯示 3D 過濾器(二維的表示不是那麼酷)

從對深度學習一無所知到做出一個還不錯的 app(https://itunes.apple.com/gb/app/pupcam/id1356734305?mt=8)。我想要分享我在每一步中所學到的經驗。

我希望那些剛接觸深度學習的人會覺得這些方法很有用。


步驟 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(https://developer.apple.com/documentation/coreml)。在 iOS 上運行.mlmodel 可以通過教程代(http://suo.im/4NmTUj)碼完成。如此簡單的過程讓我被它征服了。

但是,即使是這個簡單的轉換步驟(從 .h5 到 .mlmodel)也不是沒有挑戰的。

蘋果將一個 .h5 模型轉換成一個 .mlmodel 模型的工具(稱為 coremltools),是一個半成品。 使用pip安裝的版本在box外無法運行,我必須使用 python2.5 在 conda 環境中從源代碼構建它,打補丁。嘿,至少它有用。

弄清楚如何在手機上預先處理輸入圖像,就像模型所期望的那樣,卻出人意料的不簡單。我在 StackOverflow 提問,或者搜索博客文章,可什麼都沒有。我最終通過給Matthijs Hollemans發送陌生郵件來找到了我的答案,讓我驚喜的是他的答案使我脫離困境!他甚至有一篇關於這個問題的博客文章(http://machinethink.net/blog/help-core-ml-gives-wrong-output/)。如果沒有他,我不會發現這篇文章。

事實證明,整個深度學習工具鏈仍在開發中。在深度學習領域,事物變化很快。

另一方面,我喜歡團體小而富有活力,互幫互助的感覺。如果你像我一樣,有點迷糊,不要猶豫,直接發郵件問。最差也不過是沒有人回答。最好的情況卻是有個好人幫了你。就像 Matthijs(http://machinethink.net/blog/googles-mobile-net-architecture-on-iphone/)。感謝!

我的模型在實體機上以每秒 19 幀的速度運行了,這就像一個神奇的劃時代事件。有了這個基礎,現在我可以致力於提高質量了。

步驟 4:讓模型運行得更加完美

這的確需要一些時間。我該怎麼做才能讓我的產品在深度學習模型外也表現良好?再多點數據?使用不同的頂層?使用不同的損失函數?層中使用不同的激活參數?太麻煩了!

循序漸進似乎是最好的。不斷測試,訓練,和前一次的運行情況進行比較,看看哪一個辦法起了作用。剛開始用少量的數據,慢慢地擴大數據集。少量的數據意味著較短的訓練時間。一旦利用大型數據集進行訓練。運行一次得等待24小時是很常見的,這並不是真正的快速迭代。

數據擴充是可能會出錯的代碼。開始的時候可以略過這一部分,運行的時候可以不運行這一部分代碼,然後一點點增加數據擴充部分的代碼。要保證代碼是穩定的。你的模型應該始會和你輸入的數據一樣好。準備好時間會被浪費掉,準備好學習最優做法需要時間。你必須要不斷往前走並且不斷往下做,不然你是不會從錯誤中學到任何東西的。往前走,要勇於犯錯。

這是我試著做這個項目的時所學到的:

這一點似乎顯而易見----使用TendorBoard對迭代開發能夠達到數量級的提高

從我的數據生成器中對圖像數據進行調試,這能幫助我找到影響我模型的圖像處理的Bug。就像我對鏡像照片時,雖然我並沒有交換左右眼。

和那些經常訓練模型、有經驗的人進行交談,這節省了我很多時間。一個羅馬尼亞的機器學習團隊和幾個慷慨的朋友證明這很重要(感謝Csomin Negruseri,Matt Slotkin,Qianyi Zhou以及Ajay Chainani)。讓別人來主動問你遇到什麼困難,這是不可能。

通常來說,不按照默認規則來做並不是一個好主意。比如,當我嘗試著用fisheries competition上發布的一個博客(http://suo.im/5p2whV)做頂層時-- 博客裡面的使用了 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 (https://developer.apple.com/documentation/arkit/arhittestresult)表明,通過圖片中的像素,它會返回給你像素的三維坐標,確實有用但是精度不夠好。結果中百分之七十是在正確的位置,百分之三十齣現在了錯誤的位置。這給我把過濾器應用在臉部識別上造成了困難。

備用計劃:構建二維的過濾器。 SpriteKit(https://developer.apple.com/documentation/spritekit),蘋果的二維遊戲引擎,使用起來十分簡單--這個引擎有一個內置的物理引擎。使用和學習起來很有意思(雖然表面上是這樣)。

第一代結合了 CoreMl 的 ARKit 技術讓我大開眼界。

在幾個星期之內,我就能夠在實時的照相機視頻流上運行我的深度學習模型了,抽取出臉部特徵點,利用Arkit展示出三維的內容,使用 SceneKit 展示出二維的內容,處理的精度相當不錯。

僅僅在兩年前,為了相似的技術(用於人臉),SnapChat不得不花一億五千萬美元(https://techcrunch.com/2015/09/15/snapchat-looksery/)買下一個公司。現在 iOS 免費提供人臉標誌檢測,並且不像我的 ARHitTestResult 的結果,它的精確度很高。這種技術迅速商品化真是太不可思議了

再過幾年,一旦 iPhone 背面有紅外點,你的環境的 3D 映射應該變得相當好。


總結

對於深度學習的應用,人工智慧的熱潮和什麼相關,iPhone 當前所擁有的性能,以及 ARkit,SpriteKit,Swift,我感覺自己對它們有了一個深刻的理解。

現在你還不能找到現成的深度學習模型,因為深度學習相關的一切都還不是很普遍,但是,在將來情況就會改善。

如果你跳過一些必要的步驟,以及一些必要的限制,對我來說就像技術在這篇博客的應用。

我不必深入神經網路的內部細節,也不必直接觸碰任何 TensorFlow 相關的東西。

高層次的 Keras 遠遠夠用了。一周的關於卷積神經網路基礎的網路課程足夠滿足我的需要了。當然,這不會讓我成為專家 ,但這能讓我最小限度地得到一個可用的產品。

我開始相信蘋果公司必須在手機業務之外開發增強現實技術。當他們推出 Magic-Leap-Equivalent 產品時,構建增強現實會變得十分容易。ARKit 已經讓人印象深刻。

經過這次練習後,我對深度學習的理解更加深入,特別是在計算機視覺方面,感覺就像魔法一樣。

能夠從諸如照片這樣簡單的東西中提取的結構化數據的類型將是不可思議的。你買什麼狗玩具,你還剩多少狗糧,你喜歡什麼樣的狗糧,你什麼時候帶狗去看獸醫。你將能夠從你的照片那樣簡單的事情中了解你與寵物(或你的寶寶,或你的伴侶)的關係的一切。

感謝閱讀,希望對你會有幫助。如果你有任何建議,不要猶豫(https://twitter.com/pupcamapp),我很願意讓我的的應用程序變得更好。

在應用商店下載這款應用(https://itunes.apple.com/gb/app/pupcam/id1356734305?mt=8),讓我知道你的想法。

另外, 非常感謝Cosmin Negruseri,Matt Slotkin,Qianyi Zhou以及Ajay Chainani,感謝他們幫助我完成的應用以及評閱這篇文章。感謝Andy Bons為這個應用提供了最初的想法。

https://medium.com/octavians-thoughts/what-ive-learned-building-a-deep-learning-dog-face-recognition-ios-app-afd1eb168ad2

雷鋒字幕組正在招募中


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 AI研習社 的精彩文章:

剛刷完李飛飛斯坦福CS231n,我反手就是滿屏原創代碼
如何用張量分解加速深層神經網路?

TAG:AI研習社 |