45

机器学习之CoreML入门

 5 years ago
source link: https://www.tuicool.com/articles/Nf6namf
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

机器学习是当今最热门的研究方向之一,涉及到包括算法在内的多项技术,看似门槛挺高,但是在 iOS 端可以基于苹果提供的 CoreML 及相关框架来更加便捷的研究并实现和人工智能相关的功能。

一、 CoreML 概览

使用 Core ML ,可以将机器学习模型集成到应用程序中。

R3M7F3Y.jpg!web

模型是用机器学习算法来训练数据集合的结果。我们可以使用模型根据新输入数据进行预测。例如,在给定卧室和浴室数量的情况下,根据区域历史房价进行训练生成的模型能够预测房屋的价格。

我们可以使用苹果提供的 Create ML 来训练模型。或者我们也可以先使用各种其他机器学习库来训练模型,然后使用 Core ML Tools 将对应模型转换为 Core ML 格式。 Core ML 还允许我们在设备上使用 MLUpdateTask 重新训练或微调现有模型,并保持用户数据的私密性和安全性。

Core ML 还是一些其他苹果框架和功能的基础。核心 ML 支持 Vision 图像分析, Natural Language 的自然语言处理, Speech 转换音频文本, SoundAnalysis 用于识别音频声音。 Core ML 本身建立在低级原语之上,如 Accelerate and BNNS ,和 Metal Performance Shaders 。

iMbIBbV.jpg!web

Core ML 在 iOS 设备上对性能进行了优化,可最大限度地减少内存占用和功耗,且在安全性上进行严格控制可保证用户数据的隐私性,并确保在网络连接不可用时,我们的 App 仍可正常运行并做出响应。

二、获取 CoreML 模型

在 App 使用 CoreML 的前提条件是要获取符合我们要求的的 Core ML 模型。

Core ML 支持各种机器学习模型,包括 neural networks (神经网络)、 tree ensembles (树集合)和 generalized linear models (广义线性模型)。 Core ML 需要 Core ML 模型格式(具有 .mlmodel 文件扩展名的模型)等。

我们还可以使用苹果提供的 Create ML 和自己的数据,通过训练自定义模型来执行诸如识别图像、文本识别或查找数值之间的关系等任务。使用 Create ML 训练的模型采用 Core ML 模型格式,可以直接在 App 中使用。

Apple 还提供了几种已经采用 Core ML 模型格式的流行开源模型。我们可以下载这些模型并直接在应用中使用它们。此外,各种研究小组和大学发布他们的模型和训练数据,这些数据可能不是 Core ML 模型格式。要在应用中使用这些模型,需要把它们转换成 CoreML 格式的模型。

1 、将其他模型转换为 CoreML 模型

如果我们的模型是使用受支持的第三方机器学习框架创建和培训的,则可以使用 Core ML Tools 或第三方转换工具(如 MXNet 转换器或 TensorFlow 转换器)将模型转换为 Core ML 模型格式。如果三方模型和框架苹果不支持,那幺我们还可以创建自己的转换工具来进行模型格式转换。

1 )使用 CoreML Tools

Core ML Tools 是一个 Python 包,可将各种模型类型转换为 Core ML 模型格式。使用说明及下载地址为: https://pypi.org/project/coremltools/ 。 下图列出了 Core ML Tools 支持的模型和第三方框架。

nYFnuua.jpg!web

2 )模型转换

使用与模型的第三方框架对应的 Core ML 转换器来转换模型。调用转换器的 convert 方法并将生成的模型保存为 Core ML 模型格式( .mlmodel )。

例:如果模型是使用 Caffe 创建的,可以先将 Caffe 模型( .caffemodel )做为参数传给 coremltools.converters.caffe.convert 方法,

然后将生成的模型保存为 Core ML 模型格式,

根据模型的不同,可能还需要更新输入、输出和标签,或者可能需要声明图像名称、类型和格式。因为模型的可用选项因工具而异,所以转换工具会生成一些文档给我们查阅。有关 Core ML Tools 的更多信息,可以查阅 Package Documentation ,地址为: https://apple.github.io/coremltools/ 。

3 )自定义模型转换工具

当需要转换的不是上面列出的工具支持的格式的模型时,我们还可以创建自己的转换工具。

编写自己的转换工具涉及将模型的输入、输出和体系结构的表示转换为 Core ML 模型格式。我们可以通过定义模型架构的每个层及其与其他层的连接来实现此目的。我们可以参考 Core ML Tools 提供的转换工具的实现,其演示了如何将从第三方框架创建的各种模型类型转换为 Core ML 模型格式。

