天天看點

在iOS11中使用Core ML 和TensorFlow對手勢進行智能識别

在計算機科學中,手勢識别是通過數學算法來識别人類手勢的一個議題。使用者可以使用簡單的手勢來控制或與裝置互動,讓計算機了解人類的行為。

這篇文章将帶領你實作在你自己的應用中使用深度學習來識别複雜的手勢,比如心形、複選标記或移動裝置上的笑臉。我還将介紹和使用蘋果的Core ML架構(iOS11中的新架構)。

在iOS11中使用Core ML 和TensorFlow對手勢進行智能識别

在螢幕上随便劃動兩下,手機就會對複雜的手勢進行實時識别

這項技術使用機器學習來識别手勢。本文中的一些内容是特定于iOS系統的,但是Android開發者仍然可以找到一些有用的資訊。

我們将建構什麼?

在本教程結束時,我們将有一個設定,讓我們可以選擇完全自定義的手勢,并在iOS應用中非常準确地識别它們。

一個APP收集每個手勢的一些例子(畫一些複選标記或者心形,等等)。

一些Python腳本用于訓練機器學習算法(下面将會解釋),以識别手勢。我們将使用TensorFlow,稍後會講到。

這款APP可以使用自定義手勢。記錄使用者在螢幕上的動作,并使用機器學習算法來找出它們所代表的手勢。

在iOS11中使用Core ML 和TensorFlow對手勢進行智能識别

我們所畫的手勢将用于訓練機器學習算法,我們将用Core ML來評估應用内(in-app)的算法

什麼是機器學習算法?

機器學習算法從一組資料中學習,以便根據其他資料的不完整的資訊作出推斷。

在我們的例子中,資料是使用者及其相關的手勢類(“心形”、“複選标記”等)在螢幕上做出的劃動。我們想要推斷的是,在我們不知道手勢類(不完整的資訊)的情況下,使用者所畫出的東西是什麼。

允許一種算法從資料中學習,稱為“訓練”。對資料進行模組化的推理機器被恰當地稱為“模型”。

什麼是Core ML?

機器學習模型可能是複雜的,(尤其是在移動裝置上)評估是非常緩慢的。在iOS 11中,蘋果引入了Core ML,這是一種新的架構,使其快速并易于實作。對于Core ML,實作一個模型主要是為了在Core ML模型格式(.mlmodel)中儲存它。

在iOS11中使用Core ML 和TensorFlow對手勢進行智能識别

支援的格式可以通過使用coremltools自動轉換成Core ML模型。像TensorFlow這樣的不支援格式需要更多的手動操作來完成。

注意:Core ML隻支援在裝置上評估模型,而不是訓練新模型。

1.生成資料集

首先,讓我們確定我們的機器學習算法有一些資料(手勢)來學習。為了生成一個真實的資料集,我編寫了一個名為“GestureInput”的iOS應用,用于在裝置上輸入手勢。它允許你輸入大量的筆畫,然後預覽所生成的圖像,并将其添加到資料集中。你還可以修改相關的類(稱為标簽)并且删除示例。

當我想要改變它們顯示的頻率時(例如,當向現有的資料集添加一個新的類時),我将更改寫死的值并重新編譯。盡管看起來不是很漂亮,但很管用。

在iOS11中使用Core ML 和TensorFlow對手勢進行智能識别

為機器學習算法生成資料

項目的自述檔案解釋了如何修改手勢類的集合,包括複選标記、x标記、“塗鴉”(在上下移動時快速的側向運動)、圓形、U形、心形、加号、問号、大寫A、大寫B、笑臉和悲傷的表情。還包括一個樣本資料集,你可以将它傳輸到你的裝置上。

輸出訓練

GestureInput中的“Rasterize”按鈕将使用者畫的圖案轉換為圖像,并将其儲存到一個名為data.trainingset的檔案中。這些圖像就是我們要輸入的算法。

在iOS11中使用Core ML 和TensorFlow對手勢進行智能識别

将使用者畫出的圖案轉換成一個灰階圖像來輸入我們的機器學習算法

請注意,我仍然在另一個檔案中存儲每次筆畫的觸摸位置的原始時間序列。這樣,我就可以改變手勢在未來轉換成圖像的方式,甚至可以使用非基于圖像的方法來識别,而不用再畫出所有的手勢。手勢輸入在它的container文檔檔案夾中儲存資料集。從你的裝置上擷取資料的最簡單方法是通過Xcode下載下傳container。

2.訓練一個神經網絡

目前,最先進的圖像分類機器學習算法是卷積神經網絡(CNNs)。我們将用TensorFlow訓練一個CNNs,并在我們的APP中使用它。

我的神經網絡是基于“Deep MNIST for Experts”的TensorFlow教程所使用的。

我用來訓練和導出模型的一組腳本在一個叫做“gesturelearner”的檔案夾中。

我将讨論典型的用例,但是它們有一些額外的以virtualenv開頭的指令行選項可能是有用的:

準備資料集

首先,我使用filter.py将資料集分成15%的“測試集”和85%的“訓練集”。

