Categories
程式開發

如何基於蘋果推出的CoreML 3.0從零開發一個圖像分類應用?


蘋果新推出的Core ML 3是讓開發者和程序員切入AI生態系統的一條理想的快車道,你可以使用Core ML 3為iPhone構建機器學習和深度學習模型,本文將詳細介紹如何基於Core ML 3為iPhone創建一個圖像分類應用程序。

簡介

想像一下,不用深度了解機器學習,就可以使用最先進的機器學習模型打造驚豔的應用程序。歡迎來到蘋果的Core ML 3的世界!

你是一名狂熱的蘋果迷嗎?你使用iPhone嗎?你是否想過蘋果是如何使用機器學習和深度學習來打造其應用程序和軟件的?

如果你對以上任何一個問題的回答是肯定的話——你將會進入到一場盛宴之中!因為在本文中,我們將使用深度學習和蘋果的Core ML 3為iPhone打造一款應用程序。我們先來大致看下這個應用的樣子:

如何基於蘋果推出的CoreML 3.0從零開發一個圖像分類應用? 1

軟件開發者、程序員,甚至是數據科學家都喜愛蘋果的AI生態系統。他們近年來創造了一些超級棒的開發程序,包括Core ML和我個人最愛的Swift編程語言。

Core ML 3框架支持了iPhone的一些很酷的功能,如FaceID、Animoji和增強現實。自從2017年蘋果首次推出Core ML以來已經過了很長時間了,現在它支持大量的工具,這些工具能幫助我們快速開發出非常棒的基於機器學習的應用程序。

本文中,我們將探索助力蘋果應用程序的整個AI生態系統,並學習使用Core ML 3豐富的生態系統,包括前沿的深度學習預訓練模型。

注意:本文需要讀者俱備一些Core ML的基礎知識,才能夠理解其中介紹的概念。我建議讀者先閱讀這篇文章來加速對本文的理解。

目錄

  • 蘋果的AI生態系統
  • 進入Core ML 3的世界
  • Core ML 3有哪些更新
  • 使用ResNet50模型為iPhone構建一個圖像分類應用
  • 我們對Core ML的看法

蘋果的AI生態系統

蘋果在利用機器學習來構建工具和框架方面做得相當出色。構建AI應用程序有大量的工具和框架可選,每一種都有其優缺點。下面我們將在較高層面上瀏覽一下蘋果的AI生態系統:

如何基於蘋果推出的CoreML 3.0從零開發一個圖像分類應用? 2

讓我們對每種工具或者框架都來了解一下:

1)Turi Create

如果你想給你的應用程序增加推薦、物體檢測、圖像分類、圖像相似度檢測或者行為分類的功能,那這就是你想要的框架。

你不用成為機器學習專家之後再使用這個工具。為什麼?因為它已經為每項任務都提供了模型。

我喜歡Turi Create是因為我們可以通過Python使用它,就像我們通常使用的工作流那樣。當我們得到了滿意的網絡模型後,就可以把它導入到Core ML,供其在iOS、macOS、watchOS和tvOS應用程序中使用啦!

以下是Turi Create中已經支持的一些任務,可以馬上在您的應用程序中使用的:

如何基於蘋果推出的CoreML 3.0從零開發一個圖像分類應用? 3

2)Create ML

Create ML能夠讓我們不用寫太多代碼就可以構建機器學習模型。

我喜愛這個工具的地方是,你能夠把訓練數據用拖拽的方式放置到它的界面上,然後選擇你想要訓練的模型(如語音識別、物體檢測等等),它就會自動開始訓練模型啦!

以下是訓練狗和貓分類模型的一個例子:

如何基於蘋果推出的CoreML 3.0從零開發一個圖像分類應用? 4

注意我只寫了兩行代碼,然後把存放訓練數據的文件夾拖拽到了界面上——其他的就可以交由CreateML來做啦!

因為Turi Create使用的是Python語言,所以我們可以使用CreateML在Mac上構建模型。喔,是的,它還支持在GPU上訓練(耶!)。

3)Swift for Tensorflow

Swift for Tensorflow擁有靈活而高性能的,類似Tensorflow/PyTorch風格的API,可以用來構建複雜的神經網絡架構。

這個框架最美妙的事情莫過於其代碼和Python代碼一樣具有良好的可讀性。以下是分別用Swift和Python寫的同一個模型的代碼(注意它倆的相似性):

