天天看點

如何在iPhone上建立第一個機器學習模型

引言

作為一名資料科學家,我一直有一個夢想——頂級科技公司在與我相關的領域不斷推出新産品。

如果你觀看了Apple公司最新的iPhone X釋出會,你會發現iPhone X具有非常酷的特性,比如FaceID、動态表情、增強現實,這些特性都使用了機器學習。作為一名駭客,我決定親自上手探索一下如何建立那樣的系統。

進一步調查後我發現了一個很有趣的工具,那就是Apple官方面向開發者推出的機器學習架構工具CoreML。它可以在iPhone、Macbook、Apple TV、Apple watch等任何一個蘋果裝置上使用。

如何在iPhone上建立第一個機器學習模型

另一個有趣的發現是Apple在最新的iPhone手機上設計了一個定制GPU,以及一個帶有神經引擎的A11先進仿生學處理晶片,以便用于優化機器學習。

随着核心元件計算引擎功能日益強大,iPhone将開辟機器學習的新途徑,CoreML在未來的意義将越來越重要。

讀完這篇文章,大家将會了解Apple CoreML是什麼以及為何它勢頭正猛。我們也将通過開發一款iPhone上的垃圾短信分類app來與大家一起一探CoreML的實作細節。

同時,我們也會通過客觀評價CoreML的利弊來結束本篇文章。

如何在iPhone上建立第一個機器學習模型

文章目錄:

CoreML是什麼?

建立系統

案例學習:實作一個iPhone上的垃圾短信分類app

使用CoreML的利弊

01、CoreML是什麼?

如何在iPhone上建立第一個機器學習模型

今年,Apple公司在每年一次的全球開發者大會WWDC(類似于谷歌的I/O會議)上大肆宣傳CoreML。為了更好地了解CoreML的作用,我們需要了解一些背景。

CoreML的背景

有趣的是,這并不是Apple公司第一次釋出移動端機器學習架構。去年它就釋出了一些同樣的架構庫:

Accelerate 架構和基本神經網絡子程式(BNNS)——高效利用CPU并使用卷積神經網絡進行預測。

Metal Performance Shaders CNN(MPSCNN)——高效利用GPU并使用卷積神經網絡進行預測。

這兩個架構庫的差別在于,一個針對CPU優化而另一個針對GPU。這是因為有時在inference(推斷)過程中CPU比GPU計算更快,而在training(訓練)過程中幾乎每次都是GPU計算更快。

但為了提高性能,架構會非常接近底層硬體,使得這些混合架構對開發者造成混亂,進而很難程式設計。

走進CoreML

如何在iPhone上建立第一個機器學習模型

CoreML 會在之前提到的兩個庫上面提供一個抽象層,并且還會提供一個簡單的接口,以達到同樣的效率。另一個好處是,在我們的app運作時,CoreML充分照顧到了CPU與GPU之間的上下文切換。

換句話說,假如我們有一個耗記憶體的任務,它涉及文本處理(自然語言處理),CoreML将自動在CPU運作;而如果我們有一個計算繁重的任務,例如圖像識别,它将使用GPU;當app包含這兩種功能的時候,它又會自動切換進而使得兩者都得到最大化的利用。

如何在iPhone上建立第一個機器學習模型

CoreML還将提供什麼?

CoreML頂層還附帶了三個庫:

Vision:這個庫提供了高性能圖像分析與計算機視覺技術,用于人臉識别、特征檢測以及圖像與視訊中的場景識别。

Foundation(NLP):顧名思義,它提供了自然語言處理的一些功能

Gameplay Kit:用于遊戲開發的庫,此外它還提供了AI,并運用決策樹。

以上提到的所有庫都可以用一些簡單的接口輕松使用,可用于完成一系列任務。通過上述的庫,CoreML最終架構圖如下:

如何在iPhone上建立第一個機器學習模型

注意,上述設計給iOS應用程式提供了一個很好的子產品化結構。你可以使用不同層進行不同的任務,也可以用多種方式使用它們(例如,在app中使用NLP進行圖像分類)。了解更多:Vision、Foundation與GameplayKit。好了,現在我們有了足夠的理論知識,是時候實踐一下了!

“微信排版限制,需要代碼的同學請看文末的原文連結自行查找”

02、建立系統

為了充分使用CoreML,你需要遵循如下要求:

1.OS:MacOS(Sierra 10.12或以上)

2.Python 2.7和pip:點選下載下傳mac上的python。打開終端,輸入如下代碼安裝pip:

sudo easy_install pip 

3.coremltools:這個包有助于将你的模型從python轉換成CoreML能了解的格式。在終端輸入如下代碼進行安裝:

sudo pip install -U coremltools 

4.Xcode 9:這是用于建構Apple裝置上應用程式的預設軟體。點此下載下傳。下載下傳Xcode之前,你需要使用Apple ID進行登陸。

如何在iPhone上建立第一個機器學習模型

登陸之後,你需要驗證你的apple ID。你将會收到與注冊Apple ID的裝置相同的通知。

如何在iPhone上建立第一個機器學習模型

點選“允許”并輸入網站顯示的6位密碼。

如何在iPhone上建立第一個機器學習模型

當你完成這一步,你将會看到一個下載下傳選項。你可以在那兒下載下傳Xcode。現在,我們建立好了系統,準備好了的話就讓我們進入實作部分!

03、案例學習:實作一個iPhone上的垃圾短信分類app

在本次開發中,我們将着重于在兩個重要途徑上來使用CoreML的能力。讓我們開始吧!

将你的機器學習模型轉換成CoreML格式

CoreML其中一個優勢,或者我應該說它的創造者作出的明智的決定是,支援在sklearn、caffe、xgboost等其他流行架構中訓練好的機器學習模型的轉換。

資料科學社群并不會不嘗試CoreML試行,因為他們可以在他們最喜歡的環境中進行實驗、訓練他們的模型,然後輕松導入并在iOS/MacOS的app上使用。

下面是即時可用的CoreML支援的架構:

如何在iPhone上建立第一個機器學習模型

Mlmodel是什麼?

為了使轉換過程簡單,Apple設計了它自己的開放格式來代表跨架構機器學習模型,即mlmodel。這個模型檔案包含了模型各層的描述、輸入、輸出、類标簽、任何需要對資料進行的預處理。它還包含了已學習的參數(權重及偏差)。

轉換流程如下:

在你最喜歡的架構中訓練模型

使用python子產品coremltools将模型轉換為.mlmodel格式

在app中使用模型

如何在iPhone上建立第一個機器學習模型

在本次例子中,我們将在sklearn中訓練一個垃圾短信分類器,然後将該模型轉給CoreML。

關于垃圾短信資料集

SMS垃圾短信資料集 v.1是一個公開的SMS标注短信資料集,用于手機垃圾短信研究。它包含了5574份真實無編碼的英文短信,這些短信都标注了合法(做作)或者垃圾短信。

如何在iPhone上建立第一個機器學習模型

你可以在此下載下傳該資料集。

建立基礎模型

我們使用sklearn中的LinearSVC建立基礎模型。同時,我們提取短信文本的TF-IDF值作為模型特征。TF-IDF是自然語言進行中的一種方法,它基于唯一辨別文檔的詞來分類文檔。如果你想要學習更多NLP和tf-idf的知識,你可以閱讀這篇文章。代碼如下:

import numpy as npimport pandas as pd#Reading in and parsing dataraw_data = open('SMSSpamCollection.txt', 'r')sms_data = []for line in raw_data: split_line = line.split("\t") sms_data.append(split_line) 

#Splitting data into messages and labels and training and testsms_data = np.array(sms_data)X = sms_data[:, 1]y = sms_data[:, 0]  

#Build a LinearSVC modelfrom sklearn.feature_extraction.text import TfidfVectorizerfrom sklearn.svm import LinearSVC  

#Build tf-idf vector representation of datavectorizer = TfidfVectorizer()vectorized_text = vectorizer.fit_transform(X)text_clf = LinearSVC()text_clf = text_clf.fit(vectorized_text, y) 

我們的模型建立好了,讓我們用一份垃圾短信測試一下:

#Test the modelprint text_clf.predict(vectorizer.transform(["""XXXMobileMovieClub: To use your credit, click the WAP link in the next txt message or click here>> http://wap. xxxmobilemovieclub.com?n=QJKGIGHJJGCBL"""])) 

有趣,我們的模型效果很好!讓我們添加交叉驗證:

#Cross - Validationfrom sklearn.model_selection import cross_val_scorecross_score = cross_val_score(text_clf, vectorized_text, y, cv=10)print cross_scoreprint "mean:",np.mean(cross_score) 

現在已建好模型,為使它适用于CoreML,我們需要把它轉換成.mlmodel格式。用之前安裝的coremltools工具包來實作。以下代碼能将我們的模型轉換成.mlmodel格式。  

import coremltools  

#convert to coreml model  

coreml_model = coremltools.converters.sklearn.convert(text_clf, "message", "spam_or_not")  

#set parameters of the model 

coreml_model.short_description = "Classify whether message is spam or not"  

coreml_model.input_description["message"] = "TFIDF of message to be classified"  

coreml_model.output_description["spam_or_not"] = "Whether message is spam or not"  

