详解苹果Core ML:如何为iOS创建机器学习应用?
DanBaracchi
7年前
<p>在昨天开幕的 WWDC 2017 开发者大会上,苹果宣布了一系列新的面向开发者的机器学习 API,包括面部识别的视觉 API、自然语言处理 API,这些 API 集成了苹果所谓的 Core ML 框架;参阅机器之心报道《苹果开发者大会WWDC 2017:首次全面展示苹果的人工智能实力》。软件主管兼高级副总裁 Craig Federighi 介绍说,Core ML 的核心是加速在 iPhone、iPad、Apple Watch 上的人工智能任务,*支*持深度神经网络、循环神经网络、卷积神经网络、支持向量机、树集成、线性模型等。大会之后,苹果开发者网站更新了相关文档,对 Core ML 进行了更加详细的介绍。机器之心在本文中对该文档的内容进行了翻译和整理。更多详情可访问原文档。</p> <p>Core ML 文档地址:https://developer.apple.com/documentation/coreml</p> <h2>Core ML 介绍</h2> <p>使用 Core ML,你可以将训练好的机器学习模型整合到你的应用中。它支持以下操作系统:</p> <ul> <li>iOS 11.0+Beta</li> <li>macOS 10.13+Beta</li> <li>tvOS 11.0+Beta</li> <li>watchOS 4.0+Beta</li> </ul> <p>训练好的模型(trained model)是将一个机器学习算法应用到一个训练数据集之后所得到的结果。然后该模型可以基于新的输入数据而进行预测。比如,如果一个模型在一个地区的历史房价数据上进行了训练,那么它就可能能够根据房子的卧室和浴室数量来预测房价。</p> <p style="text-align:center"><img src="https://simg.open-open.com/show/5cb8bc2755dfb0785d147b3add55e060.png"></p> <p>Core ML 是域特定的框架和功能的基础。Core ML 支持用于图像分析的 Vision;用于自然语言处理的 Foundation(比如</p> <p>NSLinguisticTagger 类)和用于评估已经学习到的决策树的 GameplayKit。 Core ML 本身构建于低层面的原语(primitives)之上,比如 Accelerate、BNNS 和 Metal Performance Shaders。</p> <p style="text-align:center"><img src="https://simg.open-open.com/show/38f5357eaf4e79d74e2e314bd902b943.png"></p> <p>Core ML 也为设备性能进行了优化,从而减少了内存占用和功耗。严格在设备上运行能够确保用户数据的隐私,并且能保证你的应用在没有网络连接时也能够工作和响应。</p> <h2>如何使用 Core ML?</h2> <h2>获取 Core ML 模型</h2> <p>如何将 Core ML 模型用在你的应用中?Core ML 支持大量机器学习模型,包括神经网络、数集成、支持向量机和广义的线性模型。Core ML 需要 Core ML 格式(.mlmodel)。苹果已经以该格式提供了一些流行的开源模型,请访问: https://developer.apple.com/machine-learning 。你可以下载这些模型,并用在你的应用中。另外,一些研究组和大学也会发布自己的模型和训练数据,这些可能并不是 Core ML 模型格式的。要使用这些模型,请将其转换成 Core ML 格式。</p> <h2>将 Core ML 模型用在你的应用中</h2> <p>下面给出了一个示例,将一个训练好的模型 MarsHabitatPricer.mlmodel 用在了一个简单应用中,以用来预测火星上的地价。</p> <p>1.将模型添加到你的 Xcode 项目</p> <p>通过将模型拖拽到项目导航即可将该模型添加到你的 Xcode 项目。</p> <p><img src="https://simg.open-open.com/show/e92da7178e327ac7a995a875e1b4007b.png"> 你可以在 Xcode 中打开模型来查看关于该模型的信息——包括模型的类型及其需要的输入和输出。该模型的输入是太阳能电池板和温室的数量,以及栖息地的大小(单位:英亩)。该模型的输出是该栖息地的预测价格。</p> <p>2.在代码中创建模型</p> <p>Xcode 也会使用关于该模型输入和输出的信息来自动生成一个该模型的自定义的编程接口,你可以在代码中使用这些接口来和该模型进行交互。对于 MarsHabitatPricer.mlmodel,Xcode 会生成几个接口,其中 MarsHabitatPricer 表示该模型,MarsHabitatPricerInput表示该模型的输入,MarsHabitatPricerOutput则是该模型的输出。</p> <p>使用生成的 MarsHabitatPricer 类的初始化器来创建该模型:</p> <pre> let model = MarsHabitatPricer()</pre> <p>3.将输入值输入该模型</p> <p>这个示例应用使用了 UIPickerView 来获取来自用户的输入值:</p> <pre> func selectedRow(for feature: Feature) -> Int { return pickerView.selectedRow(inComponent: feature.rawValue) } let solarPanels = pickerDataSource.value(for: selectedRow(for: .solarPanels), feature: .solarPanels)let greenhouses = pickerDataSource.value(for: selectedRow(for: .greenhouses), feature: .greenhouses)let size = pickerDataSource.value(for: selectedRow(for: .size), feature: .size)</pre> <p>4.使用模型来做预测</p> <p>MarsHabitatPricer 类有一个生成的 prediction(solarPanels:greenhouses:size:)方法(method),可用于根据模型的输入值预测一个价格。在这个案例中,输入是太阳能电池板和温室的数量,以及栖息地的大小(单位:英亩)。这个方法的结果是一个 MarsHabitatPricerOutput 实例 marsHabitatPricerOutput</p> <pre> guard let marsHabitatPricerOutput = try? model.prediction(solarPanels: solarPanels, greenhouses: greenhouses, size: size) else { fatalError("Unexpected runtime error.") }</pre> <p>获取 marsHabitatPricerOutput 的 price 属性来获取预测的价格,并将结果展示在该应用的用户界面上:</p> <pre> let price = marsHabitatPricerOutput.price priceLabel.text = priceFormatter.string(for: price)</pre> <p>注:生成的 prediction(solarPanels:greenhouses:size:) 方法可能会报错。你会遇到的最常见的错误类型是你输入该方法的数据的类型与该模型所需的输入数据类型不符——比如,格式不对的图片。在这个示例应用中,输入是 Double 类型的。任何类型不匹配都会在编译时显现,对于这个示例应用而言,如果有什么地方不对,它就会报出一个致命错误。</p> <p>5.构建和运行一个 Core ML 应用</p> <p>Xcode 可以将该 Core ML 模型编译成一个资源(resource),其已经为设备上的运行进行了优化。这种优化了的模型的表示被包含在你的应用捆绑(app bundle)中,而且该应用在设备上运行时会使用这个模型来进行预测。</p> <p>将训练好的模型转换成 Core ML</p> <p>如果你的模型是使用支持的第三方机器学习工具创建和训练的,那么你可以使用 Core ML Tools(https://developer.apple.com/machine-learning ) 将其转换成 Core ML 模型格式。下表给出了支持的模型和第三方工具。</p> <p>Core ML Tools 是一个 Python 包(coremltools),托管在 Python Package Index (PyPI) 上。要了解更多有关 Python 包的信息,请参阅:https://packaging.python.org</p> <p>模型类型支持的模型支持的工具神经网络前馈、卷积、循环Caffe</p> <p>Keras 1.2.2树集成随机森林、boosted trees、决策树scikit-learn 0.18</p> <p>XGBoost 0.6支持向量机标量回归、多类分类scikit-learn 0.18</p> <p>LIBSVM 3.22广义的线性模型线性回归、logistic 回归scikit-learn 0.18特征工程稀疏矢量化、密集矢量化、分类处理scikit-learn 0.18Pipeline 模型顺序链式模型scikit-learn 0.18 </p> <p><img src="https://simg.open-open.com/show/fa8dc1273cce9395ae2d1caf653c4dc4.png"> <strong> </strong></p> <p>转换你的模型</p> <p>使用对应你的模型的第三方工具的 Core ML 转换器转换你的模型。调用该转换器的 convert 方法,并将结果保存为 Core ML 模型格式(.mlmodel)。比如,如果你的模型是用 Caffe 创建的,那么将该 Caffe 模型(.caffemodel)转递给 coremltools.converters.caffe.convert:</p> <pre> import coremltools coreml_model = coremltools.converters.caffe.convert('my_caffe_model.caffemodel')</pre> <p>然后将所得到的模型保存为 Core ML 模型格式:</p> <pre> coreml_model.save('my_model.mlmodel')</pre> <p>根据你模型的需要,你可能需要更新输入、输出和标签,或者你可能需要声明图像名、类型、格式。这些转换工具捆绑了更多文档,因工具不同,其提供的选项也有所不同。</p> <p>你也可以编写自定义的转换工具</p> <p>当你需要转换一个不在上表中的格式的模型时,你也可以创建你自己的转换工具。</p> <p>编写你自己的转换工具涉及到将你的模型的输入、输出和架构的表示(representation)翻译成 Core ML 模型格式。你需要定义该模型架构的每一层以及它们与其它层的连接。使用 Core ML Tools 提供的转换工具为例;它们演示了通过第三方工具创建的多种类型的模型被转换成 Core ML 模型格式的方法。</p> <p>注:Core ML 模型格式是由一些协议缓冲文件(protocol buffer files)定义的,具体描述请参阅: <a href="/misc/goto?guid=4959749678369085428" rel="nofollow,noindex">https://developer.apple.com/machine-learning</a></p> <h2>Core ML API</h2> <p>这个文档包含了正在开发中的 API 和相关技术的初步信息。这些信息可能会发生变化,遵循这个文档实现的软件应该在最后的操作系统软件上进行测试。了解更多使用苹果 Beta 软件的信息,访问: <a href="/misc/goto?guid=4959749678463478299" rel="nofollow,noindex">https://developer.apple.com/support/beta-software/</a></p> <p>在大多数案例中,你仅需要与你的模型的动态生成的接口进行交互,这些接口是 Xcode 自动生成的。你可以使用 Core ML API 直接支持自定义的工作流和高级的用例。比如,如果你需要做预测,同时异步地将输入数据收集到一个自定义的结构中,你可以通过采用 MLFeatureProvider 协议来使用该结构来为你的模型提供输入特征。</p> <p><img src="https://simg.open-open.com/show/9a082d7d8503557d5155d9176aa77291.jpg"></p> <p> </p> <p>来自:https://www.jiqizhixin.com/articles/d49f994b-78e8-4028-b2e1-2e3412086be9</p> <p> </p>