訓練集當然是用來訓練神經網絡的。測試集的目的是為了說明神經網絡的學習是如何對新資料進行歸納的。

我選擇把15%的資料放在測試集中,如果你隻有幾百個手勢例子,那麼15%的數字将是一個相當小的數字。這意味着測試集的準确性隻會讓你對算法的表現有一個大緻的了解。

訓練

在把我的自定義.trainingset格式變為TensorFlow喜歡的TFRecords格式之後,我使用train.py來訓練一個模型。我們給神經網絡提供了有力的分類,它在未來會遇到新的手勢。

train.py列印出它的程序,然後定期儲存一個TensorFlow Checkpoint檔案,并在測試集上測試它的準确性(如果指定的話)。

訓練應該很快,在一分鐘内達到98%的準确率,在大約10分鐘後完成。

在iOS11中使用Core ML 和TensorFlow對手勢進行智能識别

訓練神經網絡

如果你在訓練中退出了train.py,你可以稍後重新啟動,它将加載checkpoint檔案以擷取它所處的位置,它還可以選擇從哪裡加載模型以及儲存它的位置。

用不平衡資料訓練

如果你的手勢比其他手勢有更多的例子,那麼網絡就會傾向于學會以犧牲其他手勢為代價來識别更好的手勢。有幾種不同的方法來應對這個問題:

神經網絡是通過最小化與制造錯誤相關的成本函數來訓練的。為了避免忽略某些類,你可以增加錯誤分類的成本。

包含一些較少代表性(less-represented)的手勢的副本,這樣你的所有手勢的數量都是相等的。

删除一些更有代表性(more-represented)的手勢的例子。

我的代碼并不是開箱即用的,但是它們應該相對容易實作。

輸出到Core ML

Core ML沒有一個用于将TensorFlow模型轉換為Core ML的ML模型的“轉換器”。這就給我們提供了兩種把我們的神經網絡轉換成一個ML模型的方法:

使用一個用于建構神經網絡的API的coremltools.模型包。

由于MLModel說明是基于Google的protocol buffers,是以你可以跳過coremltools,然後直接在任何程式設計語言中使用protobuf。Google的protocol buffers

到目前為止,除了在現有的轉換器的内部代碼之外,在web上似乎沒有找到任何方法的例子。下面是我使用coremltools的示例的精簡版:

使用它:

必須編寫這種轉換代碼的一個副作用是,我們将整個網絡描述為兩個位置(TensorFlow代碼位置和轉換代碼位置)。每當我們更改TensorFlow圖時,我們就必須同步轉換代碼以確定我們的模型正确地導出。

希望将來蘋果能開發出一種更好的輸出TensorFlow模型的方法。而在Android上,你可以使用官方的Tensorflow API。

此外,谷歌還将釋出一款名為TensorFlow Lite的移動優化版本的TensorFlow。

3.在應用内識别手勢

最後,讓我們把我們的模型放到一個面向使用者的APP中,這個項目的一部分是手勢識别(GestureRecognizer。

一旦你有了一個mlmodel檔案,就可以将它添加到Xcode中的一個目标。你将需要運作Xcode 9。

Xcode 9将編譯任何向目标添加的mlmodel檔案,并為它們生成Swift類。我将我的模型命名為GestureModel,是以Xcode生成了GestureModel, GestureModelInput和GestureModelOutput這三個類。

我們需要将使用者的手勢轉換成GestureModel接受的格式。這意味着要将這個手勢轉換成灰階圖像,就像我們在步驟1中所做的那樣。然後,Core ML要求我們将灰階值數組轉換為多元數組類型,MLMultiArray。

MLMultiArray就像一個圍繞一個原始數組的包裝器(wrapper),它告訴了Core ML它包含什麼類型以及它的形狀(例如次元)是什麼。有了一個MLMultiArray,我們可以評估我們的神經網絡。

我使用了一個GestureModel的共享執行個體,因為每個執行個體似乎都要花費很長的時間來配置設定。事實上,即使在建立執行個體之後,這個模型第一次評估的速度也很慢。當應用程式啟動時,我用一個空白圖像對網絡進行評估,這樣使用者在開始做手勢時不會看到延遲。

避免手勢沖突

由于我使用的一些手勢類彼此包含(笑臉與U形嘴相包含,x标記與上升的對角相包含),是以當使用者想要繪制更複雜的圖形時,可能會貿然地識别出更簡單的手勢。

為了減少沖突,我使用了兩個簡單的規則:

如果一個手勢能構成更複雜的手勢的一部分,那麼就可以暫時延遲它的識别,看看使用者是否能做出更大的手勢。

考慮到使用者的筆畫數,一個還未被完全畫出的手勢(例如,一張笑臉需要至少畫三筆:一張嘴巴和兩隻眼睛)是不能被識别的。

結語

就是這樣!有了這個設定,你可以在大約20分鐘内給你的iOS應用添加一個全新的手勢(輸入100張圖檔,訓練達到99.5+%的準确率,并且把模型導出)。

本文為編譯作品,轉載請注明出處。更多内容關注公衆号:atyun_com