Core ML和Vision:iOS11中的機器學習教程

機器學習是很火的,許多人只是聽說過,但知之甚少。這篇iOS機器學習的教程將會介紹CoreML和Vison,這是iOS11中引入的的兩個全新的框架。
具體來說,將學習如何使用Places205-GoogLeNet模型將這些新API用于對圖像的場景

開始

下載啟動項目。他已經包含了顯示圖片的用戶界面,并且可是讓用戶從照片庫中選擇另一張圖片。所以你可以專注于實現應用程序的機器學習和視覺方面。
編譯并運行項目,你將看到一個城市的圖片和一個按鈕:

image.png

從相冊中選擇領一張圖片。這個啟動項目的Info.plist已經包含了Privacy – Photo Library Usage Description,因此將會提示你允許使用。
在圖片和按鈕之間還包含一個文本框,它用于顯示模型對圖片場景的分類。

iOS機器學習

機器學習是一種人工智能,其中計算機“學習”而不被明確編程。機器學習工具不用編碼算法,而是通過大量數據中查找模式,使計算器能夠開發和優化算法。

深度學習

自20世紀50年代以來,AI研究人員開發了許多機器學習方法。蘋果的核心ML框架支持神經網絡,樹組合,支持向量機,廣義線性模型,特征工程和流水線模型。然而,神經網絡已經產生了許多最壯觀的最近的成功,從2012年谷歌2012年使用YouTube視頻來訓練其人工智能來識別貓和人。只有五年后,Google正在贊助一個比賽,以確定5000種植物和動物。像Siri和Alexa這樣的應用程序也存在于神經網絡中。
一個神經網絡試圖用層次的節點來模擬人類腦部過程,并以不同的方式聯系在一起。每個附加層需要大量增加計算能力:Inception v3,一個對象識別模型,有48層和約2000萬個參數。但是計算基本上是矩陣乘法,哪些GPU處理非常有效。 GPU的成本下降使得人們能夠創建多層深層神經網絡,因此是深入學習的術語。

image.png

神經網絡需要大量的訓練數據,理想地代表了全方位的可能性。 用戶生成數據的爆炸也促成了機器學習的復興。
訓練模型意味著向神經網絡提供訓練數據,并使其計算用于組合輸入參數以產生輸出的公式。 培訓發生在離線狀態,通常在具有多個GPU的機器上。
要使用這個模型,你給它新的輸入,它計算輸出:這被稱為推論。 推論仍然需要大量的計算,來計算新輸入的輸出。 由于像Metal這樣的框架,現在可以在手持設備上進行這些計算。
如本教程末尾所示,深入學習遠非完美。 建立真正有代表性的培訓數據真的很困難,過分訓練模型太容易了,所以對古怪的特征給予太多的重視。

蘋果提供了什么?

蘋果在iOS5中引入了NSLinguisticTagger來分析自然語言。Metal出現在iOS8中,提供對設備GPU的低級訪問。
去年,蘋果公司將基本神經網絡子程序(BNNS)添加到其加速框架中,使開發人員可以構建神經網絡來進行推理(而不是訓練)。
而今年,蘋果給出了CoreML和Vision!

  • Core ML 使您更容易在您的應用程序中使用經過訓練的模型
  • Vision 讓您輕松訪問Apple的模型,以檢測臉部,面部地標,文字,矩形,條形碼和對象。

您還可以在Vision模型中包裝任何圖像分析Core ML模型,這在本教程中將會如何。 因為這兩個框架是基于Metal構建的,所以它們在設備上高效運行,因此您不需要將用戶的數據發送到服務器。

將CoreML模型集成到你的App中

本教程使用Places205-GoogLeNet模型,您可以從Apple的“機器學習頁面.”頁面下載。 向下滾動到Working with Models,并下載第一個。 當您在那里時,請注意其他三個模型,它們都會在圖像中檢測物體 - 樹木,動物,人物等。

如果您使用受支持的機器學習工具(如Caffe,Keras或scikit-learn)創建的訓練模型,將訓練模型轉換為CoreML可描述如何將其轉換為Core ML格式。

添加模型到項目中

下載完GoogLeNetPlaces.mlmodel后,拖到項目的Resources目錄中。

image.png

選中這個文件,并稍等一下。當Xcode生成模型類時,將會出現一個箭頭:

image.png

點擊箭頭就可以看到生成的類:

image.png