Ps : Core ML 模型格式由一组协议缓冲区文件定义,并在 Core ML Model Specification 中详细描述,地址为:

https://apple.github.io/coremltools/coremlspecification/

2 、 Create ML

创建在应用中使用的机器学习模型,使用熟悉的工具(如 Swift 和 macOS playground )创建 ML ,以在 Mac 上创建和训练自定义机器学习模型。我们可以训练模型执行诸如识别图像、文本识别或查找数值之间的关系等任务。

uqY3aif.png!web

通过使用具有代表性的样本来训练模型。例如,我们可以通过展示不同狗的大量图像来训练模型来识别狗。在训练模型之后,可以测试它之前从未见过的数据,并评估它执行任务的程度。当模型运行良好时,可以使用 Core ML 将其集成到应用程序中。

qYFBbqj.png!web

Create ML 还可以使用 Photos 和 Siri 等苹果内置的机器学习基础架构,这意味着我们的图像分类和自然语言模型更小,训练时间更短。

CreateML 相关重点内容如下,仅做简单介绍并附上文档地址,有兴趣的同学可以详细查看:

1 )创建图片分类模型

创建图像分类器模型,训练机器学习模型对图像进行分类,并将其添加到我们的 Core ML 应用程序中。文档地址:

https://developer.apple.com/documentation/createml/creating_an_image_classifier_model

2 )创建文本分类模型

创建文本分类器模型,训练机器学习模型以对自然语言文本进行分类。文档地址为:

https://developer.apple.com/documentation/createml/creating_a_text_classifier_model

3 )创建声音分类模型

struct MLSoundClassifier ,用于训练模型以编程方式对音频数据进行分类的结构。

4 )创建活动分类模型

struct MLActivityClassifier ,训练的模型,用于根据运动传感器数据对活动进行分类。

5 )从表格数据创建模型

结构体和模型对于标记信息、估计新数量或查找相似度等任务非常有用。我们可以从表格数据创建模型,通过使用 Core ML 导入和管理表格数据来训练机器学习模型。文档地址:

https://developer.apple.com/documentation/createml/creating_a_model_from_tabular_data

6 )增加模型的准确性

提高模型的准确性,使用指标调整机器学习模型的性能。文档地址:

https://developer.apple.com/documentation/createml/improving_your_model_s_accuracy

7 )模型元数据结构

struct MLModelMetadata ,有关存储在 Core ML 模型文件中的模型的信息。

Ps :看到苹果支持这幺多类型的模型创建和训练,是不是感到手痒了,想自己亲自实践一把,那幺我们接下来仔细看一下如何从表格数据创建模型。

3 、从表格数据创建模型

从表格数据创建模型,通过使用 Core ML 导入和管理表格数据来训练机器学习模型。

1 )概览

接下来我们要看的这个示例 playground 使用 Create ML 框架来训练两个 Core ML 模型,一个 regressor (回归量)和一个 classifier (分类器)。

qU3miyN.png!web

使用 playground 将包含火星人住房数据的 CSV 文件导入数据表。数据表包含有关火星栖息地的以下信息栏:价钱、面积(面积)、温室数量、太阳能电池板数量、主要目的

playground 训练回归量和分类器模型,每个模型都有一组与该模型相关的列。一旦经过训练,回归者就可以预测栖息地的价格,并且分类器已准备好预测栖息地的目的。

Playground 最后将每个模型保存到文件,用来集成到应用程序中。

2 )导入数据

使用 MLDataTable 初始化方法将数据导入数据表。在此示例中,如下图 1 号位置所示 playground 将初始化其第一个数据表,其中包含嵌入在 playground 中的 CSV 文件的内容。

如下图 2 号位置所示通过数据表使用 print() 在控制台中查看其内容的打印文本如下图 3 号位置所示。

UNbUZrR.jpg!web

3 )隔离相关模型数据

如有必要,可以生成一个新数据表,其中仅包含模型的相关列。例如,要预测价格, playground 的回归量只需要五个原始列中的四列: price 、 solarPanels 、 greenhouses 和 size 。

playground 通过将一组列名称传递给第一个数据表来生成专门为回归器定制的新数据表。

bMrQFzY.jpg!web

为了预测栖息地的目的,分类器需要一组类似的列: purpose 、 solarPanels 、 greenhouses 和 size 。

