MK
摩柯社区 - 一个极简的技术知识社区
AI 面试

Objective-C与机器学习(Core ML)基础应用

2023-04-177.3k 阅读

Objective-C 与 Core ML 环境搭建

在开始使用 Objective-C 与 Core ML 进行开发之前,我们需要确保开发环境已经正确搭建。

安装 Xcode

首先,你需要从 Mac App Store 下载并安装 Xcode。Xcode 是苹果官方的集成开发环境(IDE),用于开发 macOS、iOS、watchOS 和 tvOS 应用程序。它包含了编译器、调试器以及各种开发工具,同时也内置了对 Core ML 的支持。

创建 Objective-C 项目

打开 Xcode 后,选择 “Create a new Xcode project”。在模板选择界面中,根据你的目标平台(如 iOS 或 macOS)选择相应的应用程序模板,这里我们以 iOS 应用为例。在项目设置页面,填写项目名称、组织标识符等信息,并确保选择 “Objective-C” 作为项目的编程语言。

导入 Core ML 框架

创建好项目后,我们需要导入 Core ML 框架。在项目导航器中,选择你的项目,然后在 “General” 标签下的 “Frameworks, Libraries, and Embedded Content” 部分,点击 “+” 号。在弹出的搜索框中输入 “Core ML”,然后选择 “Core ML.framework” 并点击 “Add”。这样就将 Core ML 框架成功添加到了项目中。

Core ML 模型简介

Core ML 是苹果推出的一个用于在 iOS、macOS、watchOS 和 tvOS 上运行机器学习模型的框架。它允许开发者轻松地将预训练的机器学习模型集成到自己的应用程序中,而无需深入了解机器学习的复杂算法和实现细节。

Core ML 模型格式

Core ML 模型以 .mlmodel 格式存储,这种格式经过优化,可以在苹果设备上高效运行。模型可以通过多种方式获得,例如使用苹果的 Create ML 工具在本地创建,或者从第三方来源下载经过转换的模型。

模型结构

一个 Core ML 模型通常包含输入层、中间层(如神经网络的隐藏层)和输出层。输入层接收数据,中间层对数据进行一系列的计算和转换,最终输出层产生预测结果。例如,一个图像分类模型的输入层可能接收一张图片,中间层通过卷积神经网络对图片进行特征提取,输出层则给出图片属于各个类别的概率。

在 Objective-C 中使用 Core ML 进行简单预测

加载 Core ML 模型

假设我们有一个简单的线性回归 Core ML 模型,用于预测房屋价格。首先,我们需要在 Objective-C 代码中加载这个模型。

#import <CoreML/CoreML.h>

// 加载 Core ML 模型
NSError *error;
YourModelName *model = [[YourModelName alloc] initWithConfiguration:[[MLModelConfiguration alloc] init] error:&error];
if (error) {
    NSLog(@"Error loading model: %@", error);
    return;
}

在上述代码中,YourModelName 是你实际的 Core ML 模型类名,它是在导入模型到 Xcode 时自动生成的。MLModelConfiguration 可以用于设置模型的一些运行时配置,如计算精度等。

准备输入数据

接下来,我们需要准备输入数据。假设我们的模型需要房屋面积(以平方米为单位)作为输入来预测价格。

// 创建输入数据
MLFeatureProvider *input = [YourModelNameInput inputWithHouseArea:@(100.0)];

这里,YourModelNameInput 也是自动生成的类,用于创建符合模型输入要求的 MLFeatureProvider 对象。@(100.0) 表示房屋面积为 100 平方米。

进行预测

准备好输入数据后,我们就可以进行预测了。

// 进行预测
YourModelNameOutput *output = [model predictionFromFeatures:input error:&error];
if (error) {
    NSLog(@"Error making prediction: %@", error);
    return;
}

NSNumber *predictedPrice = output.predictedPrice;
NSLog(@"Predicted house price: $%@", predictedPrice);

在上述代码中,YourModelNameOutput 同样是自动生成的类,用于获取模型的输出结果。predictedPrice 就是模型预测出的房屋价格。

使用 Core ML 进行图像分类

图像分类模型概述

图像分类是 Core ML 常见的应用场景之一。一个图像分类模型可以识别图片中的物体属于哪一个预定义的类别。例如,它可以判断一张图片是猫、狗还是其他动物。

导入图像分类模型

假设我们有一个训练好的图像分类模型 ImageClassifier.mlmodel,将其拖入 Xcode 项目中。Xcode 会自动生成对应的模型类,假设为 ImageClassifier

加载和预处理图像