如何基於蘋果推出的CoreML 3.0從零開發一個圖像分類應用? 5

如果你需要模型的高性能,想要高效部署模型時,就可以使用Swift for Tensorflow。你可以通過這個鏈接了解怎樣使用Swift for Tensorflow來構建深度學習模型。

4)語言和視覺框架(Language and Vision Frameworks)

這些是蘋果自己的框架,對應於Python的spaCy和OpenCV框架,但蘋果自己添加了一些額外功能。這些框架可以讓我們創建端到端的流程,用於圖像處理和文字處理等。

如果你想執行圖像分析任務,比如人臉或者地標檢測、文字檢測、條形碼識別、圖像註冊和通用特徵追踪功能,那麼Vision就正好適合你

如何基於蘋果推出的CoreML 3.0從零開發一個圖像分類應用? 6

類似的,如果你想執行諸如語言和腳本識別、打上標記、詞形還原、詞性標記和命名實體識別等功能,那麼Language就正好適用於這些場景。

如何基於蘋果推出的CoreML 3.0從零開發一個圖像分類應用? 7

除了這兩個以外,蘋果還支持用於語音數據的框架(它們可以和CoreML很好地結合)。我在後續文章中會介紹到這些工具。現在,先讓我們看看令人嘆為觀止的Core ML 3!

進入Core ML 3的世界

我喜愛蘋果的Core ML 3框架,因為它不僅支持上文提到的這些工具,而且它自己還具有一些額外的功能。

首先,CoreML3允許我們導入通過所有主流Python框架訓練好的機器學習或者深度學習模型。

如何基於蘋果推出的CoreML 3.0從零開發一個圖像分類應用? 8

我們之前的文章(上面的那個鏈接)已經介紹了Core ML 3的這個功能。這裡,我們會介紹Core ML 3的另一個有趣的功能——我們怎樣利用CoreML3現在支持的大量前沿的預訓練模型。

下面是Core ML 3支持的模型列表。注意其中一些模型(例如Squeezenet、DeeplabV3和YOLOv3)是非常新的,它們幾個月前才被提出來:

如何基於蘋果推出的CoreML 3.0從零開發一個圖像分類應用? 9

所有這些模型實際上都經過了優化,以在手機、平板和計算機上提供最優性能。這就是蘋果公司最偉大的地方。

這就意味著,即使這些模型中很多都是複雜的深度學習模型,我們也不用擔心其在我們的應用程序中部署和使用時的性能——這是多麼炫酷?

Core ML 3——有什麼更新?

你觀看了今年的WWDC大會嗎?會議上有一些關於Core ML 3的有趣聲明,以及蘋果設備將為這個框架提供的支持。如果你錯過了這場大會,以下是其快速摘要:

1)設備端上的訓練

這是目前為止Core ML 3最棒的地方。之前,我們只有“設備端上推理”功能的支持,這基本上意味著我們可以在其他某台機器上訓練模型,然後再在設備上使用這個訓練好的模型進行實時預測,這提供了更好的用戶體驗,因為我們不需要藉助因特網就可以做出預測了。

Core ML 3現在也支持設備端上的訓練了!你可以使用iPhone的CPU、GPU和神經引擎來訓練你的機器學習和深度學習模型。

你可以把Core ML 3當做是遷移學習或者在線學習,這個過程中,你只需要微調一個已有的模型即可。

以Face ID應用為例。它需要讓模型保持最新,因為用戶的臉可能隨著時間流逝而發生變化(臉上長出了鬍鬚、化了不同的妝、臉變老了等等)。基本的想法是在一開始生成一個基礎模型,這個模型對每一個人都具有相同的平均性能,然後會將其複制一份,這份拷貝就會針對每個用戶進行定制化。

隨著時間推移,每個用戶獨有的這個模型會變得更加出色,更加契合該用戶:

如何基於蘋果推出的CoreML 3.0從零開發一個圖像分類應用? 10

這個方法具有幾個好處:

  1. 訓練只會在用戶的個人設備上進行,這意味著能很好地保護用戶的數據隱私
  2. 我們不需要為數百萬用戶搭建大量的服務器來做模型訓練
  3. 由於不需要因特網,這個模型隨時都可以用來做預測!

2)Core ML 3中增加了新的神經網絡層類型

如何基於蘋果推出的CoreML 3.0從零開發一個圖像分類應用? 11

