1. 程式人生 > 其它 >【實踐操作】在iPhone上建立你的第一個機器學習模型

【實踐操作】在iPhone上建立你的第一個機器學習模型

最近的蘋果iPhone X釋出會,你會看到iPhone X有一些很酷的功能,比如FaceID,Animoji和AR。我們需要弄明白建立這樣一個系統需要什麼。

當進一步研究時,得到的答案是蘋果的官方機器學習工具CoreML。它適用於iPhone、Macbook、Apple TV、Apple watch,以及每一個蘋果裝置。

另一個有趣的資訊是,蘋果公司在最新的iphon上設計了一個定製的GPU和一個帶有神經引擎(neural engine)深度加工的A11 Bionic(仿生)晶片,該晶片用於深度學習的優化。

“隨著計算引擎的核心的日益強大,iPhone將會開啟新的機器學習的途徑,CoreML在未來的日子裡的意義只會上升。”

在這篇文章的結尾,你將知道Apple CoreML是什麼,以及它為什麼會獲得動力。我們還將通過構建iPhone的垃圾資訊分類應用程式來研究CoreML的實現細節。

我們將客觀地看待這篇文章的利弊。

1.什麼是CoreML

蘋果公司今年在他們的年度開發者大會WWDC(https://developer.apple.com/wwdc/)(相當於谷歌I / O會議)上釋出了CoreML(https://developer.apple.com/documentation/coreml),並大肆宣傳。為了更好地理解CoreML的作用,我們必須瞭解一些它的相關背景。

CoreML的背景

這並不是蘋果第一次推出機器學習框架。去年,它還推出了一組同樣的庫:

  • 加速和基本的神經網路子程式(BNNS)-高效利用CPU進行卷積神經網路的預測;
  • Metal效能著色程式CNN(MPSCNN)-高效利用GPU進行卷積神經網路的預測。

不同的是,一個優化了CPU,而另一個優化了GPU。這樣做的原因是,在推理過程中,CPU有時可能比GPU快。而在訓練過程中,幾乎每次都是GPU更快。

多個框架在開發人員之間造成了很大的混亂,因為它們非常接近硬體(為了高效能),因此很難進行程式設計。

進入CoreML

CoreML為前兩個庫提供了另一個抽象化的層,並提供了一個簡單的介面,以達到同樣的效率水平。另一個好處是,在應用程式執行時,CoreML負責處理CPU和GPU本身之間的上下文轉接。

“也就是說,例如,你有一個記憶體繁重的任務,該任務涉及文字處理(自然語言處理),CoreML將自動在CPU上執行它,如果計算像影象分類這樣的繁重任務,它將使用GPU。如果應用程式中有兩個功能,它也會自動處理這些功能,這樣你就能在兩個世界中獲得最好的效果。”

CoreML提供了什麼?

CoreML還附帶了三個建立在其上的庫:

  • 視覺:提供高效能影象分析和計算機視覺技術的庫,用於識別人臉,檢測特徵,並對影象和視訊中的場景進行分類;
  • Foundation(NLP):顧名思義,它是一個提供自然語言處理功能的庫;
  • 遊戲工具包:一個用於遊戲開發的庫同樣也提供人工智慧提供,使用決策樹。

以上所有的庫,都很容易使用,並提供了一個簡單的介面來完成一系列任務。使用上述庫,CoreML的最終結構將如下所示:

注意,上面的設計為iOS應用程式提供了一個很好的模組結構。對於不同的任務對應不同的層,可以以多種方式使用它們(例如,在應用程式中使用帶有影象分類的NLP)。

可以在這裡閱讀更多關於這些庫的內容:

視覺(https://developer.apple.com/documentation/vision)Foundation(https://developer.apple.com/documentation/foundation) 遊戲工具包(https://developer.apple.com/documentation/gameplaykit)

2.設定系統

要充分利用CoreML,需要遵循以下設定要求:

  • 作業系統:MacOS(Sierra 10.12或以上);
  • Python 2.7和pip:從mac中下載Python(https://www.python.org/downloads/release/python-2714/)。要安裝pip,需要開啟終端並使用以下程式碼:
sudo easy_install pip
  • coremltools:該程式包有助於將模型從python轉換成CoreML能夠理解的格式。要安裝它,需要再次開啟終端:
sudo pip install-U coremltools
  • Xcode 9:這是蘋果裝置開發應用程式的預設軟體。可以從這裡下載(https://developer.apple.com/xcode/)。要下載Xcode,必須先使用Apple ID登入。

登入後,需要驗證Apple ID,你將收到與註冊Apple ID的裝置相同的通知。

選擇“Allow”並在網站上輸入給出的6位密碼。

完成此步驟後,將顯示一個下載選項,可以從那裡下載Xcode。現在我們已經建立了自己的系統,並準備好繼續執行實現部分。

3.案例研究:為iPhone實現垃圾資訊分類器

我們將利用CoreML的力量來構建兩種重要的方法。

開始:

將機器學習模型轉換成CoreML格式

CoreML的優勢之一是支援在其他流行的框架中建立訓練機器學習模型的轉換,比如sklearn,caffe,xgboost等。

“這並沒有使資料科學社群疏遠CoreML,因為他們可以在他們最喜歡的環境中進行實驗,訓練他們的模型,然後將其匯入到他們的iOS / MacOS應用程式中。”

下面是CoreML支援的框架:

mlmodel是什麼?

為了簡化轉換過程,蘋果設計了自己的開放格式,用於表示跨框架機器學習模型,並命名為mlmodel。這個模型檔案包含對模型各層的描述、輸入和輸出、類標籤以及需要對資料進行的任何預處理。它還包含所有的學習引數(權重和偏差)。

轉換流看起來是這樣的:

  • 在你喜歡的框架中進行培訓;
  • 使用coremltools python程式包將模型轉換為.mlmodel;
  • 在你的應用程式中使用這個模型。

在這個示例中,我們將在sklearn中構建一個垃圾資訊分類器,然後將相同的模型轉移到CoreML。

關於垃圾資訊集合資料集

SMS垃圾資訊集合v.1(http://www.dt.fee.unicamp.br/~tiago/smsspamcollection/)是一組公開的SMS標籤的資訊,已被用於手機垃圾資訊的研究。它有一個集合,由5574個英語,真實和非編碼資訊組成,被標記為合法(ham)或垃圾資訊。

可以從這裡下載資料集(http://simplysanad.com/CoreML-on-iPhone/Complete%20App/coreml%20test/SMSSpamCollection.txt)。

構建基本模型

我們將在sklearn中建立一個使用LinearSVC

(http://scikit-learn.org/stable/modules/generated/sklearn.svm.LinearSVC.html)的基本模型。另外,我在資訊文字中使用了 TF-IDF作為模型的一個特性。 TF-IDF是一種在自然語言處理中使用的技術,可以對基於唯一識別文件的文件進行分類。

這是它的程式碼:

import numpy as np
import pandas as pd

#Reading in and parsing data
raw_data= open('SMSSpamCollection.txt','r')
sms_data= []
for linein raw_data:
    split_line= line.split("t")
    sms_data.append(split_line)

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

#Build a LinearSVC model
from sklearn.feature_extraction.textimport TfidfVectorizer
from sklearn.svmimport LinearSVC

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

模型建立完成。用垃圾資訊對它進行測試。

#Test the model
print 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 - Validation
from sklearn.model_selectionimport cross_val_score
cross_score= cross_val_score(text_clf, vectorized_text, y, cv=10)
print cross_score
print "mean:",np.mean(cross_score)

我們已經構建了模型,需要將其轉換為 .mlmodel格式,以便與CoreML相容。我們將使用前面安裝的coremltools程式包(https://pypi.python.org/pypi/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")

發生了什麼?

首先匯入python中的coremltools程式包。然後使用轉換器轉換模型,在這種情況下,我們使用converters.sklearn,因為我們必須轉換在sklearn中建立的模型。然後,傳遞模型物件、輸入變數名和. convert()中的輸出變數名。接著,設定模型的引數,以新增更多關於輸入、輸出的資訊,最後呼叫. save()來儲存模型檔案。

當雙擊模型檔案時,它應該在Xcode視窗中開啟。

模型檔案顯示了模型的型別、輸入、輸出等的詳細資訊。上面的影象突出顯示了這些資訊。這些描述與我們在轉換為.mlmodel時提供的描述相匹配。

將模型匯入CoreML很容易。現在模型進入了蘋果系統,這才是真正的開始。

該步驟的完整的程式碼檔案:https://github.com/mohdsanadzakirizvi/CoreML-on-iPhone/blob/master/Complete%20App/CoreML%20Conversion.ipynb 更多關於coremltools的資訊:https://apple.github.io/coremltools/ 不同型別的轉換器:https://apple.github.io/coremltools/coremltools.converters.html

整合帶有應用程式的模型

現在已經訓練了我們的模型並將它轉移到CoreML,接下來我們將使用這個模型,為iPhone構建一個垃圾資訊分類器應用程式。

我們會在模擬器上執行我們的應用程式。模擬器是一個軟體,它展示了應用程式的外觀和工作方式,就好像它真的在手機上執行一樣。這節省了很多時間,因為我們可以用我們的程式碼進行實驗,並在實際手機上試驗應用程式之前,修復所有的bug。看看最終的產品會是什麼樣子:

下載專案

我已經為我們的應用建立了一個基本的UI,它可以在GitHub上使用。使用以下命令來啟動和執行:

git clone https://github.com/mohdsanadzakirizvi/CoreML-on-iPhone.git
cd CoreML-on-iPhone/Practice App/
open coreml test.xcodeproj/

使用Xcode開啟我們的專案。

Xcode視窗突出了三個主要區域:

  • 左上方的播放按鈕用於在模擬器上啟動應用程式。
  • 在播放按鈕下面是與該專案相關的檔案和資料夾。被稱為專案導航器,它在專案的檔案和資料夾之間進行導航。
  • 在播放按鈕上,iPhone 8 Plus被寫入,這表示你希望的測試模擬器的目標裝置。你可以點選它,下拉選擇iPhone 7

先執行我們的應用程式,看看會發生什麼。點選左上方的播放按鈕,在模擬器上執行我們的應用程式。試著在文字框裡輸入一些文字並點選“Predict”按鈕。會發生什麼呢?

目前,我們的應用程式並沒有做很多事情,只是輸出了在文字框裡鍵入的東西。

在應用程式中新增預先訓練的模型

  • 將.mlmodel檔案拖放到專案導航窗格中的Xcode視窗;
  • 當你這樣做的時候,視窗會彈出一些選項,選擇預設選項,然後點選“Finish”;
  • 當你將檔案拖放到Xcode中時,它會自動為專案中的檔案建立引用。通過這種方式,你可以輕鬆地在程式碼中訪問該檔案。

以下是整個過程:

編譯模型

從模型開始進行推斷之前,我們需要利用Xcode去建立階段編譯模型。步驟如下:

  • 在專案導航器面板中,選擇藍色圖示的檔案;
  • 開啟右側的專案設定。單擊編譯原始檔並選擇+ 圖示;
  • 在視窗中選擇mlmodel檔案並單擊Add。

每次執行應用程式時,Xcode都會編譯我們的機器學習模型,以便它進行預測。

在程式碼中使用模型

蘋果裝置的應用程式都是用swift(https://developer.apple.com/swift/)程式設計。在本教程中,不需要學習swift,但如果你對它感興趣,並且想深入學習,可以跟隨教程(https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/GuidedTour.html)。

  • 在專案導航器面板中選擇swift。該檔案包含了許多控制我們應用程式功能的程式碼;
  • 檢視第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 pathfor files
      let wordsFile= Bundle.main.path(forResource:"wordlist", ofType:"txt")
      let smsFile= Bundle.main.path(forResource:"SMSSpamCollection", ofType:"txt")
      do {
          //read wordsfile
          let wordsFileText= try String(contentsOfFile: wordsFile!, encoding: String.Encoding.utf8)
          var wordsData= wordsFileText.components(separatedBy: .newlines)
          wordsData.removeLast()// Trailing newline.
          //read spam collectionfile
          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 iin 0..<wordsData.count{
              let word= wordsData[i]
              if sms.contains(word){
                  var wordCount= 0
                  for substrin wordsInMessage{
                      if substr.elementsEqual(word){
                          wordCount+= 1
                      }
                  }
                  let tf= Double(wordCount)/ Double(wordsInMessage.count)
                  var docCount= 0
                  for smsin 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和返回相同的操作。一旦你儲存了程式並重新執行模擬器,應用程式就應該可以正常運行了。

4.CoreML的優點和缺點

就像所有發展中的庫一樣,它也有它的優點和缺點,讓我們明確地說明它們。

優點:

  • 對裝置效能進行優化,最大限度地減少記憶體佔用和功耗;
  • On-device指使用者資料的隱私,不再需要將資料傳送到伺服器進行預測;
  • On-Device指在沒有網路連線且對使用者的響應時間減少的情況下的功能預測;
  • 它決定是否在CPU或GPU上執行該模型(或兩者兼而有之);
  • 因為它可以使用CPU,你可以在iOS模擬器上執行它(iOS不支援GPU);
  • 它支援許多模型,因為它可以從其他流行的機器學習框架中匯入模型,如:

1.支援向量機(SVM);

2.tree ensembles,如隨機森林和提升數模型(boosted trees)

3.線性迴歸和邏輯迴歸;

4.神經網路:前饋,卷積,反覆。

缺點

  • 監督模型的本機支援,只支援無監督或增強學習;
  • 沒有對裝置進行訓練,只有推理(預測);
  • 如果CoreML不支援某一層的型別,就不能使用它。目前不允許用自己的層型別擴充套件核心ML;
  • 核心ML轉換工具只支援有限數量的訓練工具的特定版本(不包括tensorflow);
  • 不能檢視由中間層生成的輸出,只能得到預測;
  • 僅支援迴歸和分類(不支援叢集、排名、維度減少等)。

總結

在這篇文章中,我們學習了更多關於CoreML的知識,以及它在構建iPhone機器學習應用程式方面的應用。CoreML是一個相對較新的庫,因此有它自己的優點和缺點。其中一個非常有用的特性是它在本地裝置上執行,從而提供了更快的速度和更多的資料隱私。與此同時,它還不能被認為是一個成熟的資料科學家友好的庫。我們將拭目以待,看看它在即將釋出的版本中會如何發展。

本文的所有程式碼:https://github.com/mohdsanadzakirizvi/CoreML-on-iPhone

另外,如果你想更深入地探索CoreML,這些是一些資源:

  • CoreML文件(https://developer.apple.com/documentation/coreml);
  • WWDC 2017視訊會議-深度核心ML(https://www.youtube.com/watch?v=cyWYTwDtbyw&t=69s);

核心ML介紹:構建一個簡單的影象識別應用(https://www.appcoda.com/coreml-introduction/)。