Core ML框架详细解析(十七) —— Core ML 和 V
版本记录
版本号 | 时间 |
---|---|
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,您可以轻松访问Apple的模型,以检测面部,面部标记,文本,矩形,条形码和对象。
您还可以将任何图像分析Core ML模型包装在Vision模型中,这是您在本教程中要做的。由于这两个框架都是基于Metal构建的,因此它们可以在设备上高效运行,因此您无需将用户的数据发送到服务器。
Integrating a Core ML Model Into Your App - 将Core ML模型集成到您的应用程序中
本教程使用Places205-GoogLeNet
模型,您可以从Machine Learning page下载该模型。 向下滚动到Working with Models
,然后下载第一个。 当你在那里时,请注意其他三个模型,它们都在图像中检测物体 - 树木,动物,人等等。
注意:如果您拥有使用受支持的机器学习工具(如
Caffe
,Keras
或scikit-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模型完成工作的图像分析请求。其完成处理程序接收request
和 error
对象。
您检查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 project。 Vision + ML
示例应用程序使用MNIST
分类器,它识别手写数字 - 对邮政分拣的自动化非常有用。 它还使用原生Vision
框架方法VNDetectRectanglesRequest
,并包含Core Image
代码以更正检测到的矩形的透视图。
您还可以从Core ML documentation page下载不同的示例项目。 MarsHabitatPricePredictor
模型的输入只是数字,因此代码直接使用生成的MarsHabitatPricer
方法和属性,而不是将模型包装在Vision模型中。 通过一次更改一个参数,很容易看出模型只是一个线性回归:
137 * solarPanels + 653.50 * greenHouses + 5854 * acres
您现在已经准备好将现有模型集成到您的应用中。以下是一些更详细的资源:
- Apple的Core ML Framework文档
- WWDC 2017 Session 703介绍Core ML
- WWDC 2017 Session 710 Core ML深入
从2016年起:
- WWDC 2016 Session 605 Metal的新功能,第2部分:演示展示了应用程序进行Inception模型分类计算的速度,这要归功于Metal。
- Apple的Basic Neural Network Subroutines文档
考虑建立自己的模型?我担心这超出了本教程(以及我的专业知识)的范围。这些资源可能会帮助您入门:
-
Quartz article on Apple’s AI research paper:
Dave Gershgorn
关于人工智能的文章非常清晰且内容丰富。本文非常出色地总结了Apple’s first AI research paper:研究人员使用经过真实图像训练的神经网络来优化合成图像,从而有效地生成大量高质量的新训练数据,不存在个人数据隐私问题。 - 感谢
Jimmy Kim(jimmyk1)
与这个链接Awesome CoreML Models - 一系列与Core ML一起使用的机器学习模型:试用它们,并贡献自己的模型!
最后但并非最不重要的是,我从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简单示例,感兴趣的给个赞或者关注~~~