2020年的苹果机器学习:有什么新鲜事?

2020-06-30 21:24:16

2020年是移动上的机器学习不再是炙手可热的新生事物的一年。在应用程序中添加某种类型的智能已经成为标准做法。

在这篇博客文章中,我将总结Core ML和其他来自苹果生态系统的AI和ML技术的新特性。

去年是Core ML的一次重大更新,但今年的改进要温和得多:一些新的层类型、对加密模型的支持,以及在CloudKit上托管模型更新的能力。

看来版本号掉了。去年的更新名为Core ML 3,但现在的名称只是没有编号的Core ML。然而,coem ltools确实升级到了版本4。

注意:内部mlmodel规范版本号现在是5,因此新型号将在Netron中显示为“Core ML v5”。

Convolution3DLayer、Pooling3DLayer、GlobalPooling3DLayer:它们对于处理视频数据特别有用,您现在可以使用Vision框架来实现这一点。(Core ML仍然不明确支持一维卷积,尽管您可以使用常规的2D卷积层来实现这一点。)。

ArgSortLayer:用于对输入张量进行排序。这将返回排序的索引,而不是实际的排序值。没有常规的排序层,但是您可以使用GatherLayer对argort输出中的元素进行重新排序。

SliceBySizeLayer:核心ML已经有几种类型的切片层。这允许您传入一个张量,该张量包含开始切片的索引;切片的大小始终是固定的。

这些层类型只能与规范版本5或更高版本一起使用,这意味着IOS 14和MacOS 11.0或更高版本。

在Core ML的早期版本中,您可以量化权重,但在加载模型时,它们将反量化为浮点。使用新的int8DynamicQuantize特性,权重保持为8位整数值,并且实际计算也是使用整数执行的。

使用INT8的计算有可能比浮点运算快得多,但我想知道这是否只是CPU的优势,而不是GPU的优势,因为GPU真的很喜欢浮点运算。也许即将到来的神经引擎更新将本机支持INT8操作。(苹果前段时间确实收购了Xnor.ai…)。

CPU上的核心ML现在还可以使用16位浮点操作,而不是32位浮点(在A11仿生和更高版本上)。正如在“探索SWIFT中的数值计算”视频中提到的,Float16现在是SWIFT的一流数据类型。由于CPU本身支持16位浮点数,Core ML的速度可以提高一倍以上!

注意:Core ML已经在GPU和神经引擎上使用了Float16,所以这只会在使用CPU时有所不同。

UpsampleLayer现在可以具有分数比例因子。在BILINEAR模式下,网格点的采样方式有新的选项(“对齐角点”)。这应该可以解决我在这篇博客文章中指出的大部分问题。

ReOrganeDataLayerParams有一个Pixel_Shuffle模式。这是另一种进行上采样的方法。以前,您可以使用几个置换和重塑图层来实现像素洗牌,但是现在内置它很酷。

TileLayer接受第二个输入张量,因此您可以动态指定重复次数。

设备上培训似乎没有变化:仍然只支持全连接和卷积层。CoreML框架中的MLParameterKey类现在有一个用于RMSprop优化器的配置选项,但是该选项当前没有列在NeuralNetwork.proto中。它可能会在以后的测试版中添加。

序列化模型。不知道这是干什么用的。这是一个“私人”定义,“如有更改,恕不另行通知或支持”。也许这是苹果在mlmodel中嵌入专有模型格式的一种方式?

现有应用程序无需发布应用程序更新,只需下载新版本的mlmodel文件即可。公平地说,这并不是一个新的想法,一些第三方供应商已经为此提供了SDK。自己建造这个也不是很难。使用苹果解决方案的好处是,模型可以托管在苹果云上。

因为您的应用程序中可能有多个模型,所以模型集合的新概念允许您将多个模型捆绑在一起,并且应用程序将一次更新所有模型。您可以在CloudKit仪表板上创建这些集合。

在应用程序中,您可以使用MLModelCollection类来下载和管理模型更新。WWDC视频显示了这方面的代码片段。

为了准备核心ML模型进行部署,现在Xcode中有一个create Model Archive按钮。这将写入一个.mlarchive文件。您可以将此版本的模型上载到CloudKit仪表板,然后将其放入模型集合中。(看起来mlarchive实际上只是一个包含mlmodel文件夹内容的压缩文件。)。

一个很好的特性是您可以将不同的模型集合部署到不同的用户。例如,iPhone上的摄像头与iPad上的摄像头不同,因此您可能希望创建一个型号的两个版本,并将一个版本发送给该应用程序的iPhone用户,另一个发送给iPad用户。

您可以为设备类别(iPhone/iPad/TV/Watch)、操作系统和版本、区域代码、语言代码和应用程序版本创建目标规则。

似乎没有按其他标准将用户分组的机制,例如A/B测试型号更新,或针对特定设备类型(如“iPhone X或更低版本”)。但是,您仍然可以手动完成此操作,方法是创建具有不同名称的集合,然后显式要求MLModelCollection在运行时按名称获取适当的集合。

部署新的型号版本并不总是立竿见影的。这款应用程序会在某个时候检测到有新的型号可用,并会自动下载并将其放入应用程序的沙盒中。但是您无法控制这种情况发生的时间和方式--例如,Core ML可能会在手机不使用时在后台执行下载。

正因为如此,将内置型号作为后备选项(例如同时处理iPhone和iPad的通用型号)发布您的应用程序是个好主意。

尽管这是一个方便的解决方案,而且您不必担心自己托管模型,但请记住,您的应用程序现在使用的是CloudKit。据我所知,模型集合确实计入您的存储配额,而下载模型计入您的网络流量配额。

注意:如果您想要对模型进行设备上的个性化,没有简单的方法可以将其与这个新的CloudKit更新功能结合起来。没有直接的方法可以将个性化模型学到的东西转移到新模型中,或者以某种方式组合这些模型。

到目前为止,有人真的很容易窃取您的Core ML模型并将其嵌入到自己的应用程序中。从iOS14/MacOS11.0开始,Core ML可以自动加密和解密模型,这样陌生人就不能再窥视您的mlmodel文件夹。无论是否使用新的CloudKit部署,您都可以使用加密。

Xcode加密编译后的模型mlmodel c,而不是原始的mlmodel文件。该模型始终以加密形式保存在用户设备上。只有当应用程序实例化模型时,Core ML才会自动解密它。此解密版本仅存在于内存中,不会以文件形式存储在任何地方。

首先,您需要一个加密密钥。好消息是您不需要自己管理这个密钥!现在,在Xcode的Core ML模型查看器中有一个Create Encryption Key按钮。单击此选项时,Xcode将生成与您的Apple Developer团队帐户关联的新加密密钥。不需要在CSR和钥匙链访问这一点上胡乱摆弄。🤪

此过程将创建一个新的.mlmodel key文件。这个密钥存储在苹果的服务器上,但您也可以获得一个本地副本,用于加密Xcode中的模型。您不需要也不应该将此加密密钥嵌入到您的应用程序中!

要加密Core ML模型,可以将--Encrypt YourModel.mlmodel key添加到模型的编译器标志中,或者,如果要使用CloudKit部署,则需要在创建模型存档时提供加密密钥。

要在应用程序实例化模型时对其进行解密,Core ML需要通过网络从苹果的服务器获取加密密钥,因此这显然需要网络连接。核心ML只需要在您第一次使用该模型时执行此操作。

当然,如果网络故障且加密密钥尚未下载,您的应用程序将无法实例化Core ML模型。因此,您应该使用新的YourModel.load()函数。它有一个完成处理程序,允许您响应加载错误。例如,modKeyFetch错误代码告诉您Core ML无法从Apple的服务器加载解密密钥。

非常酷的功能-如果你担心人们会窃取你的专有技术-而且很容易在你的应用程序中实现。

注意:根据这篇论坛帖子,加密的机型不能与设备个性化一起使用。合乎道理。

使用Core ML模型的iOS API没有太大变化。尽管如此,还是有一些有趣的事情需要指出。

如您所知,当您将mlmodel文件添加到项目中时,Xcode会自动生成一个SWIFT或Objective-C源文件,其中的类使模型更易于使用。这些生成的类中有几个更改:

默认的init()现在已弃用,因此写入let model=YourModel()将导致编译器警告。相反,可以使用YourModel(configuration:)或新的YourModel.load()方法,该方法允许您处理模型加载错误,如无法解密加密的模型。

如果您的模型在图像上工作,而不是必须处理CVPixelBuffer对象,您现在可以使用CGImage或本地PNG或JPG文件的URL创建YourModelInput对象,并对其进行预测。但是,这并不能让您设置cropAndScale方法或cropRect,所以如果您想更好地控制如何调整图像大小,这些新方法不是很有用。

