天天看点

如何在iPhone上建立第一个机器学习模型

引言

作为一名数据科学家,我一直有一个梦想——顶级科技公司在与我相关的领域不断推出新产品。

如果你观看了Apple公司最新的iPhone X发布会,你会发现iPhone X具有非常酷的特性,比如FaceID、动态表情、增强现实,这些特性都使用了机器学习。作为一名骇客,我决定亲自上手探索一下如何建立那样的系统。

进一步调查后我发现了一个很有趣的工具,那就是Apple官方面向开发者推出的机器学习框架工具CoreML。它可以在iPhone、Macbook、Apple TV、Apple watch等任何一个苹果设备上使用。

如何在iPhone上建立第一个机器学习模型

另一个有趣的发现是Apple在最新的iPhone手机上设计了一个定制GPU,以及一个带有神经引擎的A11先进仿生学处理芯片,以便用于优化机器学习。

随着核心组件计算引擎功能日益强大,iPhone将开辟机器学习的新途径,CoreML在未来的意义将越来越重要。

读完这篇文章,大家将会了解Apple CoreML是什么以及为何它势头正猛。我们也将通过开发一款iPhone上的垃圾短信分类app来与大家一起一探CoreML的实现细节。

同时,我们也会通过客观评价CoreML的利弊来结束本篇文章。

如何在iPhone上建立第一个机器学习模型

文章目录:

CoreML是什么?

建立系统

案例学习:实现一个iPhone上的垃圾短信分类app

使用CoreML的利弊

01、CoreML是什么?

如何在iPhone上建立第一个机器学习模型

今年,Apple公司在每年一次的全球开发者大会WWDC(类似于谷歌的I/O会议)上大肆宣传CoreML。为了更好地理解CoreML的作用,我们需要了解一些背景。

CoreML的背景

有趣的是,这并不是Apple公司第一次发布移动端机器学习框架。去年它就发布了一些同样的框架库:

Accelerate 框架和基本神经网络子程序(BNNS)——高效利用CPU并使用卷积神经网络进行预测。

Metal Performance Shaders CNN(MPSCNN)——高效利用GPU并使用卷积神经网络进行预测。

这两个框架库的区别在于,一个针对CPU优化而另一个针对GPU。这是因为有时在inference(推断)过程中CPU比GPU计算更快,而在training(训练)过程中几乎每次都是GPU计算更快。

但为了提高性能,框架会非常接近底层硬件,使得这些混合框架对开发者造成混乱,从而很难编程。

走进CoreML

如何在iPhone上建立第一个机器学习模型

CoreML 会在之前提到的两个库上面提供一个抽象层,并且还会提供一个简单的接口,以达到同样的效率。另一个好处是,在我们的app运行时,CoreML充分照顾到了CPU与GPU之间的上下文切换。

换句话说,假如我们有一个耗内存的任务,它涉及文本处理(自然语言处理),CoreML将自动在CPU运行;而如果我们有一个计算繁重的任务,例如图像识别,它将使用GPU;当app包含这两种功能的时候,它又会自动切换从而使得两者都得到最大化的利用。

如何在iPhone上建立第一个机器学习模型

CoreML还将提供什么?

CoreML顶层还附带了三个库:

Vision:这个库提供了高性能图像分析与计算机视觉技术,用于人脸识别、特征检测以及图像与视频中的场景识别。

Foundation(NLP):顾名思义,它提供了自然语言处理的一些功能

Gameplay Kit:用于游戏开发的库,此外它还提供了AI,并运用决策树。

以上提到的所有库都可以用一些简单的接口轻松使用,可用于完成一系列任务。通过上述的库,CoreML最终框架图如下:

如何在iPhone上建立第一个机器学习模型

注意,上述设计给iOS应用程序提供了一个很好的模块化结构。你可以使用不同层进行不同的任务,也可以用多种方式使用它们(例如,在app中使用NLP进行图像分类)。了解更多:Vision、Foundation与GameplayKit。好了,现在我们有了足够的理论知识,是时候实践一下了!

“微信排版限制,需要代码的同学请看文末的原文链接自行查找”

02、建立系统

为了充分使用CoreML,你需要遵循如下要求:

1.OS:MacOS(Sierra 10.12或以上)

2.Python 2.7和pip:点击下载mac上的python。打开终端,输入如下代码安装pip:

sudo easy_install pip 

3.coremltools:这个包有助于将你的模型从python转换成CoreML能理解的格式。在终端输入如下代码进行安装:

sudo pip install -U coremltools 

4.Xcode 9:这是用于构建Apple设备上应用程序的默认软件。点此下载。下载Xcode之前,你需要使用Apple ID进行登陆。

如何在iPhone上建立第一个机器学习模型

登陆之后,你需要验证你的apple ID。你将会收到与注册Apple ID的设备相同的通知。

如何在iPhone上建立第一个机器学习模型

点击“允许”并输入网站显示的6位密码。

如何在iPhone上建立第一个机器学习模型

当你完成这一步,你将会看到一个下载选项。你可以在那儿下载Xcode。现在,我们建立好了系统,准备好了的话就让我们进入实现部分!

03、案例学习:实现一个iPhone上的垃圾短信分类app

在本次开发中,我们将着重于在两个重要途径上来使用CoreML的能力。让我们开始吧!

将你的机器学习模型转换成CoreML格式

CoreML其中一个优势,或者我应该说它的创造者作出的明智的决定是,支持在sklearn、caffe、xgboost等其他流行框架中训练好的机器学习模型的转换。

数据科学社区并不会不尝试CoreML试行,因为他们可以在他们最喜欢的环境中进行实验、训练他们的模型,然后轻松导入并在iOS/MacOS的app上使用。

下面是即时可用的CoreML支持的框架:

如何在iPhone上建立第一个机器学习模型

Mlmodel是什么?

为了使转换过程简单,Apple设计了它自己的开放格式来代表跨框架机器学习模型,即mlmodel。这个模型文件包含了模型各层的描述、输入、输出、类标签、任何需要对数据进行的预处理。它还包含了已学习的参数(权重及偏差)。

转换流程如下:

在你最喜欢的框架中训练模型

使用python模块coremltools将模型转换为.mlmodel格式

在app中使用模型

如何在iPhone上建立第一个机器学习模型

在本次例子中,我们将在sklearn中训练一个垃圾短信分类器,然后将该模型转给CoreML。

关于垃圾短信数据集

SMS垃圾短信数据集 v.1是一个公开的SMS标注短信数据集,用于手机垃圾短信研究。它包含了5574份真实无编码的英文短信,这些短信都标注了合法(做作)或者垃圾短信。

如何在iPhone上建立第一个机器学习模型

你可以在此下载该数据集。

建立基础模型

我们使用sklearn中的LinearSVC建立基础模型。同时,我们提取短信文本的TF-IDF值作为模型特征。TF-IDF是自然语言处理中的一种方法,它基于唯一标识文档的词来分类文档。如果你想要学习更多NLP和tf-idf的知识,你可以阅读这篇文章。代码如下:

import numpy as npimport pandas as pd#Reading in and parsing dataraw_data = open('SMSSpamCollection.txt', 'r')sms_data = []for line in raw_data: split_line = line.split("\t") sms_data.append(split_line) 

#Splitting data into messages and labels and training and testsms_data = np.array(sms_data)X = sms_data[:, 1]y = sms_data[:, 0]  

#Build a LinearSVC modelfrom sklearn.feature_extraction.text import TfidfVectorizerfrom sklearn.svm import LinearSVC  

#Build tf-idf vector representation of datavectorizer = TfidfVectorizer()vectorized_text = vectorizer.fit_transform(X)text_clf = LinearSVC()text_clf = text_clf.fit(vectorized_text, y) 

我们的模型建立好了,让我们用一份垃圾短信测试一下:

#Test the modelprint text_clf.predict(vectorizer.transform(["""XXXMobileMovieClub: To use your credit, click the WAP link in the next txt message or click here>> http://wap. xxxmobilemovieclub.com?n=QJKGIGHJJGCBL"""])) 

有趣,我们的模型效果很好!让我们添加交叉验证:

#Cross - Validationfrom sklearn.model_selection import cross_val_scorecross_score = cross_val_score(text_clf, vectorized_text, y, cv=10)print cross_scoreprint "mean:",np.mean(cross_score) 

现在已建好模型,为使它适用于CoreML,我们需要把它转换成.mlmodel格式。用之前安装的coremltools工具包来实现。以下代码能将我们的模型转换成.mlmodel格式。  

import coremltools  

#convert to coreml model  

coreml_model = coremltools.converters.sklearn.convert(text_clf, "message", "spam_or_not")  

#set parameters of the model 

coreml_model.short_description = "Classify whether message is spam or not"  

coreml_model.input_description["message"] = "TFIDF of message to be classified"  

