Introduction
我的数据科学家是一个梦想 - 我可以看到顶尖的科技公司在我工作的地区附近推出产品。
如果您看到最近的Apple iPhone X发布活动,iPhone X附带了一些非常酷的功能,如FaceID,Animoji,开箱即用的增强现实,它们利用了机器学习的强大功能。我的黑客想弄脏手,弄清楚构建这样的系统需要什么?
当进一步探讨时,答案是CoreML,它是Apple为开发人员提供的官方机器学习工具包。它适用于iPhone,Macbook,Apple TV,Apple手表,简而言之,适用于所有Apple设备。
另一个有趣的消息是Apple已经设计了一个定制的GPU和一个先进的处理芯片A11 Bionic,带有针对机器学习优化的神经引擎 在最新的iPhone
“凭借强大的计算引擎的核心,iPhone现在将开放新的机器学习途径,而CoreML的重要性只会在未来几天内上升。”
在本文结束时,您将看到Apple CoreML是什么以及为什么它正在获得动力。我们还将通过为iPhone构建消息垃圾邮件分类应用程序来查看CoreML的实现细节。
我们将通过客观地看待相同的利弊来完成文章。
目录
- 什么是CoreML?
- 设置系统
- 案例研究:为iPhone实施垃圾邮件分类器应用程序
- 使用CoreML的优点和缺点
1.什么是CoreML?
Apple今年在其年度开发者大会WWDC(相当于谷歌I / O大会)上推出了CoreML,并进行了大量宣传。为了更好地理解CoreML的角色,我们必须了解一些上下文。
CoreML的一个小环境
有趣的是,这并不是Apple第一次在其设备上推出机器学习框架。去年,它推出了一系列相同的库:
- 加速和基本神经网络子程序(BNNS) - 使用卷积神经网络有效地利用CPU进行预测。
- 金属性能着色器CNN(MPSCNN) - 使用卷积神经网络有效地利用GPU进行预测。
不同之处在于,一个针对CPU进行了优化,另一个针对GPU进行了优化。其原因有时在推理期间CPU可能比GPU快。虽然在训练期间几乎每次GPU都更快。
这些多个框架在开发人员之间造成了很多混乱,因为它们非常接近硬件(为了高性能),所以很难编程。
输入CoreML
CoreML提供了前两个库的另一个抽象层,并提供了一个简单的界面来实现相同的效率。 另一个好处是CoreML在您的应用程序运行时负责CPU和GPU本身之间的上下文切换。
“也就是说,例如,你有一个内存繁重的任务,涉及处理文本(自然语言处理),CoreML将自动在CPU上运行它,而如果你有计算繁重的任务,如图像分类,它将使用 GPU。如果你的应用程序中同时具备这两种功能,它也会自动处理这些功能,以便你可以充分利用这两个世界。“
CoreML还提供了什么?
CoreML还附带了三个基于它的库:
- 愿景:提供高性能图像分析和计算机视觉技术的图书馆,用于识别人脸,检测特征,并对图像和视频中的场景进行分类。
- Foundation(NLP):顾名思义,它是一个提供自然语言处理功能的库。
- 游戏套件:用于游戏开发的库也提供相同的AI,使用决策树。
所有上述库,都非常易于使用,并提供了一个简单的界面来完成一堆任务。 使用上面的库,CoreML的最终结构看起来像这样
请注意,上述设计为您的iOS应用程序提供了一个很好的模块化结构。 对于不同的任务,您有不同的层,您可以通过各种方式使用它们(例如,在应用程序中使用带有图像分类的NLP)。 您可以在这里阅读有关这些库的更多信息:Vision,Foundation和GameplayKit。 嗯,这就是现在的理论,现在是时候弄清楚了!
2.设置系统
要充分利用CoreML,您需要设置以下要求:
- 操作系统:MacOS(Sierra 10.12或更高版本)
- Python 2.7和pip:你可以从这里下载python for mac。 要安装pip,请打开终端并使用以下代码
sudo easy_install pip
- 1 coremltools:这个包有助于将模型从python转换为CoreML可以理解的格式。 要再次安装,请打开终端并执行此操作
sudo pip install -U coremltools
Xcode 9:这是用于为Apple设备构建应用程序的默认软件。 你可以在这里下载。 要下载Xcode,您必须先使用Apple ID登录。
登录后,您必须验证您的苹果ID。 您将在使用Apple ID注册的设备上收到有关该通知的通知。
选择“允许”并在网站中键入给定的6位数密码
执行此步骤后,您将看到一个下载选项,您可以从那里下载Xcode。 现在我们已经建立了我们的系统,所有准备工作都转到了实施部分!
3。案例研究:为iPhone实施垃圾邮件分类器
我们将通过构建它们来研究利用CoreML的强大功能的两种重要方法。 让我们开始吧!
将您的机器学习模型转换为CoreML格式
现在,CoreML的优势之一,或者我应该说它的创建者明智的决定是支持转换训练的机器学习模型,这些模型建立在其他流行的框架中,如sklearn,caffe,xgboost等。
“这并没有疏远数据科学界尝试使用CoreML,因为他们可以在他们喜欢的环境中进行实验,训练他们的模型,然后只需将其导入iOS / MacOS应用程序即可使用。”
以下是CoreML支持的框架:
什么是mlmodel?
为了简化转换过程,Apple设计了自己的开放格式来表示名为mlmodel的跨框架机器学习模型。 此模型文件包含模型中图层的描述,输入和输出,类标签以及需要对数据执行的任何预处理。 它还包含所有学习参数(权重和偏差)。
转换流程如下所示:
- 在您最喜欢的框架中训练模型
- 使用coremltools python包将模型转换为.mlmodel
- 在您的应用中使用该模型
对于此示例,我们将在sklearn中构建垃圾邮件分类器,然后将相同的模型移植到CoreML。
关于垃圾邮件收集数据集
SMS垃圾邮件收集v.1是一组公共短信标记的邮件,已收集用于手机垃圾邮件研究。 它有一个由5,574个英文,真实和非编码信息组成的集合,根据合法(火腿)或垃圾邮件进行标记。
您可以从here下载数据集。
构建一个基本模型
我们将使用sklearn中的LinearSVC构建一个基本模型。 另外,我在消息文本中使用TF-IDF作为模型的一个功能。 TF-IDF是一种在自然语言处理中使用的技术,它有助于根据唯一标识文档而非其他文档的单词对文档进行分类。 如果您想了解有关NLP和tf-idf的更多信息,请阅读本文。 这将是代码:
import numpy as np
import pandas as pd
#Reading in and parsing data
raw_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 test
sms_data = np.array(sms_data)
X = sms_data[:, 1]
y = sms_data[:, 0]
#Build a LinearSVC model
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.svm import LinearSVC
#Build tf-idf vector representation of data
vectorizer = TfidfVectorizer()
vectorized_text = vectorizer.fit_transform(X)
text_clf = LinearSVC()
text_clf = text_clf.fit(vectorized_text, y)
这构建了我们的模型。 让我们用垃圾邮件测试它,
#Test the model
print 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 - Validation
from sklearn.model_selection import cross_val_score
cross_score = cross_val_score(text_clf, vectorized_text, y, cv=10)
print cross_score
print "mean:",np.mean(cross_score)
现在我们已经构建了模型,我们需要将其移植到.mlmodel格式,以使其与CoreML兼容。 我们将使用之前安装的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")
这里发生了什么?
我们首先在python中导入coremltools包。 然后我们使用其中一个转换器来转换我们的模型,在这种情况下,我们使用了** converters.sklearn **,因为我们必须转换一个sklearn内置的模型。 然后,我们在.convert()中传递模型对象,输入变量名和输出变量名。 然后我们设置模型的参数以添加关于输入,输出的更多信息,最后调用.save()来保存我们的模型文件。
如您所见,模型文件显示有关模型类型,输入和输出,类型等的详细信息。我在上图中突出显示了所有这些信息。您可以将描述与我们在转换为.mlmodel时提供的描述相匹配。
这就是将模型导入CoreML是多么容易。现在你的模型正在进入Apple生态系统,那就是真正的乐趣开始的时候!
注意:此步骤的完整代码文件可以在这里找到 。阅读更多关于coremltools 这里和不同类型的转换器这里。
将模型与我们的应用程序集成
现在我们已经训练了我们的模型并将其移植到CoreML,让我们使用该模型并为iPhone构建垃圾邮件分类器应用程序!
我们将在模拟器上运行我们的应用程序。模拟器是一种软件,可以显示应用程序的外观和工作方式,就好像它实际上是在手机上运行一样。这节省了大量时间,因为我们可以在实际手机上尝试应用之前尝试使用我们的代码并修复所有错误。看看最终产品会是什么样子:
Downloading the project
I have already built a basic UI for our app and it is available on GitHub. Use the following commands to get it up and running:
git clone https://github.com/mohdsanadzakirizvi/CoreML-on-iPhone.git
cd CoreML-on-iPhone/Practice\ App/
open coreml\ test.xcodeproj/
This will open our project using Xcode.
我在Xcode窗口中突出显示了三个主要区域:
- 左上角的播放按钮用于在模拟器上启动应用程序。
- 在播放按钮下方是显示与我们项目相关的文件和文件夹。 这称为项目导航器,它可以帮助您在项目的文件和文件夹之间导航。
- 接下来,在播放按钮上写入iPhone 8 Plus,这表示您要测试模拟器的目标设备。 您可以单击它并从下拉列表中选择iPhone 7
让我们首先运行我们的应用程序,看看会发生什么。 单击左上角的播放按钮,将在模拟器中运行我们的应用程序。 尝试在框中键入一些文本,然后单击“预测”按钮。 怎么了?
就目前而言,我们的应用程序并没有做太多的事情,它只是打印出框中输入的内容。
在您的应用中添加预先训练的模型
这一点相当容易,
将.mlmodel文件拖到项目导航器窗格中的Xcode窗口中。
执行此操作时,将弹出一个窗口,其中包含一些选项,默认选项为“完成”。
将此类文件拖到Xcode中时,它会自动创建对项目中文件的引用。 这样您就可以在代码中轻松访问该文件。
以下是整个过程供参考:
编译模型
在我们开始从模型中推断之前,我们需要告诉Xcode在构建阶段编译模型。 为此,请遵循以下步骤:
- 在项目导航器窗格中,选择带有蓝色图标的文件
- 这将打开右侧的项目设置。 单击Compile Sources并选择+图标。
- 在出现的窗口中,选择SpamMessageClassifier.mlmodel文件,然后单击“添加”。
现在每次运行我们的应用程序时,Xcode都会编译我们的机器学习模型,以便它可以用于进行预测。
在代码中使用模型
任何为Apple设备开发的应用程序都是以swift编程的。 为了学习本教程,您不需要学习swift,但如果之后它对您感兴趣并且您希望更深入,那么您可以按照本教程进行操作。
-
在项目导航器窗格中,选择ViewController.swift。 这是包含控制我们应用程序功能的大部分代码的文件。
-
查看第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并返回相同的内容。 保存程序并重新运行模拟器后,您的应用程序现在应该正常运行。
4. CoreML的优点和缺点
像开发中的每个图书馆一样,它有其优点和缺点。 让我们明确说明一下。
优点
针对设备性能进行了优化,可最大限度地减少内存占用和功耗。
设备上意味着用户数据的隐私,您不再需要将数据发送到服务器进行预测。
设备上意味着功能预测,即使没有互联网连接,也不会减少用户的响应时间。
它决定自己是在CPU还是GPU(或两者)上运行模型。
因为它可以使用CPU,所以可以在iOS模拟器(不支持GPU)上运行它。
它支持许多模型,因为它可以从其他流行的机器学习框架导入模型:
支持向量机(SVM)
树丛,如随机森林和匍匐树木
线性回归和逻辑回归
神经网络:前馈,卷积,复发
Cons
对监督模型的原生支持仅不支持无监督或强化学习。
没有设备培训,只有推理(预测)。
如果CoreML不支持某种图层类型,则无法使用它。目前无法使用您自己的图层类型扩展Core ML。
核心ML转换工具仅支持有限数量的培训工具的特定版本(没有张量流,什么??)
你不能看中间层产生的输出,你只能得到预测。
仅支持回归和分类(不支持聚类,排名,降维等)
结束笔记
在本文中,我们了解了更多有关CoreML及其在构建iPhone机器学习应用程序中的应用。 CoreML是一个相对较新的库,因此有各自的优缺点。这里提供的一个非常有用的功能是它在本地设备上运行,从而提供更快的速度并提供数据隐私。与此同时,它还不能被认为是一个成熟的数据科学家友好的库。我们将不得不等待,看看它在即将发布的版本中是如何发展的。
对于那些陷入困境的人来说,本文的所有代码都是可在GitHub上获得。
此外,如果您想更深入地探索CoreML,这些是一些资源:
CoreML Documentation
WWDC 2017 Video Session – Core ML in depth
Introduction to Core ML: Building a Simple Image Recognition App