一次在一个线程或一个调度队列上使用MLModel实例。这可以通过序列化对模型的方法调用,或者通过为每个线程和调度队列创建单独的模型实例来实现。

哎呀,我做这件事很内疚。🙈让我相信MLModel在内部使用串行队列来处理请求-但这可能不是真的,或者它可能已经改变了。不管怎样,最好从现在开始听从建议。

MLMultiArray有一个新的初始化(连接:Axis:DataType:)初始值设定项,它通过连接几个现有的多数组来创建一个新的多数组。除了指定的轴外,它们必须具有相同的形状,它们将沿着指定的轴连接。它看起来像是专门为对视频进行预测而添加的,就像Create ML中的新操作分类器模型一样。汉迪!

注意:MLMultiArrayDataType枚举现在具有静态的.float和.float64属性。不确定这些是用来做什么的,因为它已经有了.float32和.Double案例。贝塔故障?

Xcode现在显示了更多关于模型的信息,比如类标签和您添加到模型中的任何定制元数据。它还显示有关模型内部图层类型的统计信息。

有一个方便的交互式预览,可以让你在不必运行应用程序的情况下玩模型。您可以将图像、视频或文本拖放到此预览窗口中,并立即查看模型的预测。非常好!

现在,您还可以在操场上使用Core ML模型。Xcode将自动为它生成类,您可以照常使用它。这是在将模型放入应用程序之前可以交互操作模型的另一种方式。

对于简单的项目来说,使用create ML构建您自己的模型很有趣,但是使用TensorFlow或PyTorch进行培训要常见得多。要将这样的模型与Core ML一起使用,您需要首先将其转换为mlmodel文件格式。这就是coemltools的作用。

好消息:文档大大改进了。你应该去看看。我们希望他们能让这本用户指南保持最新,因为旧的文档并不总是最新的版本。

注:不幸的是,Jupyter笔记本的例子已经消失了。这些示例现在是用户指南的一部分,但不再作为笔记本。

转换模型的方式已经发生了相当大的变化。旧的神经网络转换器几乎已经过时,取而代之的是一种更新、更灵活的设计。

用于TensorFlow(1.x和2.x)、tf.keras和PyTorch的现代转换器。所有这些转换器都构建在相同的堆栈上,并使用称为MIL或模型中间语言的东西。对于这些类型的模型,您不再需要使用tfcoreml或onnx-coreml。

用于Kera 1.x、Caffe和ONNX神经网络的旧转换器。这些都有自己的专用转换器。这些不会进一步开发,只会得到错误修复。不推荐再使用ONNX转换PyTorch模型!

要转换TensorFlow 1.x或2.x、PyTorch或tf.keras模型,可以使用新的统一转换API。它看起来是这样的:

将核心工具导入为ctclass_labels=[";cat";,";]image_input=ct.ImageType(Shape=(1,224224,3),Bias=[-1,-1,-1],Scale=2/255.)MODEL=ct.Convert(KERAS_MODEL,INPUTS=[IMAGE_INPUT],classifier_config=ct.ClassifierConfig(class_labels))model.save(";YourModel.mlmodel";)。

ct.Convert()函数检查模型文件以查看其格式,并自动选择适当的转换器。参数与以前有所不同:预处理参数使用imageType对象传入,分类器标签使用SorfierConfig对象传入,依此类推。

这个新的转换API将模型转换为称为MIL的中间表示。目前有TensorFlow 1.x到MIL的转换器、TensorFlow 2.x到MIL的转换器(包括tf.keras)和PyTorch到MIL的转换器。如果一个新的深度学习框架在某个时候变得流行起来,它可以得到自己的MIL转换器。

一旦模型为MIL格式,就可以根据一般规则进行优化,例如剥离不必要的操作或将不同的层融合在一起。最后,将其从MIL转换为mlmodel格式。

我还没有详细研究过它,但是这种新的方法让我相信coem ltools 4生成的mlmodel文件比以前要高效得多,特别是对于TF2.x图形。

我喜欢MIL的原因是它允许您告诉转换器如何处理它还不理解的层。如果您的模型具有Core ML不直接支持的层,则可以将其拆分为更原始的MIL操作,如矩阵乘法或其他算术。

然后,只要遇到该类型的层,转换器就可以使用这种所谓的“复合操作”。这比使用自定义层实现不受支持的操作要容易得多,尽管这仍然是可能的。文档中有一个很好的示例来说明如何使用这种复合操作。

iOS和MacOSSDK中有几个执行机器学习相关任务的高级框架。让我们快速看一看这里有什么新东西。

视觉已经有了人脸、人脸地标和人体的检测模型。此新版本增加了以下功能:

事实上,苹果在操作系统中加入姿势估计功能真的很酷。有几个开源模型可以做到这一点,但它们并不是很好,或者速度很慢,而商业解决方案很昂贵。现在您可以免费获得高质量的身体姿势检测!

除了只看静态图像,现在还更强调从视频中检测东西,无论是离线检测还是从摄像头实时检测。为方便起见,您可以将摄像机中的CMSampleBuffer对象直接与请求处理程序一起使用。

新的是VNStatefulRequest,它是VNImageBasedRequest的一个子类,它会随着时间的推移建立证据,证明已经检测到您正在寻找的东西。与典型的VNImageBasedRequest不同,您可以在多个帧上重用有状态请求。它每N帧视频执行一次分析操作。

一旦观察到您要寻找的东西,就会用VNObservation对象调用完成处理程序,该对象现在有一个timeRange属性,告诉您视频中观察的开始和停止时间。

您不能直接使用VNStatefulRequest-它是一个抽象基类,当前仅由VNDetectTrajectoriesRequest子类来进行轨迹检测。这可以检测沿抛物线路径移动的形状,如踢球或扔球。(这似乎是目前唯一的内置视频任务。)。

如果需要离线分析视频,可以使用VNVideoProcessor。此对象获取本地电影文件的URL,并每隔N帧或每秒执行一个或多个Vision请求。

用于分析视频的一种重要的传统计算机视觉技术是光流。Vision现在具有VNGenerateOpticalFlowRequest,它可以计算每个像素从一帧移动到下一帧的方向(密集光流)。输出是一个VNPixelBufferObservation,其中包含一个新图像,每个像素有两个32位或16位浮点数。

另一个新功能是VNDetectConoursRequest,用于检测图像中对象的轮廓。这些轮廓作为矢量路径返回。VNGeometryUtils具有辅助函数,用于对检测到的等高线进行后处理,例如将其简化为基本几何形状。

Vision中的最后一个新功能是内置特征提取器VisionFeaturePrint的新变体。iOS已经附带了VisionFeaturePrint.Scene,它对制作图像分类器很有用。现在有了一个新的VisionFeaturePrint.Object模型,该模型针对提取对对象检测有用的特征进行了优化。

它处理一幅299×299的输入图像,并分别输出两个多形状阵列(288,35,35)和(768,17,17)。这些还不是边界框预测,只是“原始”特征。全对象检测器仍然需要添加逻辑来将这些功能转换为边界框和类标签。当您使用转移学习训练对象检测器时,Create ML就会做到这一点。

对于NLP任务,您可以使用自然语言框架。它与经过Create ML培训的模型紧密合作。

NLTagger和NLModel现在可以找到多个标签并预测它们的可信度。之前,你得到的只是最高分的标签。

句子嵌入。本来可以使用单词嵌入,但现在NLEmbedding也支持句子。

句子嵌入使用内置的神经网络将整个句子编码成512维向量,以便捕捉单词出现在句子中的上下文(这是单词嵌入本身无法做到的)。

从iOS 11.3和Metal Performance Shaders框架开始,我们就可以使用Apple API训练模型。多年来,我们添加了新的训练API,今年我们又增加了几个-据我统计,我们现在有7个不同的API,用于在iOS和/或MacOS上训练神经网络!

目前,您可以在iOS和MacOS上使用以下Apple API来训练机器学习模型,特别是神经网络:

Create ML:您可能知道这是一款应用程序,但它也是MacOS上可用的框架。

金属性能着色器:用于GPU上的推理和培训。这实际上是两个不同的API,如果您不熟悉Metal,它们不是特别容易使用。现在还有一个新的“金属性能着色器图表”框架,似乎可以替代这些旧的API。

BNNS:Accelerate框架的一部分。以前,BNNS只有做推理的例程,但今年它增加了对培训的支持。

Turi Create:基本上是Create ML的Python版本。它不会上厕所。

..