6FVBjqA.jpg!web

4 )为训练和评估分配数据

如果我们打算在训练后评估模型,请保留一些数据表的行,以便通过将它们与训练数据分开来进行评估。通过使用不存在用于培训的数据评估我们的模型,模型评估更能代表其真实世界的性能。

playground 通过使用 MLDataTable 的 randomSplit(by:seed:) 方法为每个模型创建两个数据表,一个用于评估,另一个用于训练。该方法返回两个新数据表的元组,每个数据表通过随机划分原始数据表的行而生成。元组中第一个数据表的大小由参数 proportion 确定,即 0.0 和 1.0  之间的浮点值。元组中的第二个数据表包含剩余的数据行。

在此示例中, playground 将每个模型的数据行的 20 %留出用于评估,剩余的 80 %用于训练。

r6vyIzQ.jpg!web

模型所需的评估与培训所需的数据量因每个应用程序而异。通常,使用更多示例训练模型可以获得更好的性能。

5 )训练回归器

playground 通过向回归器的初始化方法提供训练数据表和目标列的名称来训练回归器。参数 targetColumn 确定我们希望模型在其预测中提供哪些信息。如下图所以 playground 告诉回归者通过指定模型的目标列来预测栖息地的价格 price 。

在训练期间, Create ML 会自动留出一小部分训练数据,用于在训练阶段验证模型的进度。训练过程根据验证数据测量模型的性能。根据验证的准确性,如果精度足够高,训练算法可以调整模型中的值,甚至停止训练过程。由于拆分是随机完成的,因此每次训练模型时可能会得到不同的结果。

6 )评估回归器

要了解回归者在训练和验证过程中的准确程度, playground 将获得其属性 trainingMetrics 和 validationMetrics 的 maximumError 属性值 。

uqeMVbz.jpg!web

Ps : MLRegressorMetrics 也有一个 rootMeanSquaredError 属性。

playground 通过传递其评估数据表来评估回归者的表现。

YnqymqA.jpg!web

如果回归器的评估表现不够好,我们可能需要做以下操作:

重新排列更多的数据行。

选择不同的特定回归类型(可以查阅“支持类型” MLRegressor ,文档地址: https://developer.apple.com/documentation/createml/mlregressor )。

进行其他调整(可以查阅“提高模型的准确度”,文档地址: https://developer.apple.com/documentation/createml/improving_your_model_s_accuracy )。

7 )训练分类器

playground 训练分类器以预测栖息地的目的。它通过在其训练数据表的“ purpose ”列上定位分类器来实现。

YZv6nmI.jpg!web

分类器只能预测其训练数据中提供的值,与回归量不同,回归量可以预测除训练数据之外的数值。例如,示例 playground 的分类器只能预测 “power” 的值, “farm” 或者 “general” ,因为这些都是“ purpose ”列的特定值。

Ps :此外我们还可以训练具有数值的分类器,而不是此处演示的文本标签(字符串)。与文本标签一样,分类器只能从其训练数据中返回特定的数值,并且不会像回归量那样修改或推断新的值。

8 )评估分类器

要了解分类器在训练和验证过程中的准确程度, playground 将获得其属性 trainingMetrics 和 validationMetrics 的 classificationError 属性值。

RzIVvme.jpg!web

与回归量一样, playground 通过传递其评估数据表来评估分类器的性能。

N3MZnuv.jpg!web

如果分类器的评估表现不够好,我们可能需要做以下操作:

重新排列更多的数据行。

