导读:本期聚焦于小伙伴创作的《如何在iOS中使用Create ML构建图像分类模型并集成到Vision框架?》,敬请观看详情。移动端图像识别往往面临模型体积大、集成门槛高的痛点。Create ML 是苹果推出的原生机器学习训练工具,配合 Vision 框架,可以在不需要深厚机器学习背景的情况下完成从数据准备到模型部署的全流程。这篇文章会围绕数据标注策略、Create ML 训练模板的选择、模型导出格式以及 Vision 请求的构建,给出一个完整的可落地方案。同时会对比不同数据集规模下模型的表现差异,并指出 Core ML 模型转换为 mlmodelc 之后如何通过 VNCoreMLRequest 完成实时分类。对于正在寻找非云端、低延迟图像识别方案的 iOS 开发者,这是一个可以直接上手的操作指南。

如何在iOS中使用Create ML构建图像分类模型并集成到Vision框架?

图像分类在移动端有着广泛的应用场景,比如物体识别、文档扫描分类、植物鉴别等。过去在 iOS 上实现这类功能通常需要依赖第三方深度学习框架,或者将图像上传至云端 API,既增加了延迟,也对用户隐私带来了挑战。苹果在 WWDC 2018 推出的 Create ML 工具显著降低了机器学习模型的构建门槛,而 Core ML 与 Vision 框架的深度结合则让模型推理变得异常简洁。本文将直接切入数据标注环节,从零构建一个花卉品种识别模型,并演示如何将其集成到 Vision 中以实现毫秒级的本地分类。

数据采集与标注策略

图像分类模型的性能上限由数据质量决定。在 Create ML 的语境下,数据组织方式会直接影响训练效率和最终精度。Create ML 支持两种常见的数据组织形式:按文件夹分类存放图片,或者通过 JSON 注解文件指定每张图片的标签。对于大多数场景,文件夹分类是最直观的选择——每个类别一个文件夹,文件夹名就是标签名。以花卉分类为例,目录结构可以这样设计:

FlowerDataset/
├── rose/
│   ├── rose_001.jpg
│   ├── rose_002.jpg
│   └── ...
├── tulip/
│   ├── tulip_001.jpg
│   ├── tulip_002.jpg
│   └── ...
└── sunflower/
    └── ...

标注的过程其实就是将每张图片放入对应文件夹,不需要额外格式转化。但这里要特别留意数据多样性和平衡性问题。如果某个类别的图片都是在白色背景下拍摄的,而实际应用场景中背景复杂,那么模型泛化能力会大打折扣。建议在拍摄或收集数据时,有意变换角度、光照条件、背景,甚至对图片做适度的旋转、裁剪、颜色调整等数据增强。Create ML 在训练时也可以自动进行数据增强,例如随机翻转、裁剪、改变亮度和对比度,但这些预处理并不能完全替代原始数据的多样性。

数据量的经验法则是每个类别至少 30 张图片,但如果类别间视觉差异较大,15 张有时也能得到一个可接受的初始模型。对于 10 个以下类别的项目,总数据集控制在 500 张以内通常就能训练出可用模型,且训练速度非常快。如果类别超过 30 个,则需要更多样本来防止欠拟合。此外,建议预留 20% 的数据作为验证集,Create ML 会自动随机划分,但手动检查划分结果可以避免验证集中出现泄漏(比如同一朵花的连拍照片同时出现在训练集和验证集)。

使用 Create ML 训练图像分类器

Create ML 提供了两种训练图像分类模型的接口:Swift Playgrounds 中的 Xcode Playground 以及 Create ML app。对于追求效率的开发者,Create ML app 的图形化界面可以直接拖入数据集,实时显示训练进度和结果评估,非常适合快速原型验证。打开 Create ML app,选择“Image Classification”模板,然后设置训练数据源,将之前准备好的 FlowerDataset 文件夹拖入即可。项目会自动识别文件夹名称作为标签,并在右侧面板展示类别的分布统计。

在训练参数设置方面,Create ML 提供了几种预设的迭代次数选项,默认会根据数据集大小自动调整。如果想获得更好的模型,可以适当增加最大迭代次数,但要防止过拟合。Create ML 会在训练结束时输出验证精度和混淆矩阵,通过这些指标可以快速判断模型是否需要增加数据或调整参数。当精度达到 85% 以上时,通常就足以满足演示型应用的需求。更高要求的场景可以通过集成后进一步测试来迭代。