在进行图像分类之前,我们需要加载图像并对其进行预处理,以符合模型的输入要求。Core ML 模型通常期望输入的图像具有特定的尺寸、颜色空间等。

#import <UIKit/UIKit.h>
#import <CoreML/CoreML.h>

// 加载图像
UIImage *image = [UIImage imageNamed:@"cat.jpg"];

// 图像预处理
MLFeatureProvider *input = [ImageClassifierInput inputWithImage:image];

这里,ImageClassifierInput 是自动生成的用于创建图像输入的类。[UIImage imageNamed:@"cat.jpg"] 从项目资源中加载名为 cat.jpg 的图片。

进行图像分类预测

// 加载模型
NSError *error;
ImageClassifier *model = [[ImageClassifier alloc] initWithConfiguration:[[MLModelConfiguration alloc] init] error:&error];
if (error) {
    NSLog(@"Error loading model: %@", error);
    return;
}

// 进行预测
ImageClassifierOutput *output = [model predictionFromFeatures:input error:&error];
if (error) {
    NSLog(@"Error making prediction: %@", error);
    return;
}

NSDictionary<NSString *, NSNumber *> *probabilities = output.classLabelProbs;
NSString *predictedLabel = output.classLabel;
NSLog(@"Predicted label: %@", predictedLabel);
NSLog(@"Probabilities: %@", probabilities);

在上述代码中,ImageClassifierOutput 用于获取模型的输出。classLabel 是预测出的类别标签,classLabelProbs 是各个类别对应的概率。

Core ML 模型性能优化

模型量化

Core ML 支持模型量化,通过降低模型权重和激活值的精度来减小模型大小并提高运行速度。例如,可以将 32 位浮点数表示的权重转换为 16 位浮点数甚至 8 位整数。

硬件加速

苹果设备的 GPU 和神经引擎(如 A12 及后续芯片中的神经引擎)可以加速 Core ML 模型的运行。在使用 Core ML 时,框架会自动利用这些硬件资源,但开发者也可以通过一些配置选项来进一步优化硬件加速的使用。

模型剪枝

模型剪枝是一种去除模型中不重要连接或参数的技术。通过剪枝,可以在不显著降低模型精度的情况下减小模型大小,从而提高运行效率。不过,模型剪枝通常需要在模型训练阶段进行操作。

Core ML 与 Objective-C 的高级应用

实时图像识别

在实时图像识别应用中,我们可以结合摄像头捕获的实时视频流,使用 Core ML 进行实时的图像分类或物体检测。

#import <AVFoundation/AVFoundation.h>
#import <CoreML/CoreML.h>

// 设置摄像头会话
AVCaptureSession *session = [[AVCaptureSession alloc] init];
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:nil];
[session addInput:input];

AVCaptureVideoDataOutput *output = [[AVCaptureVideoDataOutput alloc] init];
[output setSampleBufferDelegate:self queue:dispatch_get_main_queue()];
[session addOutput:output];

// 开始捕获
[session startRunning];

captureOutput:didOutputSampleBuffer:fromConnection: 代理方法中,我们可以获取每一帧图像,并进行 Core ML 预测。

- (void)captureOutput:(AVCaptureOutput *)output didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection {
    // 将样本缓冲区转换为 UIImage
    CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
    CIImage *ciImage = [CIImage imageWithCVImageBuffer:imageBuffer];
    CIContext *context = [CIContext contextWithOptions:nil];
    CGImageRef cgImage = [context createCGImage:ciImage fromRect:CGRectMake(0, 0, CVPixelBufferGetWidth(imageBuffer), CVPixelBufferGetHeight(imageBuffer))];
    UIImage *image = [UIImage imageWithCGImage:cgImage];
    CGImageRelease(cgImage);

    // Core ML 图像分类预测
    MLFeatureProvider *input = [ImageClassifierInput inputWithImage:image];
    NSError *error;
    ImageClassifier *model = [[ImageClassifier alloc] initWithConfiguration:[[MLModelConfiguration alloc] init] error:&error];
    if (error) {
        NSLog(@"Error loading model: %@", error);
        return;
    }

    ImageClassifierOutput *prediction = [model predictionFromFeatures:input error:&error];
    if (error) {
        NSLog(@"Error making prediction: %@", error);
        return;
    }

    NSString *predictedLabel = prediction.classLabel;
    NSLog(@"Predicted label in real - time: %@", predictedLabel);
}

自然语言处理应用

Core ML 也可以用于自然语言处理任务,如文本分类、情感分析等。假设我们有一个训练好的文本分类 Core ML 模型 TextClassifier.mlmodel

#import <CoreML/CoreML.h>

// 准备文本输入
NSString *text = @"This is a great product!";
MLFeatureProvider *input = [TextClassifierInput inputWithText:text];

// 加载模型
NSError *error;
TextClassifier *model = [[TextClassifier alloc] initWithConfiguration:[[MLModelConfiguration alloc] init] error:&error];
if (error) {
    NSLog(@"Error loading model: %@", error);
    return;
}

// 进行预测
TextClassifierOutput *output = [model predictionFromFeatures:input error:&error];
if (error) {
    NSLog(@"Error making prediction: %@", error);
    return;
}

NSString *predictedCategory = output.predictedCategory;
NSLog(@"Predicted text category: %@", predictedCategory);

在上述代码中,TextClassifierInputTextClassifierOutput 是根据模型自动生成的类,用于处理输入和获取输出。

与其他框架结合使用

与 Vision 框架结合

Vision 框架是苹果提供的用于计算机视觉任务的框架,它可以与 Core ML 紧密结合。例如,我们可以使用 Vision 框架进行图像特征提取,然后将提取的特征作为 Core ML 模型的输入。

#import <Vision/Vision.h>
#import <CoreML/CoreML.h>

// 创建 Vision 图像请求
VNImageRequestHandler *handler = [[VNImageRequestHandler alloc] initWithCGImage:cgImage options:nil];
VNCoreMLRequest *coreMLRequest = [[VNCoreMLRequest alloc] initWithModel:model completionHandler:^(VNRequest * _Nonnull request, NSError * _Nullable error) {
    if (error) {
        NSLog(@"Error in Vision request: %@", error);
        return;
    }

    VNClassificationObservation *observation = request.results.firstObject;
    NSString *label = observation.identifier;
    NSLog(@"Predicted label using Vision and Core ML: %@", label);
}];

// 执行请求
NSError *visionError;
[handler performRequests:@[coreMLRequest] error:&visionError];
if (visionError) {
    NSLog(@"Error performing Vision requests: %@", visionError);
}

在上述代码中,VNCoreMLRequest 将 Core ML 模型集成到 Vision 框架的请求中,VNImageRequestHandler 用于处理图像并执行请求。

与 ARKit 结合

在增强现实(AR)应用中,可以使用 Core ML 进行物体识别,然后结合 ARKit 将虚拟物体放置在识别出的物体上。

#import <ARKit/ARKit.h>
#import <CoreML/CoreML.h>

// ARKit 会话设置
ARSession *session = [[ARSession alloc] init];
ARWorldTrackingConfiguration *configuration = [[ARWorldTrackingConfiguration alloc] init];
[session runWithConfiguration:configuration];

// 在 ARKit 委托方法中进行 Core ML 物体识别
- (void)renderer:(id <SCNSceneRenderer>)renderer didUpdateFrame:(ARFrame *)frame {
    CIImage *ciImage = [CIImage imageWithCVImageBuffer:frame.capturedImage];
    MLFeatureProvider *input = [ObjectDetectionModelInput inputWithImage:ciImage];

    NSError *error;
    ObjectDetectionModel *model = [[ObjectDetectionModel alloc] initWithConfiguration:[[MLModelConfiguration alloc] init] error:&error];
    if (error) {
        NSLog(@"Error loading model: %@", error);
        return;
    }

    ObjectDetectionModelOutput *output = [model predictionFromFeatures:input error:&error];
    if (error) {
        NSLog(@"Error making prediction: %@", error);
        return;
    }

    // 根据识别结果在 AR 场景中添加虚拟物体
    if (output.detectedObject) {
        SCNNode *virtualObjectNode = [SCNNode node];
        // 设置虚拟物体的几何形状、材质等
        SCNGeometry *geometry = [SCNBox boxWithWidth:0.1 height:0.1 length:0.1 chamferRadius:0];
        virtualObjectNode.geometry = geometry;

        ARAnchor *anchor = [[ARAnchor alloc] initWithTransform:frame.camera.transform];
        [session addAnchor:anchor];

        SCNScene *scene = [SCNScene scene];
        [scene.rootNode addChildNode:virtualObjectNode];
        renderer.scene = scene;
    }
}

在上述代码中,我们在 ARKit 的 renderer:didUpdateFrame: 委托方法中,利用 Core ML 进行物体识别,并根据识别结果在 AR 场景中添加虚拟物体。

通过以上内容,我们详细介绍了 Objective-C 与 Core ML 的基础应用、高级应用以及与其他框架的结合使用。希望这些知识能够帮助你在 Objective-C 项目中更好地运用 Core ML 实现各种机器学习相关的功能。