选择不同的特定分类类型(可以查阅“支持类型” MLClassifier ,文档地址: https://developer.apple.com/documentation/createml/mlclassifier )。

进行其他调整(可以查阅“提高模型的准确度”,文档地址: https://developer.apple.com/documentation/createml/improving_your_model_s_accuracy )。

9 )保存模型

如果我们对模型的性能感到满意,可以将其保存到文件中,以便以后在应用中使用。 playground 通过其 write(to:metadata:) 方法将价格回归器以及元数据保存到用户的桌面。

RjINjuf.jpg!web

playground 同样将目的分类器保存到用户的桌面。

2IFnEv3.jpg!web

Ps :要查看模型的 MLModelMetadata 的作者、版本和描述,请在将模型添加到应用程序后在 Xcode 的项目导航器选择该模型进行查看。

三、将 CoreML 模型集成到我们的 App 中

将简单模型添加到应用程序,将输入数据传递给模型,然后处理模型的预测。

Demo 地址:

https://docs-assets.developer.apple.com/published/83f5575193/IntegratingACoreMLModelIntoYourApp.zip

此示例应用程序使用上面介绍的经过训练的模型 MarsHabitatPricer.mlmodel 来预测火星上的栖息地价格。

1 、将模型添加到 Xcode 工程

通过将模型拖动到项目导航器中,将模型添加到 Xcode 项目里。

可以通过在 Xcode 中打开模型来查看有关模型的信息,包括模型类型及其预期的输入和输出。在此示例中,输入是太阳能电池板和温室的数量,以及栖息地的地块面积(以英亩为单位)。输出是栖息地的预测价格。

2 、在代码中创建模型

Xcode 还使用有关模型输入和输出的信息来自动生成模型的自定义编程接口,可以使用该接口与代码中的模型进行交互。通过 MarsHabitatPricer.mlmodel , Xcode 生成接口来代表模型( MarsHabitatPricer ),包括模型的输入( MarsHabitatPricerInput )和模型的输出( MarsHabitatPricerOutput )。

使用生成的类 MarsHabitatPricer 的初始化方法来创建模型: let model = MarsHabitatPricer()

3 、获取输入值传递给模型

此示例应用程序使用 a UIPickerView 来获取用户的模型输入值:

vq22qyV.jpg!web

4 、使用模型进行预测

类 MarsHabitatPricer 有一个生成预言的方法 (solarPanels:greenhouses:size:) ,这个方法会从模型的输入值(太阳能电池板的数量,温室的数量和栖息地的大小(英亩))来预测价格。此方法的结果是一个 MarsHabitatPricerOutput 的实例。

MzEBzmB.jpg!web

通过 marsHabitatPricerOutput 的 price 属性来获取预测价格并在应用程序的 UI 中显示结果。

67NVnyJ.jpg!web

Ps :生成预测的方法 (solarPanels:greenhouses:size:) 可能会抛出错误。使用 Core ML 时遇到的最常见错误类型发生在输入数据的详细信息与模型所期望的详细信息不匹配时。例如,图像格式错误。

5 、构建并运行一个 CoreML App

Xcode 将 Core ML 模型编译为经过优化以在设备上运行的资源。模型的优化表示包含在您的应用程序包中,用于在应用程序在设备上运行时进行预测。

Ps :综上所述就是一整套通过使用自己创建的模型在 App 使用的流程,而大多数情况我们是不需要自己训练模型的,除了通过模型转换工具使用其他类型模型外,苹果还提供了一套很好用的图像视频框架让我们直接使用,接下来我们就来一起看下这个框架的简单使用。

四、使用 Vision 和 CoreML 来进行图片分类

Vision 是 Apple  在 WWDC 2017  推出的图像识别框架,它基于 Core ML ,所以可以理解成 Apple  的工程师设计了一种算法模型,然后利用 Core ML  训练,最后整合成一个新的框架,相比开源模型然后让开发者自己整合起来,这种方式更安全也更方便我们使用。

查阅苹果官方文档得知, Vision 为 应用计算机视觉算法在输入图像和视频上执行各种任务, Vision 框架执行面部和面部地标检测,文本检测,条形码识别,图像配准和一般特征跟踪。 Vision 还允许使用自定义 Core ML 模型进行分类或对象检测等任务。

使用 Vision 框架可以预处理照片,并使用 Core ML 模型对照片进行分类。使用 Core ML 框架,我们可以使用经过培训的机器学习模型对输入数据进行分类。该 Vision 框架与 Core ML 工程分类模型适用于图像,并预处理这些图像,使机器学习任务更容易,更可靠。

这里我们来看一个具体的例子。 Demo 地址:

https://docs-assets.developer.apple.com/published/cdf821b12b/ClassifyingImagesWithVisionAndCoreML.zip

此示例应用程序使用开源 MobileNet 模型(几种可用的分类模型之一)来识别使用 1000 个分类类别的图像,如下面的示例屏幕截图所示。

7FRbAv2.jpg!web

1 、预览示例 App

要查看此示例应用程序的运行情况,构建并运行项目,然后使用示例应用程序工具栏中的按钮拍摄照片或从照片库中选择图像。然后,示例应用程序使用 Vision 将 Core ML 模型应用于所选图像,并显示生成的分类标签以及指示每个分类的置信度的数字。它按模型分配给每个分类的置信度分数的顺序显示前两个分类。

2 、使用 CoreML 模型设置 Vision

Core ML 自动生成一个 Swift 类,可以轻松访问 ML 模型 ;  在此示例中, Core ML 会自动从模型 MobileNet model 中生成类 MobileNet 。要使用模型设置 Vision 请求,请创建该类的实例并使用其属性创建一个 VNCoreMLRequest 对象。使用请求对象的完成处理程序指定在运行请求后从模型接收结果的方法。

2ArQfeU.jpg!web

ML 模型以固定的宽高比处理输入图像,但输入图像可能具有任意的宽高比,因此 Vision 必须缩放或裁剪图像以适合。为获得最佳效果,请设置请求的 imageCropAndScaleOption 属性以匹配模型所训练的图像布局。对于可用的分类模型,除非另有说明,否则选项 VNImageCropAndScaleOptionCenterCrop 是合适的。

3 、运行 Vision 请求

使用要处理的图像创建 VNImageRequestHandler 对象,并将请求传递给该对象的 performRequests:error: 方法。此方法同步运行使用后台队列,以便在请求执行时不阻止主队列。

UBB3Uju.jpg!web

大多数模型都是针对已经正确定位显示的图像进行训练的。要确保正确处理具有任意方向的输入图像,请将图像的方向传递给图像请求处理程序。(此示例应用程序将初始值设定项添加 init(_:) 到用于转换方向值 UIImageOrientation 的 CGImagePropertyOrientation 类型。)

4 、处理图像分类结果

Vision 请求的完成处理程序指示请求是成功还是导致错误。如果成功,则其 results 属性包含描述由 ML 模型识别的可能分类的 VNClassificationObservation 对象。

UFNbMnr.jpg!web

Ps :参考类:

VNCoreMLRequest :使用 Core ML 模型处理图像的图像分析请求。

VNClassificationObservation :由图像分析请求产生的分类信息。

VNPixelBufferObservation :由 Core ML 图像分析请求产生的输出图像。

VNCoreMLFeatureValueObservation :由 Core ML 图像分析请求生成的键值信息的集合。

五、减少 CoreML App 的大小

减少 App 中 Core ML 模型使用的存储空间。在我们的 App 中加入机器学习模型是开始使用 Core ML 的最简单方法。随着模型变得更先进,它们可能变得更大并占用大量存储空间。对于基于神经网络的模型,请考虑通过使用较低精度的权重参数表示来减少其占用空间。如果模型不是可以使用半精度的神经网络,或者需要进一步缩小应用程序的大小,请添加在用户设备上下载和编译模型的功能,而不是将模型与 App 捆绑在一起。

1 、转换为半精度模型

Core ML Tools 提供一种转换功能,以从全精度转换神经网络模型的浮点权重到半精度值(减小在表示中使用从 32 至 16 比特的数量)。这种类型的转换可以显着减少网络的大小,其中大部分通常来自网络中的连接权重。

使用 Core ML Tools 将模型转换为更低的精度:

3QF3i2y.jpg!web

我们只能将嵌入神经网络的神经网络或管道模型转换为半精度,而且必须将模型中的所有全精度重量参数转换为半精度。

使用半精度浮点值不仅会降低浮点值的精度,还会降低可能值的范围。在将此选项部署到用户之前,请确认模型的行为不会降级。

2 、转换为较低精度模型

Core ML Tools 2.0 引入了新的实用程序,可将模型的精度降低到 8,4,2 或 1 位。这些工具包括用于衡量原始模型和较低精度模型之间行为差异的功能。有关使用这些实用程序的更多信息,请参阅 Core ML Tools 神经网络量化文档,文档地址为:

https://apple.github.io/coremltools/generated/coremltools.models.neural_network.quantization_utils.html

3 、下载并编译模型

减少 App 大小的另一个选择是让 App 将模型下载到用户的设备上并在后台进行编译。例如,如果用户仅使用我们的应用支持的模型的子集,则无需将所有可能的模型与我们的应用捆绑在一起。相反,可以稍后根据用户行为下载模型。请查阅在用户设备上下载和编译模型,文档地址为:

https://developer.apple.com/documentation/coreml/core_ml_api/downloading_and_compiling_a_model_on_the_user_s_device?language=objc 。

附录:参考文档(苹果官方文档):

https://developer.apple.com/documentation/coreml?language=objc,文中内容包括图片部分来自苹果官方文档。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK