Einführung in CoreML in Xamarin.iOS

CoreML bringt maschinelles Lernen zu iOS – Apps können trainierte Machine Learning-Modelle nutzen, um alle Arten von Aufgaben auszuführen, von der Problemlösung bis zur Bilderkennung.

In dieser Einführung werden die folgenden Themen behandelt:

Erste Schritte mit CoreML

In diesen Schritten wird das Hinzufügen von CoreML zu einem iOS-Projekt beschrieben. Ein praktisches Beispiel finden Sie im Mars Habitat Pricer-Beispiel .

Mars Habitat Price Predictor sample screenshot

1. Hinzufügen des CoreML-Modells zum Projekt

Fügen Sie dem Ressourcenverzeichnis des Projekts ein CoreML-Modell (eine Datei mit der Erweiterung MLMODEL) hinzu.

In den Eigenschaften der Modelldatei wird die Build-Aktion auf "CoreMLModel" festgelegt. Dies bedeutet, dass sie beim Erstellen der Anwendung in eine MLMODELC-Datei kompiliert wird.

2. Laden des Modells

Laden Sie das Modell mithilfe der MLModel.Create statischen Methode:

var assetPath = NSBundle.MainBundle.GetUrlForResource("NameOfModel", "mlmodelc");
model = MLModel.Create(assetPath, out NSError error1);

3. Festlegen der Parameter

Modellparameter werden mithilfe einer Containerklasse übergeben, die implementiert IMLFeatureProviderwird.

Featureanbieterklassen verhalten sich wie ein Wörterbuch mit Zeichenfolge und MLFeatureValues, wobei jeder Featurewert eine einfache Zeichenfolge oder Zahl, ein Array oder Daten oder ein Pixelpuffer sein kann, der ein Bild enthält.

Der Code für einen Einzelwert-Featureanbieter wird unten angezeigt:

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
  }

Mithilfe von Klassen wie diesem können Eingabeparameter auf eine Weise bereitgestellt werden, die von CoreML verstanden wird. Die Namen der Features (z myParam . B. im Codebeispiel) müssen mit dem übereinstimmen, was das Modell erwartet.

4. Ausführen des Modells

Die Verwendung des Modells erfordert, dass der Featureanbieter instanziiert und Parameter festgelegt werden muss, und dass die GetPrediction Methode aufgerufen wird:

var input = new MyInput {MyParam = 13};
var outFeatures = model.GetPrediction(inputFeatures, out NSError error2);

5. Extrahieren der Ergebnisse

Das Vorhersageergebnis outFeatures ist auch eine Instanz von IMLFeatureProvider; Ausgabewerte können mit GetFeatureValue dem Namen der einzelnen Ausgabeparameter (z theResult. B. ) aufgerufen werden, wie in diesem Beispiel:

var result = outFeatures.GetFeatureValue("theResult").DoubleValue; // eg. 6227020800

Verwenden von CoreML mit dem Vision Framework

CoreML kann auch in Verbindung mit dem Vision-Framework verwendet werden, um Vorgänge im Bild auszuführen, z. B. Shape-Erkennung, Objektidentifizierung und andere Aufgaben.

Die folgenden Schritte beschreiben, wie CoreML und Vision im CoreMLVision-Beispiel zusammen verwendet werden. Das Beispiel kombiniert die Rechteckeerkennung aus dem Vision-Framework mit dem MNINSTClassifier CoreML-Modell, um eine handschriftliche Ziffer in einem Foto zu identifizieren.

Image recognition of number 3Image recognition of number 5

1. Erstellen eines Vision CoreML-Modells

Das CoreML-Modell MNISTClassifier wird geladen und anschließend umschlossen, wodurch VNCoreMLModel das Modell für Vision-Aufgaben zur Verfügung gestellt wird. Dieser Code erstellt auch zwei Vision-Anforderungen: zuerst zum Suchen von Rechtecks in einem Bild und dann zum Verarbeiten eines Rechtecks mit dem CoreML-Modell:

// 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);

Die Klasse muss weiterhin die HandleRectangles und HandleClassification Methoden für die Vision-Anforderungen implementieren, die in den schritten 3 und 4 unten gezeigt werden.

2. Starten der Vision-Verarbeitung

Der folgende Code beginnt mit der Verarbeitung der Anforderung. Im CoreMLVision-Beispiel wird dieser Code ausgeführt, nachdem der Benutzer ein Bild ausgewählt hat:

// 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);
});

Dieser Handler übergibt das ciImage Vision-Framework VNDetectRectanglesRequest , das in Schritt 1 erstellt wurde.

3. Behandeln der Ergebnisse der Vision-Verarbeitung

Sobald die Rechteckerkennung abgeschlossen ist, führt sie die HandleRectangles Methode aus, mit der das Bild abgeschnitten wird, um das erste Rechteck zu extrahieren, das Rechteckbild in Graustufen konvertiert und zur Klassifizierung an das CoreML-Modell übergeben wird.

Der request an diese Methode übergebene Parameter enthält die Details der Vision-Anforderung und gibt mithilfe der GetResults<VNRectangleObservation>() Methode eine Liste der Rechtecke zurück, die im Bild enthalten sind. Das erste Rechteck observations[0] wird extrahiert und an das CoreML-Modell übergeben:

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);
  });
}

Die ClassificationRequest Methode wurde in Schritt 1 initialisiert, um die HandleClassification im nächsten Schritt definierte Methode zu verwenden.

4. Behandeln des CoreML

Der request an diese Methode übergebene Parameter enthält die Details der CoreML-Anforderung und gibt mithilfe der GetResults<VNClassificationObservation>() Methode eine Liste möglicher Ergebnisse zurück, die nach Konfidenz sortiert sind (höchste Konfidenz zuerst):

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}%";
  });
}

Beispiele

Es gibt drei CoreML-Beispiele, die Sie ausprobieren können:

  • Das Mars Habitat Price Predictor-Beispiel verfügt über einfache numerische Eingaben und Ausgaben.

  • Das Vision & CoreML-Beispiel akzeptiert einen Bildparameter und verwendet das Vision-Framework, um quadratische Bereiche im Bild zu identifizieren, die an ein CoreML-Modell übergeben werden, das einzelne Ziffern erkennt.

  • Schließlich verwendet das CoreML-Beispiel für die Bilderkennung CoreML, um Features in einem Foto zu identifizieren. Standardmäßig wird das kleinere SqueezeNet-Modell (5 MB) verwendet, aber es wurde geschrieben, sodass Sie das größere VGG16-Modell (553 MB) herunterladen und integrieren können. Weitere Informationen finden Sie in der Infodatei des Beispiels.