iOS杂技ML

Core ML框架详细解析(十七) —— Core ML 和 V

2018-10-17  本文已影响446人  刀客传奇

版本记录

版本号 时间
V1.0 2018.10.17 星期三

前言

目前世界上科技界的所有大佬一致认为人工智能是下一代科技革命,苹果作为科技界的巨头,当然也会紧跟新的科技革命的步伐,其中ios API 就新出了一个框架Core ML。ML是Machine Learning的缩写,也就是机器学习,这正是现在很火的一个技术,它也是人工智能最核心的内容。感兴趣的可以看我写的下面几篇。
1. Core ML框架详细解析(一) —— Core ML基本概览
2. Core ML框架详细解析(二) —— 获取模型并集成到APP中
3. Core ML框架详细解析(三) —— 利用Vision和Core ML对图像进行分类
4. Core ML框架详细解析(四) —— 将训练模型转化为Core ML
5. Core ML框架详细解析(五) —— 一个Core ML简单示例(一)
6. Core ML框架详细解析(六) —— 一个Core ML简单示例(二)
7. Core ML框架详细解析(七) —— 减少Core ML应用程序的大小(一)
8. Core ML框架详细解析(八) —— 在用户设备上下载和编译模型(一)
9. Core ML框架详细解析(九) —— 用一系列输入进行预测(一)
10. Core ML框架详细解析(十) —— 集成自定义图层(一)
11. Core ML框架详细解析(十一) —— 创建自定义图层(一)
12. Core ML框架详细解析(十二) —— 用scikit-learn开始机器学习(一)
13. Core ML框架详细解析(十三) —— 使用Keras和Core ML开始机器学习(一)
14. Core ML框架详细解析(十四) —— 使用Keras和Core ML开始机器学习(二)
15. Core ML框架详细解析(十五) —— 机器学习:分类(一)
16. Core ML框架详细解析(十六) —— 人工智能和IBM Watson Services(一)

开始

首先看一下写作环境

Swift 4, iOS 11, Xcode 9

机器学习风靡一时。 许多人都听说过,但很少有人知道它是什么。

这个iOS机器学习教程将向您介绍Core ML和Vision,这是iOS 11中引入的两个全新框架。

具体来说,您将学习如何将这些新API与Places205-GoogLeNet模型一起使用来对图像场景进行分类。

打开入门项目。 它已包含用于显示图像的用户界面,并允许用户从其照片库中选择另一个图像。 因此,您可以专注于实现应用程序的机器学习和视觉方面。

构建并运行您的项目;你会在看到一个城市晚上的图像,还有一个按钮:

从照片应用中的照片库中选择其他图像。 此入门项目的Info.plist已经有一个Privacy – Photo Library Usage Description,,因此可能会提示您允许使用。

图像和按钮之间的间隙包含一个标签,您可以在其中显示模型的图像场景分类。


iOS Machine Learning - iOS机器学习

机器学习是一种人工智能,计算机在没有明确编程的情况下“学习”。 机器学习工具不是编码算法,而是通过在大量数据中查找模式,使计算机能够开发和优化算法。

1. Deep Learning - 深度学习

自20世纪50年代以来,人工智能研究人员开发了许多机器学习方法。 Apple的Core ML框架支持神经网络,树集合,支持向量机,广义线性模型,特征工程和流水线模型。然而,神经网络已经产生了许多最近最成功的成功,从谷歌2012年使用YouTube视频开始训练人工智能识别猫和人。仅仅五年之后,谷歌就发起了一场测试,以确定5000种植物和动物。 Siri和Alexa等应用也归功于神经网络。

神经网络试图用不同方式链接在一起的节点层对人脑过程进行建模。每个附加层都需要大幅提高计算能力:Inception v3是一种物体识别模型,具有48层和大约2000万个参数。但计算基本上是矩阵乘法,GPU处理非常有效。 GPU的成本下降使人们能够创建多层深度神经网络,因此称为深度学习。

神经网络需要大量的训练数据,理想情况下代表了各种可能性。用户生成数据的爆炸性增长也促进了机器学习的复兴。

训练模型意味着向神经网络提供训练数据,并让它计算用于组合输入参数以产生输出的公式。离线训练通常在具有许多GPU的计算机上进行。

要使用该模型,您可以为其提供新输入,它计算输出:这称为推理。推理仍需要大量计算,以计算新输入的输出。由于像Metal这样的框架,现在可以在手持设备上进行这些计算。

正如您将在本教程结尾处看到的那样,深度学习远非完美。构建一组真正具有代表性的训练数据真的很难,而且过度训练模型太容易了,因此它对于古怪的特征给予过多的权重。

2. What Does Apple Provide? - Apple提供什么?

Apple在iOS 5中引入了NSLinguisticTagger来分析自然语言。 Metal在iOS 8引入,提供对设备GPU的低级访问。