#save the model  

coreml_model.save("SpamMessageClassifier.mlmodel") 

這是如何運作的呢?

首先我們運用coremltools Python工具包。再選擇一個轉換器對模型進行轉換,本例中用converters.sklearn,因為要轉換的模型是用sklearn工具建立的。然後在.convert()括号内聲明模型對象、輸入變量名稱、輸出變量名稱。接下來設定模型參數來添加更多關于輸入、輸出的資訊,最後用.save()儲存已轉換成CoreML格式的模型檔案。

如何在iPhone上建立第一個機器學習模型

輕按兩下模型檔案,會用Xcode打開。

如何在iPhone上建立第一個機器學習模型

如你所見,該模型檔案顯示了很多資訊,關于模型的類型、它的輸入、輸出,輸入輸出的類型等。我已在上圖中用紅色标記。你可以将這些描述和轉換成.mlmodel時所提供的一一對比。

将自己的模型引入CoreML就是這麼簡單。現在你的模型已經在蘋果生态系統裡了,接下來真正好玩的開始啦!

注意:這一步的完整代碼檔案請看這裡。進一步了解coremltools請看這裡,提供的不同種類的轉換器請看這裡。

将該模型用于我們的app

既然已經訓練好模型并引入CoreML中,讓我們用該模型開發一個iPhone垃圾資訊分類app吧!

我們将在模拟器上運作app。模拟器這一軟體能顯示app的界面及運作情況,像在iPhone上真正運作那樣。這樣節省了大量時間,因為用iPhone運作app之前,我們就可以測試代碼、調試。看一下最終産品長什麼樣子吧:

如何在iPhone上建立第一個機器學習模型

下載下傳工程

我已經為我們的app制作了一個簡單基礎的UI放在GitHub上。用以下指令加載并運作:

git clone https://github.com/mohdsanadzakirizvi/CoreML-on-iPhone.git  

cd CoreML-on-iPhone/Practice\ App/  

open coreml\ test.xcodeproj/ 

這會在Xcode打開我們的項目。

如何在iPhone上建立第一個機器學習模型

在Xcode視窗中我用紅色标示了三個重要區域:

左上角的播放按鈕用來啟動app在模拟器運作。

播放按鈕的正下方列出了與我們項目相關的檔案和檔案夾。這是項目導航欄,友善你找項目裡的檔案和檔案夾。

播放按鈕旁邊寫着iPhone 8,表示你想用模拟器仿真的目标裝置。你可以點選它,在下拉清單裡選擇iPhone 7。

讓我們開始運作app吧,看看會發生什麼。點選左上角的播放按鈕讓模拟器運作app。在框中随便鍵入些文字,點選預測按鈕。發生了什麼?

如何在iPhone上建立第一個機器學習模型

到現在,我們的app什麼也沒做,隻是原樣輸出框中鍵入的文字。

向你的app中添加一個訓練好的模型

相當簡單:

将你的.mlmodel模型檔案拖入到Xcode視窗工程導航欄中。

做好後,會彈出一個含有幾項選擇的視窗,預設預設,點選“結束”。

當你像這樣拖拽檔案到Xcode時,自動在工程中生成該檔案的參考路徑。這樣你能輕松地在代碼中擷取該檔案。

如何在iPhone上建立第一個機器學習模型

編譯模型

在能夠用我們的模型進行推測之前,需要讓Xcode在建立階段中編譯模型。以下是具體步驟:

在工程導航欄中選擇有藍色辨別的檔案

如何在iPhone上建立第一個機器學習模型

會在右手邊打開工程設定。點選Compile Sources(編譯源)并選擇+辨別。

在新出現的視窗中選擇 SpamMessageClassifier.mlmodel檔案,點選新增。

如何在iPhone上建立第一個機器學習模型

現在每次運作app,Xcode就會編譯我們的機器學習模型,使它能用來做預測。

在代碼中建立模型

任何為蘋果裝置開發的app都用swift程式設計。你不需要學swift但如果以後你有興趣深入,你可以跟着這個教程學。

在工程導航欄中選擇 ViewController.swift。這一檔案包含大部分控制app功能的代碼。

如何在iPhone上建立第一個機器學習模型

第24行的 predictSpam() 函數會做最多的工作。删除第25行,向函數中添加以下代碼:

let enteredMessage = messageTextField.text!  

if (enteredMessage != ""){  

spamLabel.text = ""  

}  

//Fetch tfidf representation of text  

let vec = tfidf(sms: enteredMessage)  

