CoreML 将机器学习引入了 iOS – 应用可以利用经过训练的机器学习模型来执行各种任务,从解决问题到图像识别均可得到支持。
本简介涵盖以下内容:
以下步骤介绍了如何将 CoreML 添加到 iOS 项目。
将 CoreML 模型(具有 .mlmodel 扩展名的文件)添加到项目的“Resources”目录中。
在模型文件的属性中,将其“生成操作”设置为 CoreMLModel。 这意味着在生成应用程序时,它将编译为 .mlmodelc 文件。
使用 MLModel.Create
静态方法加载模型:
var assetPath = NSBundle.MainBundle.GetUrlForResource("NameOfModel", "mlmodelc");
model = MLModel.Create(assetPath, out NSError error1);
使用实现 IMLFeatureProvider
的容器类传入和传出模型参数。
特征提供程序类的行为类似于字符串和 MLFeatureValue
字典,其中每个特征值可以是简单的字符串或数字、数组或数据,或者包含图像的像素缓冲区。
单值特征提供程序的代码如下所示:
public class MyInput : NSObject, IMLFeatureProvider
{
public double MyParam { get; set; }
public NSSet<NSString> FeatureNames => new NSSet<NSString>(new NSString("myParam"));
public MLFeatureValue GetFeatureValue(string featureName)
{
if (featureName == "myParam")
return MLFeatureValue.FromDouble(MyParam);
return MLFeatureValue.FromDouble(0); // default value
}
使用这样的类,可以通过 CoreML 能够理解的方式提供输入参数。 特征的名称(如代码示例中的 myParam
)必须与模型的预期用途相匹配。
使用模型要求实例化特征提供程序并设置参数,然后调用 GetPrediction
方法:
var input = new MyInput {MyParam = 13};
var outFeatures = model.GetPrediction(inputFeatures, out NSError error2);
预测结果 outFeatures
也是 IMLFeatureProvider
的一个实例;可以使用 GetFeatureValue
和每个输出参数的名称(如 theResult
)来访问输出值,如以下示例所示:
var result = outFeatures.GetFeatureValue("theResult").DoubleValue; // eg. 6227020800
CoreML 还可以与视觉框架结合使用,以对图像执行操作,例如形状识别、对象识别和其他任务。
以下步骤介绍如何结合使用 CoreML 和 Vision。 该示例将视觉框架中的矩形识别与 MNINSTClassifier CoreML 模型相结合,以识别照片中的手写数字。
以下代码将加载 CoreML 模型 MNISTClassifier,然后将其包装在 VNCoreMLModel
中,从而使该模型可用于视觉任务。 此代码还将创建两个视觉请求:首先在图像中查找矩形,然后使用 CoreML 模型处理矩形:
// Load the ML model
var bundle = NSBundle.MainBundle;
var assetPath = bundle.GetUrlForResource("MNISTClassifier", "mlmodelc");
NSError mlErr, vnErr;
var mlModel = MLModel.Create(assetPath, out mlErr);
var model = VNCoreMLModel.FromMLModel(mlModel, out vnErr);
// Initialize Vision requests
RectangleRequest = new VNDetectRectanglesRequest(HandleRectangles);
ClassificationRequest = new VNCoreMLRequest(model, HandleClassification);
该类仍需要为视觉请求实现 HandleRectangles
和 HandleClassification
方法,如下面的步骤 3 和 4 所示。
以下代码将开始处理请求。 在 CoreMLVision 示例中,此代码将在用户选择一个图像后运行:
// Run the rectangle detector, which upon completion runs the ML classifier.
var handler = new VNImageRequestHandler(ciImage, uiImage.Orientation.ToCGImagePropertyOrientation(), new VNImageOptions());
DispatchQueue.DefaultGlobalQueue.DispatchAsync(()=>{
handler.Perform(new VNRequest[] {RectangleRequest}, out NSError error);
});
此处理程序会将 ciImage
传递给在步骤 1 中创建的视觉框架 VNDetectRectanglesRequest
。
矩形检测完成后,它会执行 HandleRectangles
方法,该方法将裁剪图像以提取第一个矩形,将矩形图像转换为灰度,然后将其传递给 CoreML 模型来进行分类。
传递给此方法的 request
参数包含视觉请求的详细信息,并会在使用 GetResults<VNRectangleObservation>()
方法时返回在图像中找到的矩形列表。 此时将提取第一个矩形 observations[0]
并将其传递给 CoreML 模型:
void HandleRectangles(VNRequest request, NSError error) {
var observations = request.GetResults<VNRectangleObservation>();
// ... omitted error handling ...
var detectedRectangle = observations[0]; // first rectangle
// ... omitted cropping and greyscale conversion ...
// Run the Core ML MNIST classifier -- results in handleClassification method
var handler = new VNImageRequestHandler(correctedImage, new VNImageOptions());
DispatchQueue.DefaultGlobalQueue.DispatchAsync(() => {
handler.Perform(new VNRequest[] {ClassificationRequest}, out NSError err);
});
}
ClassificationRequest
在步骤 1 中实现了初始化,以使用下一步中定义的 HandleClassification
方法。
传递给此方法的 request
参数包含 CoreML 请求的详细信息,并会在使用 GetResults<VNClassificationObservation>()
方法时返回按置信度排序的可能结果列表(置信度最高的排在最前面):
void HandleClassification(VNRequest request, NSError error){
var observations = request.GetResults<VNClassificationObservation>();
// ... omitted error handling ...
var best = observations[0]; // first/best classification result
// render in UI
DispatchQueue.MainQueue.DispatchAsync(()=>{
ClassificationLabel.Text = $"Classification: {best.Identifier} Confidence: {best.Confidence * 100f:#.00}%";
});
}