Core ML:在 Apple 设备上集成机器学习
Core ML 入门:将机器学习融入你的 Apple 应用
Core ML 是 Apple 推出的高性能机器学习框架,能够让你将训练好的模型无缝集成到 iOS、macOS、watchOS 和 tvOS 应用中。它针对设备端的低延迟与隐私保护进行了极致优化,无需依赖网络连接即可执行预测。本教程将带你从零开始,理解 Core ML 的核心概念,学会转换模型,并在 App 中完成一次完整的图像分类。
Core ML 的核心优势
在移动端运行机器学习,通常会面临计算力、电量和私密性的多重挑战。Core ML 的设计恰好解决了这些问题:
- 完全设备端运行:所有推断都在本地完成,数据不会离开用户的设备。这对于处理敏感信息(如照片、健康数据)至关重要。
- 极致的性能优化:自动利用 CPU、GPU 和神经网络引擎(Apple Neural Engine,ANE)。你无需手动选择计算单元,Core ML 会在运行时动态调度,兼顾速度与能效。
- 低延迟体验:无网络往返,预测近乎瞬时响应,适合相机实时滤镜、语音指令等场景。
- 与生态深度整合:通过 Swift 的强类型接口调用模型,支持 Vision、Natural Language、SoundAnalysis 等系统框架直接消费 Core ML 模型,开发体验高度一致。
- 模型即 .mlmodel:一种跨 Apple 平台的通用格式,通过 Xcode 编译后进一步优化为
.mlmodelc,体积更小,加载更快。
Core ML 工作流概览
一个典型的集成过程包含三个步骤:
- 获取并训练模型 – 在服务器端或第三方工具(如 Create ML、TensorFlow、PyTorch)中训练模型。
- 转换为 Core ML 格式 – 使用 Core ML Tools 将训练好的模型转换为
.mlmodel文件。 - 导入 Xcode 并集成 – 将模型拖入 Xcode 项目,Swift 会自动生成一个代码接口,直接调用即可。
下面我们深入每个环节。
第一步:准备机器学习模型
如果你是机器学习初学者,最快捷的方式是使用 Apple 的 Create ML。这是一个无需代码的模型训练工具,内置于 Xcode 的 Playground 或独立的 macOS 应用中。你可以利用它直接训练图像分类器、文本分类器、推荐系统等,并一键导出 .mlmodel。
对于已有模型,Core ML 支持以下常见来源:
- TensorFlow(
SavedModel、HDF5、Keras) - PyTorch(通过
torch.jit.trace导出为 TorchScript) - scikit-learn(分类、回归、聚类等模型)
- XGBoost、LibSVM 等
无论模型来自何处,最终都需要一个能够被 Core ML 理解的描述:模型架构、权重以及元数据(输入输出名称、类型等)。
第二步:使用 Core ML Tools 转换模型
Core ML Tools 是一个 Python 包,负责将各类模型转换为 .mlmodel。你可以在 macOS 或 Linux 上安装它:
pip install coremltools
以下以转换一个 Keras 图像分类模型为例:
import coremltools as ct
import tensorflow as tf
# 假设你已经训练了一个 Keras 模型
keras_model = tf.keras.applications.MobileNetV2(weights='imagenet')
# 转换成 Core ML 模型
coreml_model = ct.convert(
keras_model,
inputs=[ct.ImageType(name="input_image", shape=(1, 224, 224, 3))],
classifier_config=ct.ClassifierConfig(class_labels)
)
# 设置元数据(对用户可见的模型描述)
coreml_model.author = "你的名字"
coreml_model.short_description = "基于 MobileNetV2 的图像分类器"
coreml_model.version = "1.0"
# 保存
coreml_model.save("ImageClassifier.mlmodel")
转换 PyTorch 模型的流程类似,先通过 torch.jit.trace 获取跟踪图,再使用 ct.convert。
关键点在于输入类型声明:对于图像,推荐使用 ImageType,这样模型会自动接收系统解码后的像素缓冲区,并支持 Vision 框架的预处理。对于多维数组、序列等,则使用 TensorType。
你还可以在转换时指定 compute_units 来约束运行时计算设备(所有单元、仅 CPU 和 GPU、仅神经网络引擎等),但通常保留默认的自动选择即可。
第三步:将模型集成到 Xcode 项目
拿到 .mlmodel 文件后,集成过程极其简单:
- 拖入模型文件至 Xcode 项目导航器。
- Xcode 会自动在项目的 Target 中生成对应的 Swift 类。例如,名为
ImageClassifier的模型会生成ImageClassifier类,包含init()和prediction(input:)方法。 - 调用模型进行预测。
一个完整的图像分类示例(使用生成的接口和 Vision 框架):
import UIKit
import CoreML
import Vision
class ViewController: UIViewController {
// 懒加载生成的模型实例
private lazy var classificationRequest: VNCoreMLRequest = {
do {
let model = try VNCoreMLModel(for: ImageClassifier().model)
let request = VNCoreMLRequest(model: model) { request, error in
self.processClassifications(for: request, error: error)
}
request.imageCropAndScaleOption = .centerCrop
return request
} catch {
fatalError("无法加载模型: \(error)")
}
}()
func classifyImage(_ image: UIImage) {
guard let ciImage = CIImage(image: image) else { return }
let handler = VNImageRequestHandler(ciImage: ciImage)
DispatchQueue.global(qos: .userInitiated).async {
do {
try handler.perform([self.classificationRequest])
} catch {
print("请求失败: \(error)")
}
}
}
private func processClassifications(for request: VNRequest, error: Error?) {
guard let results = request.results as? [VNClassificationObservation],
let topResult = results.first else { return }
DispatchQueue.main.async {
print("分类: \(topResult.identifier), 置信度: \(topResult.confidence)")
}
}
}
代码解读:
VNCoreMLModel是 Vision 与 Core ML 的桥梁,它会自动将CIImage缩放并裁剪为模型需要的尺寸。VNImageRequestHandler负责执行请求,可以传入CGImage、CIImage、CVPixelBuffer或Data。- 预测结果在回调中返回,
VNClassificationObservation携带标签和置信度。对于回归或多数组输出,会使用VNCoreMLFeatureValueObservation或直接使用 Core ML 原生 API(model.prediction(from:))。
原生 Core ML API 调用
如果你不想依赖 Vision,也可以直接使用生成的模型类。这种方式适用于处理非图像数据(如传感器数值、文本向量等)。
let model = ImageClassifier()
// 假设模型要求输入一个 (1, 224, 224, 3) 的 MLMultiArray
let input = try! MLMultiArray(shape: [1, 224, 224, 3], dataType: .float32)
// 填充 input 的数据...
let output = try! model.prediction(input: ImageClassifierInput(input_1: input))
print(output.classLabel)
生成的输入输出类均为强类型,开发时即可享受代码补全和安全检查。
模型优化与性能提示
- 模型量化:使用 Core ML Tools 转换时,可以通过
ct.convert(..., compute_units=..., minimum_deployment_target=...)指定量化级别(如float16、int8)。在 Apple 设备上,神经网络引擎对float16支持极好,模型大小减半且几乎无损精度。 - 使用更新后的模型格式:确保部署目标不低于 iOS 13 / macOS 10.15,以使用
mlprogram格式,它支持控制流和更灵活的算子。 - 按需加载:避免在
App启动时加载所有模型。在需要预测前再初始化,并考虑缓存已加载的模型。 - 后台线程:预测操作可能会占用计算资源,务必在后台队列执行,避免阻塞主线程。
- 利用 Xcode 的 Core ML 性能报告:运行 App 时,Xcode 的调试导航器中会显示模型推理耗时和计算单元使用情况,帮助你定位瓶颈。
支持的操作与限制
Core ML 覆盖了大量常见的机器学习运算,但并非所有 TensorFlow/PyTorch 算子在转换时都能完美映射。遇到不支持的算子时:
- 检查 Core ML Tools 的版本,最新版持续增加对新算子的支持。
- 考虑使用
ct.convert的convert_to参数尝试mlprogram格式,它支持更多动态操作。 - 重写模型图,将不被支持的子图用 Core ML 内置算子替代。
- 对于极复杂的模型(如 GPT 类大型语言模型),当前 Apple 推荐通过
MLTensor和MLComputePlan等新特性进行优化,但这些已超出入门范畴。
进阶方向
- 模型个性化与更新:利用 Core ML 的
MLUpdateTask在设备端进行模型微调,无需将用户数据上传。 - 模型加密:Xcode 允许给
.mlmodel添加加密,防止未授权的查看或篡改。 - Core ML 与 Metal 协作:性能极致优化时,可以编写自定义 Metal 着色器与 Core ML 模型协同工作。
- 模型打包与分发:将多个模型合并为一个
MLModelCollection,通过云端按需下载。
常见问题(FAQ)
问:Core ML 模型必须联网才能更新吗?
答:不需要。模型以文件形式打包在 App 内,更新模型需发布 App 新版本;或者通过 CloudKit 或自定义下载方式获取新的 .mlmodelc,应用内动态加载。
问:我的模型太大(超过 100 MB),会导致 App 体积超标吗?
答:可以。App Store 对二进制文件大小有限制,但可以通过按需资源(On-Demand Resources)将模型放在服务器,首次使用时下载。此外量化能显著减小模型体积。
问:如何调试模型输出不准确的问题?
答:首先确保预处理步骤(如图像缩放、均值/方差归一化)与训练时完全一致。Core ML Tools 转换时可以指定 image_scale 和 bias 等参数来匹配。在 Xcode 中可运行单元测试,对比同一输入在原始框架和 Core ML 上的输出差异。
总结
Core ML 让 Apple 平台上的机器学习集成变得前所未有的简单。从 Create ML 的零代码训练,到 Core ML Tools 的一键转换,再到 Swift 中安全、高效的 API,整个工作流清晰且紧密贴合 Apple 生态。掌握它,你就能在 App 中创造出智能、私密且流畅的体验。
现在,打开 Xcode,试着将你的第一个模型拖入项目,感受设备端智能的即时效能吧。