do {  

//Get prediction on the text  

let prediction = try SpamMessageClassifier().prediction(message: vec).spam_or_not  

print (prediction)  

if (prediction == "spam"){  

spamLabel.text = "SPAM!" 

 }  

else if(prediction == "ham"){  

spamLabel.text = "NOT SPAM"  

catch{  

spamLabel.text = "No Prediction"  

以上代碼檢查使用者是否向框内輸入了任何資訊。如果有,調用tfidf()函數計算文本的tfidf值。然後生成一個SpamMessageClassifier 對象執行個體,再調用.prediction() 函數。這與sklearn中的 .predict() 函數相同。然後基于預測展示恰當的資訊。

但為什麼需要tfidf()?

記住我們基于文本的tf-idf表征來訓練模型,是以我們的模型需要相同形式的輸入。一旦獲得鍵入的文本框的資訊,就調入tfidf()函數來做同樣的事。來寫這一步的代碼吧,複制下列代碼放在predictSpam()函數後:

//MARK: Functionality code  

func tfidf(sms: String) -> MLMultiArray{  

//get path for files  

let wordsFile = Bundle.main.path(forResource: "wordlist", ofType: "txt")  

let smsFile = Bundle.main.path(forResource: "SMSSpamCollection", ofType: "txt")  

//read words file  

let wordsFileText = try String(contentsOfFile: wordsFile!, encoding: String.Encoding.utf8)  

var wordsData = wordsFileText.components(separatedBy: .newlines)  

wordsData.removeLast() // Trailing newline.  

//read spam collection file  

let smsFileText = try String(contentsOfFile: smsFile!, encoding: String.Encoding.utf8)  

var smsData = smsFileText.components(separatedBy: .newlines)  

smsData.removeLast() // Trailing newline.  

let wordsInMessage = sms.split(separator: " ") 

 //create a multi-dimensional array  

let vectorized = try MLMultiArray(shape: [NSNumber(integerLiteral: wordsData.count)], dataType: MLMultiArrayDataType.double)  

for i in 0..  

let word = wordsData[i]  

if sms.contains(word){  

var wordCount = 0  

for substr in wordsInMessage{  

if substr.elementsEqual(word{  

wordCount += 1  

 let tf = Double(wordCount) / Double(wordsInMessage.count)  

var docCount = 0  

for sms in smsData{  

if sms.contains(word) {  

docCount += 1  

let idf = log(Double(smsData.count) / Double(docCount))  

vectorized[i] = NSNumber(value: tf * idf) 

 } else {  

vectorized[i] = 0.0  

return vectorized  

} catch {  

return MLMultiArray()  

以上代碼得到文本框内輸入資訊的tfidf表征,為此讀取SMSSpamCollection.txt原始資料庫并傳回同樣資訊。一旦你儲存項目然後再次運作模拟器,你的app就會運作良好。

4、CoreML優缺點

像每個發展中的庫一樣,CoreML有優點也有缺點。讓我們說清楚。

優點:

對在移動裝置上運作性能進行優化,最小化記憶體和能量消耗。

在移動裝置上運作保證了使用者隐私,不再需要将資料發給伺服器做預測。

在移動裝置上運作意味着甚至在沒聯網的時候都可以做預測,此外對使用者來說反應時間更短。

能自己決定在CPU還是GPU上運作(或者都有)。

因為它可以用CPU,是以你能在iOS模拟器上運作它(iOS模拟器不支援GPU)。

提供了很多模型,因為它能從其他主流機器學習架構中引入模型:

支援向量機(SVM)

樹內建,如随機森林、提升樹

線性回歸和邏輯回歸

神經網絡:前向回報、卷積、循環

如何在iPhone上建立第一個機器學習模型

缺點:

隻支援有監督模型,不支援無監督模型和強化學習。

不支援模型在裝置上再訓練,隻能做預測。

如果CoreML不支援某種層,你就不可以使用。目前還不能用自己的層擴充CoreML。

CoreML工具隻支援少量訓練工具的特定版本(竟然不支援tensorflow)。

不能看中間層的輸出,隻能得到預測結果。

隻支援回歸和分類(不支援聚類、排序、降維等)。

結語

本文中,我們學習了CoreML及應用它開發iPhone機器學習app。CoreML是一個較新的庫,是以有自己的優點和缺點。有一個非常有用的優點是它在本地裝置上運作,是以速度更快,保證資料隐私。但同時,它功能不全面,對資料科學家的需求考慮還不夠周全。期待後續版本會改進。

如果你在某個步驟遇到困難,本文所有代碼都在GitHub上。     

原文釋出時間為:2017-10-13

本文作者:Happen,Chloe,笪潔瓊,魏子敏編譯

本文來自雲栖社群合作夥伴“51CTO”,了解相關資訊可以關注。