如何在你的iPhone上建立第一个机器学习模型(Apple最新CoreML框架入门)


大数据文摘作品

作者:MOHD SANAD ZAKI RIZVI

编译:Happen,Chloe,笪洁琼,魏子敏


引言


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


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


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


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


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


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


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




文章目录:

1.CoreML是什么?

2.建立系统

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

4.使用CoreML的利弊


01

CoreML是什么?




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


CoreML的背景


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


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


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


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


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


走进CoreML




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


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




CoreML还将提供什么?


CoreML顶层还附带了三个库:


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


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


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


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




注意,上述设计给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进行登陆。




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




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




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


03

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


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


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


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


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


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




Mlmodel是什么?


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


转换流程如下:


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

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

3.在app中使用模型




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


关于垃圾短信数据集


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




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


建立基础模型


我们使用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格式的模型文件。




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




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


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


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


将该模型用于我们的app


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


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




下载工程


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


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


cd CoreML-on-iPhone/Practice\ App/


open coreml\ test.xcodeproj/


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




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


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

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

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


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




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


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


相当简单:


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

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

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


这里是所有步骤,以供参考:




编译模型


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


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




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


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




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


在代码中创建模型


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


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




第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")  

do {            

//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..<wordsData.count{                

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就会运行良好。


04

CoreML优缺点


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


优点:


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


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


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


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


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


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


支持向量机(SVM)


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


线性回归和逻辑回归


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




缺点:


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


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


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


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


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


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


结语


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


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

原文地址:https://www.analyticsvidhya.com/blog/2017/09/build-machine-learning-iphone-apple-coreml/



本文由机器之心经授权转载自大数据文摘,禁止二次转载。

工程
登录后评论
暂无评论
暂无评论~
返回顶部