转:https://zhuanlan.zhihu.com/p/90919163
本文中提到的所有资源都可以从这里下载:GitHub repository
机器学习目前是科技行业最热门的话题之一。能够将以前依赖人工操作的任务自动化,为许多创新和令人兴奋的可能性打开了大门。
由于机器学习算法需要相当大的计算能力,过去它们只能在强大的后端实现。但是,随着手持设备嵌入了越来越强大的中央处理器(cpu),在这些设备上实现机器学习开始成为一个可行的选择。智能手机制造商抓住了这个机会。他们开始定期发布工具,使开发人员能够在他们的应用程序中集成机器学习模型。而且,事实证明,能够在智能手机上直接运行模型有一些非常有趣的潜力:用户的私人数据不需要离开他们的设备,与网络相关的延迟不是一个问题。这打开了许多新的用例,例如视频影响的实时分析。
2017年,苹果发布了Core ML,这是一款将机器学习模型整合到iOS应用中的框架。然而,iOS开发人员发现,当他们想要完全试用Core ML时,有一个障碍:要训练一个模型,他们必须使用不熟悉的工具和语言,比如Python。但在2018年,事情发生了变化——苹果发布了Create ML,其目的非常简单:它允许iOS开发者使用相同的工具和语言来训练简单的模型。唯一的要求是安装macOS Mojave和Xcode 10。
在本文中,我们将向您展示我们在使用Core ML和Create ML在iOS上进行机器学习实验时所遵循的步骤,并强调我们所面临的挑战和限制,以及如何克服这些挑战和限制并将其转化为我们的优势。
Image classification
如果你要问机器学习最基本的用例是什么,很有可能答案是图像分类。原理很简单:预测一个图像应该归入的预定义类别。在这个例子中,我们训练了一个模型,用猫和狗这两大类对图片进行分类。
首先,我们需要数据。在目录“image_classification”中有1400图片- 700的狗和700只猫 --其中80%被分离到“Training”目录中,这些图像是用于实际训练模型的那些图像,其余的位于“test”目录中,其目的是评估模型的质量。在这两个目录中还有另外两个目录,名为“dog”和“cat”,其中包含实际的图像。
这种命名约定在Create ML易于使用方面起了很大作用:我们不需要生成任何特定的元数据来指示每个图片的类别,因为它完全是通过目录的名称来完成的。
苹果声称,Create ML可以用10张图片训练一个模型,当然,数据集越大,模型的质量越好。注意,在数据稀缺的情况下,Create ML提供了通过生成翻转或旋转的原始图像来推断数据集的可能性。虽然不如新数据好,但这个技巧可以对训练质量产生积极的影响。
那么我们是如何开始训练我们的模型的呢?首先,我们打开了Xcode并创建了一个新的游乐场。当被问到这个问题时,我们确保选择了“macOS”和“Single View”。“然后我们删除了操场上的所有内容,并粘贴了如下代码:
那么我们是怎么开始训练我们的模特的呢?首先,我们打开了Xcode并创建了一个新的playground。当询问时,我们确保同时选择“MacOS”和“Single View”。然后我们删除了playground上的所有内容,并粘贴了以下代码:
import CreateMLUI
let builder = MLImageClassifierBuilder()
builder.showInLiveView()
然后我们运行playground,打开助理编辑。当您这样做时,应该会看到下面的界面。
正如你在右边看到的,你被要求“Drop Images To Begin Training”。你只需将“training”目录拖放到虚线区域内。一旦完成,CreateML就开始处理图像。
要获得关于训练过程的更多细节,您可以打开控制台。
Extracting image features from full dataset.
Analyzing and extracting image features.
+------------------+--------------+------------------+
| Images Processed | Elapsed Time | Percent Complete |
+------------------+--------------+------------------+
| 1 | 1.40s | 0% |
| 2 | 1.46s | 0% |
| 3 | 1.51s | 0.25% |
| 4 | 1.57s | 0.25% |
| 5 | 1.64s | 0.25% |
| 10 | 1.96s | 0.75% |
| 50 | 4.48s | 4.25% |
这里发生了什么?为了理解它,我们需要提供一些关于Create ML如何工作的信息。
Create ML使用一种叫做“迁移学习”的技术。其背后的想法非常简单:在Core ML内部,有一个经过大量图像训练的通用模型。这个通用模型非常擅长于对图像进行分类,因为它已经学会了必须在图像中查看哪些特征才能对图像进行分类。因此,当我们将猫和狗的图像提供给Create ML时,它所做的第一件事就是从图像中提取这些相同的特性。
需要注意的是,虽然迁移学习是一种强大的技术,但它也有其局限性。也就是说,它只在用于重新训练模型的数据与原始数据具有相同类型的特征时才有效。例如,如果你使用一个训练过的模型来识别日常生活中的物体,并试图使用天体图像对其进行重新训练,那么你很可能会以糟糕的结果告终。
这个过程需要大量的资源,而在我们的计算机上,完成这个过程需要一分多钟。
Create ML然后进入训练过程的第二部分:逻辑回归。这个名字听起来很复杂,但它的原理也很容易理解。一旦Create ML从图像中提取了相关的特征,它就必须弄清楚如何使用这些特征对图像进行可能的分类。打个比方,它需要找到将狗和猫的图像分开的界限,在我们的例子中。这个过程要快得多,不会超过几秒钟。
一旦这一切都结束了,Create ML就会向您展示一份关于训练进展情况的报告卡。
您可以看到这里有两个度量指标:“训练”和“验证”。“训练非常简单——它表明了该模型使用自己的训练集的成功程度。在这里,我们的模型在展示自己的训练集的图像时,在99%的情况下做出了正确的预测。”
验证要复杂一些。当我们开始训练我们的模型时,随机抽取了5%的训练图像。然后,这些图像被用来确保训练过程不会专注于无关的特征来进行分类。在这里,我们的验证集有98%的准确率,这表明我们的模型在处理非直接训练过程的图像时,大部分都是正确的。
在报告卡下面,你会看到你被要求“Drop Images To Begin Testing.”。现在是时候使用“test”目录中的图像了。要开始测试过程,您再次只需将目录拖放到虚线区域上即可。Create ML然后使用在这些新图像上训练的模型来测试它是否能够正确地分类它们。控制台中有详细的报告,参见下面的示例。
Number of examples: 280
Number of classes: 2
Accuracy: 98.57%
******CONFUSION MATRIX******
----------------------------------
True\Pred cat dog
cat 138 2
dog 2 138
******PRECISION RECALL******
----------------------------------
Class Precision(%) Recall(%)
cat 98.57 98.57
dog 98.57 98.57
从这里,我们可以看到我们的模型在98%以上的情况下是正确的,这是相当不错的!混淆矩阵告诉我们,两张猫的照片被错误地归类为狗,反之亦然。
要查看模型在哪些图像上失败,需要单击下面示例中显示的小按钮。
请记住,在训练过程中,在训练集中随机选择一个验证集,所以如果您没有得到与我们完全相同的结果,这是完全正常的。然而,你应该看到,错误分类的图像往往质量很差(非常暗或裁剪得很差)。但是您也可能发现更有趣的情况,如上图所示。很容易理解为什么这张照片被错误地归类为一张猫的照片,因为狗的毛看起来很像猫。
最后,剩下要做的就是保存模型。这可以通过单击视图顶部的小箭头,然后按照说明进行操作。
使用模型
一旦你有了一个训练有素的模型,如何尝试将它嵌入到iOS应用程序中呢?
在我们的例子中,我们将iPhone摄像头直接拍摄的视频流整合到我们的模型中,以便实时预测设备是指向狗还是指向猫。
完成此工作所需的代码主要由样板文件组成,因此我们不会在这里详细讨论它的所有细节。您只需要打开目录“CatDogClassifier”中的项目,就可以看到一切都已经实现了。当您通读代码时,您将理解每次视频影像生成一个帧时,我们的模型都会预测它的类别,并将结果和预测的可信度一起显示出来。
在你开始运行这款应用之前,给你一个建议:记住,当我们训练我们的模型时,它学会了把图像分成“猫”和“狗”两类。“这意味着我们的模型生活在一个任何图像都是猫或狗的宇宙中,没有其他类型的图像存在。所以,如果你把手机对准一只笔,看到模型把它归类为一只狗,不要惊慌。这并不意味着模型坏了,只是根据它的内在逻辑,你的笔看起来更像一只狗而不是猫。
如果你家里有宠物,你当然可以把你的手机对准它们,看看模型是否能正确识别它们。但是如果您不这样做,尝试次优的解决方案:在您的计算机屏幕上显示测试数据集的图片,并查看模型如何很好地分类它们。
在这里你可以看到我们尝试的过程。
只要图像质量足够好,模型就会以非常高的可信度正确地分类。另一方面,当图像的质量下降时,就像第四幅图像一样,预测的质量遵循相同的路径。这说明了机器学习最重要的原则之一:“无用输入,无用输出。”
要进一步
我们的模型能够快速获得一些令人信服的结果,因此我们想知道如何将这一原则应用到一个成熟的应用程序中。
图像分类实际上可以应用于各种各样的主题,所以应该不缺少用例。你可以做一些有趣的事情,创造一个游戏,让玩家在有限的时间内尽可能多地拍摄不同种类的物体。
您还可以使用它简化现有的流程。例如,一个租车应用程序可以使用Core ML,当用户拍下汽车损坏的照片时,就可以预测照片中汽车的哪个部分遭到了破坏,并预先填写相应的表单字段。
一些人建议的另一个用途是为视力受损的用户改善应用程序的可访问性。通过图像分类,可以预测图像的内容,并使用这种预测来提供文本描述。
在这种情况下需要记住的重要一点是,预测只能在我们确信它们将改善用户体验时使用。抛弃一个低可信度模型产生的潜在错误预测,总比强迫用户接受并让他们处理意外后果要好。
同样重要的是要记住数据集的质量有多重要。它是学习算法所依赖的关键输入,所以它包含的数据质量越好,结果就越好。再一次:“无用输入,无用输出。”
情绪分析
正如我们所看到的,机器学习是一种非常有效的图像分类技术。但是,当您尝试从图像移动到文本时会发生什么?
您可能会本能地认为在文本上运行分类算法比在图像上运行分类算法更简单。在第二个关于如何利用Create ML的示例中,我们尝试执行一个情感分析,从一个CSV文件中提取数据,该文件包含从在线电影评论中提取的10,000多个句子。
正如你所看到的,这些句子被贴上了标签,以表明它们表达的是积极还是消极的情绪,我们用它们来训练一个模型,这个模型给出一个与电影有关的句子,可以预测它表达的是积极还是消极的情绪。
再一次,我们使用playground来运行Create ML,但是这一次,我们没有图形界面来指导我们,所以我们必须编写一些代码!
查看“text_classification”目录中训练过程的工作实现内容,我们看到了我们需要做的第一件事就是解析CSV文件中的数据(如果你想看看它,它是存储为playground的资源):
var data = try MLDataTable(contentsOf: Bundle.main.url(forResource: "movie-sentences", withExtension: "csv")!,options: MLDataTable.ParsingOptions(contains Header: true, delimiter: ";"))
然后,与图像分类一样,我们将数据集分为两部分:“training”和“test”。
let (trainingData, testingData) = data.randomSplit(by: 0.8, seed: 5)
最后,利用训练数据对模型进行训练。
let sentimentClassifier = try MLTextClassifier(trainingData: trainingData, textColumn: "text", labelColumn: "class")
与以前一样,我们希望评估训练过程的进展情况,因此我们计算了与以前相同的指标。
// Training accuracy as a percentage
let trainingAccuracy = (1.0 - sentimentClassifier.trainingMetrics.classificationError) * 100
// Validation accuracy as a percentage
let validationAccuracy = (1.0 - sentimentClassifier.validationMetrics.classificationError) * 100
您应该发现训练的准确性约为99%,这意味着数据集是被正确学习的。验证的准确性应该不那么令人印象深刻,它可能会停滞在75%。这表明,该模型可能很难推断出它从训练集以外的句子中学到了什么。
为了确保这一点,我们使用测试数据运行模型。
let evaluationMetrics = sentimentClassifier.evaluation(on: testingData)
// Evaluation accuracy as a percentage
let evaluationAccuracy = (1.0 - evaluationMetrics.classificationError) * 100
评价的准确度也应在75%左右。这意味着,当面对未知的句子时,我们的模型在4次中有3次是正确的。
这可能看起来是一个足够好的结果——毕竟,75%远高于平均水平——但是请记住,我们只是将句子分为两类(积极的和消极的情绪)。因此,试图随机猜测正确的分类平均可以达到50%的准确率。考虑到这些信息,我们75%的准确率看起来并不是特别令人印象深刻。那么,一旦它被嵌入到一个应用程序中,如何翻译呢?
实时文本分析
为了节省时间,您会发现GitHub存储库中已经实现了一个名为“SentimentAnalysis”的演示项目。
让我们回顾一下如何集成文本分类模型。
这款应用的原理很简单:它只有一个文本框,用户可以在里面表达自己对电影的看法。当他们打字时,模型试图预测用户输入的情绪,并将预测显示在文本框下面。
在代码中执行预测不会带来任何特殊的挑战。我们从实例化预测模型开始。
let sentimentPredictor = try NLModel(mlModel: MovieReview().model)
然后我们使用它来执行预测,如下所示。
let sentimentPredictionOutput = sentimentPredictor.predictedLabel(for: predictionInput)
在这里,您将注意到这个模型与图像分类进行比较时的一个局限性:它不能为我们提供它所做预测的可信度。
剩下要做的就是将信息显示给用户。
let predictionIsPositive = sentimentPredictionOutput == "Pos"
let displayableResult = predictionIsPositive ? "positive " : "negative "
self.sentimentLabel.text = "It seems that your opinion is \(displayableResult)"
现在,让我们看看应用程序是如何工作的。
你会注意到,即使这个模型在4次中有3次是正确的,它也在一个句子上失败了,这个句子对于人类来说,很容易被正确分类。
如前所述,文本分类远不简单。在这里,情绪分析证明了它本身是一个相当棘手的话题,在这个问题上,我们的学习过程表现得比我们分类图像时糟糕得多。
然而,这并不意味着文本分类不能给你的应用程序带来价值。如果我们只使用模型的预测来提供谨慎的建议,那么模型不能做出超级准确的预测可能不是问题。例如,一个消息应用程序可能依赖于文本分类来填充一个内容感知的表情符号提示。当这个建议有意义的时候,用户会很高兴有正确的表情符号供他们使用,但是当一个建议不相关的时候,用户可能不会太注意它,而且这个失败通常不会被注意到。
正确使用Create ML
对于iOS开发者来说,开始尝试机器学习需要大量的努力。正如我们所看到的,Create ML已经完全改变了游戏,我们现在可以毫不费力地在应用程序中训练和嵌入模型,使用我们已经熟悉的工具和语言。
不过,需要注意的是,虽然Create ML非常适合于原型设计,但是在训练生产模型时,它可能会有一些不足。原因很简单:Create ML依赖于消费级计算机的功能。如果你在云中训练模型,你就可以获得更多的计算能力。
您还需要记住,机器学习是一个需要大量专业知识才能成功掌握的领域。我们或许可以用它做实验,但重要的是我们不能欺骗自己:它没有让我们成为机器学习专家。现在有很多机器学习算法,它们通常需要一些细微的参数调整才能产生最佳结果。所以,如果你真的想为你的应用程序建立训练模型,那就帮自己一个忙,向专家寻求建议。
幸运的是,作为iOS开发者,我们不需要成为机器学习专家。大多数时候,我们的价值在于通过嵌入一个已经训练好的模型来成功地实现一个创新用例的能力。正如我们所看到的,这种集成可以采取多种形式,并且在保持用户体验顺畅方面,很可能会带来技术挑战。
如果您想进一步了解create ML,这里是其完整文档的链接。
同时,为了更好地了解模型集成到应用程序中的所有方式,Core ML的文档值得一读。
最后,为了了解使用更复杂的模型可以实现什么,这个项目展示了如何通过视频流实时地识别和跟踪多个对象。
结论
移动设备上的机器学习仍处于起步阶段。在iOS系统上,从最初引入Core ML到现在还不到两年。如果你回顾一下第一代iPhone发布两年后的iOS应用程序,你会发现与现代应用程序相比,它们是多么粗糙和粗糙。这是非常有意义的:随着新技术的出现,行业需要一段时间来掌握如何有效利用它们。
一些流行的应用程序已经能够将机器学习嵌入到它们的核心用例中。例如,谷歌翻译依赖于机器学习模型来执行离线翻译。但仍有大量的创新空间!大多数应用程序在用户与它们交互时都会生成相当数量的数据,所以你的应用程序几乎肯定有潜力提供由机器学习支持的创新功能。