完成训练后,Create ML 会生成一个 .mlmodel 文件,这是 Core ML 的标准模型格式。但直接使用 .mlmodel 部署到 Vision 框架时,模型会被编译成 .mlmodelc 格式。如果模型体积较大,首次加载可能会有延迟。一个实用的技巧是使用 MLModel.compileModel(at:) 方法提前编译,并将编译后的 .mlmodelc 文件打包在 app bundle 中,这样可以避免首次使用时的编译等待。更直接的是在 Create ML 导出时选择生成编译后的模型(.mlmodelc),在 Xcode 中拖入项目时,会自动识别。

下面是一个简单的训练代码示例,展示如何通过 Create ML 的 MLImageClassifier 类在 Playground 中训练:

import CreateML
import Foundation

let dataDir = URL(fileURLWithPath: "/Users/username/Desktop/FlowerDataset")
let model = try MLImageClassifier(trainingData: .labeledDirectories(at: dataDir))
let evaluation = model.evaluation(on: .labeledDirectories(at: dataDir)) // 实际应用宜用独立验证集
print("训练完成,误差: (evaluation.classificationError)")

let savePath = URL(fileURLWithPath: "/Users/username/Desktop/FlowerClassifier.mlmodel")
try model.write(to: savePath)

这种方式适合自动化训练流程,比如在持续集成环境中定期更新模型。

将 Core ML 模型集成到 Vision 框架

Vision 框架对图像分类有专门的支持,通过 VNCoreMLRequest 可以轻松地将 Core ML 模型封装为一个视觉请求。集成过程大致分为三步:加载模型、构造请求、处理结果。首先,将导出的 .mlmodel 文件添加到 Xcode 项目,Xcode 会自动生成对应的 Swift 接口类,类名通常与模型文件名一致(例如 FlowerClassifier)。接着,创建一个 VNCoreMLModel 实例,并为它创建一个 VNCoreMLRequest。最后,使用 VNImageRequestHandler 对输入图像执行请求,并在回调中获取分类结果。

一个常见的性能陷阱是在主线程上执行图像处理请求。尽管 Vision 框架本身会在后台线程执行推理,但如果传入的图像需要从摄像头缓冲区转换,或者后续的 UI 更新逻辑过于复杂,仍然可能造成卡顿。正确的做法是在一个串行队列上执行 VNImageRequestHandlerperform 方法,并在得到结果后切换到主线程更新 UI。此外,如果应用需要实时处理摄像头帧(比如每秒 15-30 帧),务必设置请求的 usesCPUOnly 为 false(默认为 false),以利用 GPU 加速。对于偶尔的单张图片识别场景,则几乎不需要做任何特殊优化。

下面的代码演示了一个完整的 Vision 分类流程,包括从 UIImage 到 CVPixelBuffer 的转换、请求的创建和结果解析:

import Vision
import CoreML

func classifyImage(_ image: UIImage) {
    guard let ciImage = CIImage(image: image) else { return }
    
    // 加载模型
    guard let model = try? VNCoreMLModel(for: FlowerClassifier().model) else {
        fatalError("模型加载失败")
    }
    
    let request = VNCoreMLRequest(model: model) { (request, error) in
        if let results = request.results as? [VNClassificationObservation],
           let topResult = results.first {
            print("预测: (topResult.identifier), 置信度: (topResult.confidence)")
            DispatchQueue.main.async {
                // 更新 UI
            }
        }
    }
    request.imageCropAndScaleOption = .centerCrop
    
    let handler = VNImageRequestHandler(ciImage: ciImage, orientation: .up)
    DispatchQueue.global(qos: .userInitiated).async {
        do {
            try handler.perform([request])
        } catch {
            print("识别失败: (error)")
        }
    }
}

需要注意,imageCropAndScaleOption 的选择会影响准确率。一般情况下,centerCrop 适合目标主体占比较大的图片,而 scaleFit 则保留了完整的图片内容但需模型适应空白区域。具体可用哪种模式需要根据训练时图像的规格来确定。如果训练图片是严格裁剪到目标对象的,那么使用 centerCrop 更合理;如果训练图片包含了较多背景且未均匀裁剪,则 scaleFit 可能更鲁棒。

从数据标注到训练再到集成,Create ML 与 Vision 框架的组合提供了一条简洁而高效的本地图像分类路径。开发者可以将更多精力集中在数据质量和业务场景上,而不用纠结于模型架构和底层推理引擎。当项目需求升级为更复杂的物体检测或语义分割时,Vision 同样提供了对应的请求类型和模型模板,整体集成思路保持一致,具有很好的扩展性。

create_ml图像分类Vision框架修改时间:2026-08-12 15:21:57

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。