去年,Apple在其Accelerate框架中添加了Basic Neural Network Subroutines(BNNS),使开发人员能够构建用于推理的神经网络(而不是训练)。

而今年,Apple已经为您提供了Core ML和Vision!

您还可以将任何图像分析Core ML模型包装在Vision模型中,这是您在本教程中要做的。由于这两个框架都是基于Metal构建的,因此它们可以在设备上高效运行,因此您无需将用户的数据发送到服务器。


Integrating a Core ML Model Into Your App - 将Core ML模型集成到您的应用程序中

本教程使用Places205-GoogLeNet模型,您可以从Machine Learning page下载该模型。 向下滚动到Working with Models,然后下载第一个。 当你在那里时,请注意其他三个模型,它们都在图像中检测物体 - 树木,动物,人等等。

注意:如果您拥有使用受支持的机器学习工具(如CaffeKerasscikit-learn)创建的训练模型,则将Converting Trained Models to Core ML描述了如何将其转换为Core ML格式。

1. Adding a Model to Your Project - 将模型添加到项目中

下载GoogLeNetPlaces.mlmodel后,将其从Finder拖到项目的Project Navigator中的Resources组中:

选择此文件,稍等片刻。 Xcode生成模型类时会出现一个箭头:

单击箭头以查看生成的类:

Xcode生成了输入和输出类,主类GoogLeNetPlaces,它具有model属性和两种prediction方法。

GoogLeNetPlacesInput具有CVPixelBuffer类型的sceneImage属性。不要害怕,Vision框架会将我们熟悉的图像格式转换为正确的输入类型。

Vision框架还将GoogLeNetPlacesOutput属性转换为自己的results类型,并管理对prediction方法的调用,因此在所有这些生成的代码中,您的代码将仅使用model属性。

2. Wrapping the Core ML Model in a Vision Model - 在Vision模型中包装核心ML模型

最后,你可以编写一些代码! 打开ViewController.swift,导入两个框架,就在导入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框架请求处理程序;它不是Core ML模型特有的。 你给它作为参数进入detectScene(image :)的图像。 然后通过调用其perform方法运行处理程序,传递一组请求。 在这种情况下,您只有一个请求。

perform方法抛出一个错误,所以你将它包装在try-catch中。

3. Using the Model to Classify Scenes - 使用模型对场景进行分类

那是很多代码! 但现在你只需要在两个地方调用detectScene(image :)

viewDidLoad()imagePickerController(_:didFinishPickingMediaWithInfo:)的末尾:

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

detectScene(image: ciImage)

现在构建并运行。 不应该花很长时间才能看到分类:

嗯,是的,图像中有摩天大楼。 还有一列火车。

点击按钮,然后选择照片库中的第一张图片:一些阳光斑驳的树叶的特写:


A Look at Apple’s Core ML Sample Apps - 看看Apple的Core ML示例应用程序

本教程的项目类似于WWDC 2017 Session 506 Vision Framework:Building on Core ML.sample projectVision + ML示例应用程序使用MNIST分类器,它识别手写数字 - 对邮政分拣的自动化非常有用。 它还使用原生Vision框架方法VNDetectRectanglesRequest,并包含Core Image代码以更正检测到的矩形的透视图。

您还可以从Core ML documentation page下载不同的示例项目。 MarsHabitatPricePredictor模型的输入只是数字,因此代码直接使用生成的MarsHabitatPricer方法和属性,而不是将模型包装在Vision模型中。 通过一次更改一个参数,很容易看出模型只是一个线性回归:

137 * solarPanels + 653.50 * greenHouses + 5854 * acres

您现在已经准备好将现有模型集成到您的应用中。以下是一些更详细的资源:

从2016年起:

考虑建立自己的模型?我担心这超出了本教程(以及我的专业知识)的范围。这些资源可能会帮助您入门:

最后但并非最不重要的是,我从Andreessen Horowitz’s Frank Chen的AI简明历史中学到了很多东西:AI and Deep Learning a16z podcast


源码

1. Swift

看一下文档结构

看一下sb内容

下面看下源码

1. ViewController.swift
import UIKit
import CoreML
import Vision

class ViewController: UIViewController {

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

  // MARK: - Properties
  let vowels: [Character] = ["a", "e", "i", "o", "u"]

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

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

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

    detectScene(image: ciImage)
  }
}

// MARK: - IBActions
extension ViewController {

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

// MARK: - Methods
extension ViewController {

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

    // 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)"
      }
    }

    // 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)
      }
    }
  }
}

// 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
    
    guard let ciImage = CIImage(image: image) else {
      fatalError("couldn't convert UIImage to CIImage")
    }

    detectScene(image: ciImage)
  }
}

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

后记

本篇主要讲述了Core ML 和 Vision简单示例,感兴趣的给个赞或者关注~~~

上一篇下一篇

猜你喜欢

热点阅读