coreml_model.output_description["spam_or_not"] = "Whether message is spam or not"  

#save the model  

coreml_model.save("SpamMessageClassifier.mlmodel") 

这是如何运作的呢?

首先我们运用coremltools Python工具包。再选择一个转换器对模型进行转换,本例中用converters.sklearn,因为要转换的模型是用sklearn工具建立的。然后在.convert()括号内声明模型对象、输入变量名称、输出变量名称。接下来设置模型参数来添加更多关于输入、输出的信息,最后用.save()保存已转换成CoreML格式的模型文件。

如何在iPhone上建立第一个机器学习模型

双击模型文件,会用Xcode打开。

如何在iPhone上建立第一个机器学习模型

如你所见,该模型文件显示了很多信息,关于模型的类型、它的输入、输出,输入输出的类型等。我已在上图中用红色标记。你可以将这些描述和转换成.mlmodel时所提供的一一对比。

将自己的模型引入CoreML就是这么简单。现在你的模型已经在苹果生态系统里了,接下来真正好玩的开始啦!

注意:这一步的完整代码文件请看这里。进一步了解coremltools请看这里,提供的不同种类的转换器请看这里。

将该模型用于我们的app

既然已经训练好模型并引入CoreML中,让我们用该模型开发一个iPhone垃圾信息分类app吧!

我们将在模拟器上运行app。模拟器这一软件能显示app的界面及运行情况,像在iPhone上真正运行那样。这样节省了大量时间,因为用iPhone运行app之前,我们就可以测试代码、调试。看一下最终产品长什么样子吧:

如何在iPhone上建立第一个机器学习模型

下载工程

我已经为我们的app制作了一个简单基础的UI放在GitHub上。用以下命令加载并运行:

git clone https://github.com/mohdsanadzakirizvi/CoreML-on-iPhone.git  

cd CoreML-on-iPhone/Practice\ App/  

open coreml\ test.xcodeproj/ 

这会在Xcode打开我们的项目。

如何在iPhone上建立第一个机器学习模型

在Xcode窗口中我用红色标示了三个重要区域:

左上角的播放按钮用来启动app在模拟器运行。

播放按钮的正下方列出了与我们项目相关的文件和文件夹。这是项目导航栏,方便你找项目里的文件和文件夹。

播放按钮旁边写着iPhone 8,表示你想用模拟器仿真的目标设备。你可以点击它,在下拉列表里选择iPhone 7。

让我们开始运行app吧,看看会发生什么。点击左上角的播放按钮让模拟器运行app。在框中随便键入些文字,点击预测按钮。发生了什么?

如何在iPhone上建立第一个机器学习模型

到现在,我们的app什么也没做,只是原样输出框中键入的文字。

向你的app中添加一个训练好的模型

相当简单:

将你的.mlmodel模型文件拖入到Xcode窗口工程导航栏中。

做好后,会弹出一个含有几项选择的窗口,默认缺省,点击“结束”。

当你像这样拖拽文件到Xcode时,自动在工程中生成该文件的参考路径。这样你能轻松地在代码中获取该文件。

如何在iPhone上建立第一个机器学习模型

编译模型

在能够用我们的模型进行推测之前,需要让Xcode在建立阶段中编译模型。以下是具体步骤:

在工程导航栏中选择有蓝色标识的文件

如何在iPhone上建立第一个机器学习模型

会在右手边打开工程设置。点击Compile Sources(编译源)并选择+标识。

在新出现的窗口中选择 SpamMessageClassifier.mlmodel文件,点击新增。

如何在iPhone上建立第一个机器学习模型

现在每次运行app,Xcode就会编译我们的机器学习模型,使它能用来做预测。

在代码中创建模型

任何为苹果设备开发的app都用swift编程。你不需要学swift但如果以后你有兴趣深入,你可以跟着这个教程学。

在工程导航栏中选择 ViewController.swift。这一文件包含大部分控制app功能的代码。

如何在iPhone上建立第一个机器学习模型

第24行的 predictSpam() 函数会做最多的工作。删除第25行,向函数中添加以下代码:

let enteredMessage = messageTextField.text!  

if (enteredMessage != ""){  

spamLabel.text = ""  

}  

//Fetch tfidf representation of text  

let vec = tfidf(sms: enteredMessage)  