除了為不同模型類別提供的網絡層,Core ML 3還為一些中間操作提供了100+的網絡層,比如Masking、Tensor Manipulation、Boolean logic、Control Flow等等。

其中一些層類型是在經典的神經網絡架構中使用的,而Core ML 3已經提供給我們了。

這就意味著我們能夠馬上為我們的應用程序構建這樣的模型了。

如果你對整個組件感興趣,請觀看WWDC完整視頻。出於本文構建應用程序的目的,我們介紹了Core ML 3的核心基礎知識。現在是時候構建一個iPhone的應用程序啦!

構建一個iPhone圖像分類應用程序

在我們開始構建應用程序前,需要先安裝一些東西:

系統搭建:

  1. macOS:我使用的是macOS Catalina(10.15.1)
  2. Xcode:這是在蘋果設備上構建應用程序的默認軟件。你可以從蘋果商店裡把它下載到你的Mac上。我使用的是11.2的版本。
  3. 項目代碼:你可以在命令行下敲入以下命令,從GitHub上拉取該項目的代碼:
git clone https://github.com/mohdsanadzakirizvi/CoreML3-Resnet50.git

注意:

  1. 對於本文介紹的應用程序,你需要一台macOS機器,不然就實現不了這個項目
  2. 為蘋果設備編寫的任何應用程序都是使用的Swift語言(https://developer.apple.com/swift/
  3. 該教程不需要你學習Swift。但是如果你對該語言感興趣,可以點這個鏈接學習。

構建我們的深度學習模型

一旦你下載了該項目,你會看到兩個文件夾:

如何基於蘋果推出的CoreML 3.0從零開發一個圖像分類應用? 12

該項目的Complete Version是應用程序的全功能版本,你可以通過導入ResNet50模型來運行它。而練習版本則缺少一些代碼,你可以使用這個版本代碼來學習本文。

運行如下命令以在Xcode中打開該項目:

open ImageClassifier.xcodeproj

如何基於蘋果推出的CoreML 3.0從零開發一個圖像分類應用? 13

我在Xcode窗口中圈出了三處主要區域:

  1. 在左上角顯示的play按鈕是用來在模擬器中啟動你的應用程序
  2. 看一下play按鈕下方,你會看到該項目的文件和文件夾。這個小面板稱為項目導航器。它幫助我們在項目的不同文件和文件夾之間跳轉。
  3. 在play按鈕旁邊寫著“iPhone 11 Pro Max”。這個區域表示你想在模擬器上測試的目標設備型號。

讓我們先運行下這個應用程序看看會發生什麼。點擊左上角的play按鈕,這會啟動模擬器。

你看到了什麼?

如何基於蘋果推出的CoreML 3.0從零開發一個圖像分類應用? 14

到目前為止,我們的應用程序沒有做什麼事情。它只是顯示一張圖片,和一個按鈕用於選擇其他圖片——讓我們做得更酷炫一些吧!

如果你打開練習版本,你會發現以下的文件夾結構:

如何基於蘋果推出的CoreML 3.0從零開發一個圖像分類應用? 15

在項目導航器面板,選擇ViewController.swift文件。這個文件包含了大部分控制我們應用程序功能的代碼。你會看到以下代碼:

import CoreML
import Vision
import UIKit

class ViewController: UIViewController {

  // MARK: - IBOutlets
  @IBOutlet weak var scene: UIImageView!
  @IBOutlet weak var answerLabel: UILabel!

  // MARK: - View Life Cycle
  override func viewDidLoad() {
    super.viewDidLoad()

    guard let image = UIImage(named: "scenery") else {
      fatalError("no starting image")
    }

    scene.image = image
  }
}

// MARK: - IBActions
extension ViewController {

  @IBAction func pickImage(_ sender: Any) {
    let pickerController = UIImagePickerController()
    pickerController.delegate = self
    pickerController.sourceType = .savedPhotosAlbum
    present(pickerController, animated: true)
  }
}

// MARK: - UIImagePickerControllerDelegate
extension ViewController: UIImagePickerControllerDelegate {

  func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: (String : Any)) {
    dismiss(animated: true)

    guard let image = info(UIImagePickerControllerOriginalImage) as? UIImage else {
      fatalError("couldn't load image from Photos")
    }

    scene.image = image
  }
}

// MARK: - UINavigationControllerDelegate
extension ViewController: UINavigationControllerDelegate {
}