Xcode已經生成輸入輸出類,并且主要的類GoogLeNetPlaces有一個model屬性和兩個prediction方法。
GoogLeNetPlacesInput用一個CVPixelBuffer類型的sceneImage屬性。這是什么?不要害怕,不要哭泣,Vision框架將會將我們屬性的圖像格式裝換為正確的輸入類型。
Vision框架還將GoogLeNetPlacesOutput屬性轉換為自己的結果類型,并管理對預測方法的調用,所以在所有生成的代碼中,代碼將只使用model屬性。

在Vision模型中包裝Core ML模型

最后,你將需要寫些代碼!打開ViewController.swift,在import UIKit下面導入兩個框架:

import CoreML
import Vision

然后在IBActions擴展末尾添加如下擴展:

// MARK: - Methods
extension ViewController {

  func detectScene(image: CIImage) {
    answerLabel.text = "detecting scene..."
  
    // Load the ML model through its generated class
    guard let model = try? VNCoreMLModel(for: GoogLeNetPlaces().model) else {
      fatalError("can't load Places ML model")
    }
  }
}

代碼意思如下:
首先,您顯示一條消息,以便用戶知道某些事情正在發生。
GoogLeNetPlaces的指定的初始化程序會引發錯誤,因此在創建時必須使用try。
VNCoreMLModel只是一個用于Vision請求的Core ML模型的容器。
標準Vision工作流程是創建模型,創建一個或多個請求,然后創建并運行請求處理程序。 您剛剛創建了該模型,因此您的下一步是創建一個請求。

detectScene(image:):末尾添加下面代碼:

// Create a Vision request with completion handler
let request = VNCoreMLRequest(model: model) { [weak self] request, error in
  guard let results = request.results as? [VNClassificationObservation],
    let topResult = results.first else {
      fatalError("unexpected result type from VNCoreMLRequest")
  }

  // Update UI on main queue
  let article = (self?.vowels.contains(topResult.identifier.first!))! ? "an" : "a"
  DispatchQueue.main.async { [weak self] in
    self?.answerLabel.text = "\(Int(topResult.confidence * 100))% it's \(article) \(topResult.identifier)"
  }
}

VNCoreMLRequest是使用Core ML模型來完成工作的圖像分析請求。它的完成處理程序接收requesterror對象。
您檢查該request.results是一組VNClassificationObservation對象,這是當Core ML模型是分類器而不是預測器或圖像處理器時,Vision框架返回的。而GoogLeNetPlaces是一個分類器,因為它僅預測了一個特征:圖像的場景分類。
VNClassificationObservation有兩個屬性:identifier - 一個String類型 - 和confidence - 介于0和1之間的數字 - 這是分類正確的概率。當使用對象檢測模型時,您可能只會看到那些confidence大于某個閾值的對象,例如30%。
然后,取第一個結果將具有最高的置信度值,并將不定冠詞設置為“a”或“an”,具體取決于標識符的第一個字母。最后,您將返回主隊列更新標簽。你很快會看到分類工作發生在主隊列中,因為它可能很慢。
現在,到第三步:創建和運行請求處理程序。
detectScene(image:):末尾添加下面代碼:

// Run the Core ML GoogLeNetPlaces classifier on global dispatch queue
let handler = VNImageRequestHandler(ciImage: image)
DispatchQueue.global(qos: .userInteractive).async {
  do {
    try handler.perform([request])
  } catch {
    print(error)
  }
}

VNImageRequestHandler是標準的Vision框架請求處理程序; 它不是核心ML模型的具體。 你給它作為一個參數進入detectScene(image :)的圖像。 然后通過調用其perform方法運行處理程序,傳遞一個請求數組。 在這種情況下,您只有一個請求。
perform方法拋出一個錯誤,所以你把它包裝在一個try-catch。

使用模型來分類場景

現在只需要在兩個地方調用detectScene(image :)。
viewDidLoad()imagePickerController(_:didFinishPickingMediaWithInfo :)的末尾添加以下行:

guard let ciImage = CIImage(image: image) else {
  fatalError("couldn't convert UIImage to CIImage")
}

detectScene(image: ciImage)

編譯并運行。很快就可以看到分類:

image.png

嗯,是的,圖像中有摩天大樓。 還有火車。
點擊按鈕,并選擇照片庫中的第一個圖像:一些太陽斑點的葉子的特寫鏡頭:

image.png

引用:

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容