do {  

//Get prediction on the text  

let prediction = try SpamMessageClassifier().prediction(message: vec).spam_or_not  

print (prediction)  

if (prediction == "spam"){  

spamLabel.text = "SPAM!" 

 }  

else if(prediction == "ham"){  

spamLabel.text = "NOT SPAM"  

catch{  

spamLabel.text = "No Prediction"  

以上代码检查用户是否向框内输入了任何信息。如果有,调用tfidf()函数计算文本的tfidf值。然后生成一个SpamMessageClassifier 对象实例,再调用.prediction() 函数。这与sklearn中的 .predict() 函数相同。然后基于预测展示恰当的信息。

但为什么需要tfidf()?

记住我们基于文本的tf-idf表征来训练模型,因此我们的模型需要相同形式的输入。一旦获得键入的文本框的信息,就调入tfidf()函数来做同样的事。来写这一步的代码吧,复制下列代码放在predictSpam()函数后:

//MARK: Functionality code  

func tfidf(sms: String) -> MLMultiArray{  

//get path for files  

let wordsFile = Bundle.main.path(forResource: "wordlist", ofType: "txt")  

let smsFile = Bundle.main.path(forResource: "SMSSpamCollection", ofType: "txt")  

//read words file  

let wordsFileText = try String(contentsOfFile: wordsFile!, encoding: String.Encoding.utf8)  

var wordsData = wordsFileText.components(separatedBy: .newlines)  

wordsData.removeLast() // Trailing newline.  

//read spam collection file  

let smsFileText = try String(contentsOfFile: smsFile!, encoding: String.Encoding.utf8)  

var smsData = smsFileText.components(separatedBy: .newlines)  

smsData.removeLast() // Trailing newline.  

let wordsInMessage = sms.split(separator: " ") 

 //create a multi-dimensional array  

let vectorized = try MLMultiArray(shape: [NSNumber(integerLiteral: wordsData.count)], dataType: MLMultiArrayDataType.double)  

for i in 0..  

let word = wordsData[i]  

if sms.contains(word){  

var wordCount = 0  

for substr in wordsInMessage{  

if substr.elementsEqual(word{  

wordCount += 1  

 let tf = Double(wordCount) / Double(wordsInMessage.count)  

var docCount = 0  

for sms in smsData{  

if sms.contains(word) {  

docCount += 1  

let idf = log(Double(smsData.count) / Double(docCount))  

vectorized[i] = NSNumber(value: tf * idf) 

 } else {  

vectorized[i] = 0.0  

return vectorized  

} catch {  

return MLMultiArray()  

以上代码得到文本框内输入信息的tfidf表征,为此读取SMSSpamCollection.txt原始数据库并返回同样信息。一旦你保存项目然后再次运行模拟器,你的app就会运行良好。

4、CoreML优缺点

像每个发展中的库一样,CoreML有优点也有缺点。让我们说清楚。

优点:

对在移动设备上运行性能进行优化,最小化内存和能量消耗。

在移动设备上运行保证了用户隐私,不再需要将数据发给服务器做预测。

在移动设备上运行意味着甚至在没联网的时候都可以做预测,此外对用户来说反应时间更短。

能自己决定在CPU还是GPU上运行(或者都有)。

因为它可以用CPU,所以你能在iOS模拟器上运行它(iOS模拟器不支持GPU)。

提供了很多模型,因为它能从其他主流机器学习框架中引入模型:

支持向量机(SVM)

树集成,如随机森林、提升树

线性回归和逻辑回归

神经网络:前向反馈、卷积、循环

如何在iPhone上建立第一个机器学习模型

缺点:

只支持有监督模型,不支持无监督模型和强化学习。

不支持模型在设备上再训练,只能做预测。

如果CoreML不支持某种层,你就不可以使用。目前还不能用自己的层扩展CoreML。

CoreML工具只支持少量训练工具的特定版本(竟然不支持tensorflow)。

不能看中间层的输出,只能得到预测结果。

只支持回归和分类(不支持聚类、排序、降维等)。

结语

本文中,我们学习了CoreML及应用它开发iPhone机器学习app。CoreML是一个较新的库,因此有自己的优点和缺点。有一个非常有用的优点是它在本地设备上运行,因此速度更快,保证数据隐私。但同时,它功能不全面,对数据科学家的需求考虑还不够周全。期待后续版本会改进。

如果你在某个步骤遇到困难,本文所有代码都在GitHub上。     

原文发布时间为:2017-10-13

本文作者:Happen,Chloe,笪洁琼,魏子敏编译

本文来自云栖社区合作伙伴“51CTO”,了解相关信息可以关注。