現在由於你已經熟悉了Xcode和項目代碼文件,讓我們進入下一階段。

向應用程序中添加一個預訓練模型

到Core ML 3官網網頁上直接下載預訓練模型:

https://developer.apple.com/machine-learning/models/

在該網頁的image部分,你將找到ResNet50模型:

如何基於蘋果推出的CoreML 3.0從零開發一個圖像分類應用? 16

你可以下載需要的模型版本。模型大小越大,模型就會越精確。類似的,模型大小越小,模型運行就會越快。

  • Resnet50.mlmodel文件拖入Xcode窗口的在項目導航面板
  • 此時會彈出一個窗口,窗口上帶有一些選項。保持默認選項,然後點擊“Finish”
  • 當我們把這樣一個文件拖入Xcode後,它會在項目中自動地創建該文件的引用。通過這個方式,我們在代碼中可以很容易地獲取這個文件

這裡是整個過程,以供參考:

如何基於蘋果推出的CoreML 3.0從零開發一個圖像分類應用? 17

使用訓練模型做出第一次預測

為了做出第一次預測,我們需要載入剛剛下載的ResNet50模型。然後,輸入一張圖片,將其轉為模型需要的格式,就可以做出預測了。

在ViewController.swift文件中的IBActions(第33行)下方寫入以下代碼:

// MARK: - Methods
extension ViewController {

  func imageClassify(image: CIImage) {
    answerLabel.text = "detecting..."
  
    // 通过生成模型的类来加载机器学习模型
    guard let model = try? VNCoreMLModel(for: Resnet50().model) else {
      fatalError("can't load Places ML model")
    }
    
    // 创建视觉模型请求,附带完成时的回调句柄
    let request = VNCoreMLRequest(model: model) { (weak self) request, error in
      let results = request.results as? (VNClassificationObservation)

      var outputText = ""
      
      for res in results!{
        outputText += "(Int(res.confidence * 100))% it's (res.identifier)n"
      }
      DispatchQueue.main.async { (weak self) in
        self?.answerLabel.text! = outputText
      }
    }
    
    // 在全局派发队列中运行CoreML3 Resnet50分类模型
    let handler = VNImageRequestHandler(ciImage: image)
    DispatchQueue.global(qos: .userInteractive).async {
      do {
        try handler.perform((request))
      } catch {
        print(error)
      }
    }

  }
}

上述代碼基本上就是接收一張新圖片,對圖片做預處理以滿足ResNet50的格式需求,然後把圖片傳入網絡做預測。

最重要的代碼行是以下這些:

// 通过生成模型的类来加载机器学习模型
guard let model = try? VNCoreMLModel(for: Resnet50().model) else {
fatalError("can't load Places ML model")
}

正是在這裡我們設置了模型名字。如果你想使用諸如BERT或者YOLO這樣的框架,你只需要改變模型名字,應用程序的其他部分就能順暢運作了。

現在,我們需要調用**imageClassify()這個函數來對圖像做出預測。在viewDidLoad()(第19行)**函數末尾添加如下代碼:

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


    classifyImage(image: ciImage)

現在你再運行這個應用程序,你可以看到它已經開始對應用程序啟動時顯示的圖片場景做出預測了。

如何基於蘋果推出的CoreML 3.0從零開發一個圖像分類應用? 18

把以上代碼拷貝到imagePickerController()(第87行)中,然後應用程序就可以對你選擇的任何圖片做出同樣的預測了。

以下就是該應用程序最終的樣子:

如何基於蘋果推出的CoreML 3.0從零開發一個圖像分類應用? 1

恭喜你——你剛剛已經為你的iPhone構建了第一個AI應用程序!

我們對Core ML 3的看法

使用最新的AI研究(包括圖像、語音和文字)來創建令人印象深刻的應用程序,顯然,蘋果把這個過程變得更簡單了。你不用知道太多的模型知識,就可以立馬開始學習和探索如何構建應用程序了。你可以進一步探索,嘗試用最新模型(例如BERT)創建更有意思的應用程序。如果可以的話,你可以嘗試在本文應用程序中使用SqueezeNet和MobileNet,看看不同模型在同樣的圖片上的性能表現如何。

本文使用的所有代碼都在Github上。

原文鏈接:
https://www.analyticsvidhya.com/blog/2019/11/introduction-apple-core-ml-3-deep-learning-models-iphone/