Wprowadzenie do języka CoreML w środowisku Xamarin.iOS
CoreML umożliwia uczenie maszynowe w systemie iOS — aplikacje mogą korzystać z wytrenowanych modeli uczenia maszynowego w celu wykonywania różnych zadań, od rozwiązywania problemów po rozpoznawanie obrazów.
To wprowadzenie obejmuje następujące kwestie:
Wprowadzenie do języka CoreML
W tych krokach opisano sposób dodawania kodu CoreML do projektu systemu iOS.
1. Dodawanie modelu CoreML do projektu
Dodaj model CoreML (plik z rozszerzeniem mlmodel ) do katalogu Resources projektu.
We właściwościach pliku modelu jego akcja kompilacji jest ustawiona na CoreMLModel. Oznacza to, że zostanie on skompilowany w pliku mlmodelc podczas kompilowania aplikacji.
2. Ładowanie modelu
Załaduj model przy użyciu metody statycznej MLModel.Create
:
var assetPath = NSBundle.MainBundle.GetUrlForResource("NameOfModel", "mlmodelc");
model = MLModel.Create(assetPath, out NSError error1);
3. Ustawianie parametrów
Parametry modelu są przekazywane i wychodzące przy użyciu klasy kontenera, która implementuje IMLFeatureProvider
element .
Klasy dostawców funkcji zachowują się jak słownik ciągów i MLFeatureValue
s, gdzie każda wartość funkcji może być prostym ciągiem lub liczbą, tablicą lub danymi albo buforem pikseli zawierającym obraz.
Poniżej przedstawiono kod dostawcy funkcji z jedną wartością:
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
}
Korzystając z takich klas, parametry wejściowe można podać w sposób zrozumiały dla języka CoreML. Nazwy funkcji (takich jak myParam
w przykładzie kodu) muszą być zgodne z oczekiwaniami modelu.
4. Uruchamianie modelu
Użycie modelu wymaga utworzenia wystąpienia dostawcy funkcji i ustawienia parametrów, a następnie wywołania GetPrediction
metody:
var input = new MyInput {MyParam = 13};
var outFeatures = model.GetPrediction(inputFeatures, out NSError error2);
5. Wyodrębnianie wyników
Wynik outFeatures
przewidywania jest również wystąpieniem ; wartości wyjściowe można uzyskać przy użyciu nazwy GetFeatureValue
każdego parametru wyjściowego IMLFeatureProvider
(na przykład ), jak theResult
w tym przykładzie:
var result = outFeatures.GetFeatureValue("theResult").DoubleValue; // eg. 6227020800
Używanie języka CoreML z platformą Vision Framework
Język CoreML może być również używany w połączeniu z platformą Vision do wykonywania operacji na obrazie, takich jak rozpoznawanie kształtów, identyfikacja obiektów i inne zadania.
W poniższych krokach opisano, jak można używać razem języka CoreML i przetwarzania obrazów. Przykład łączy rozpoznawanie prostokątów z platformy Vision z modelem MNINSTClassifier CoreML, aby zidentyfikować cyfrę odręczną na zdjęciu.
1. Tworzenie modelu Vision CoreML
Model CoreML MNISTClassifier jest ładowany, a następnie opakowany w element VNCoreMLModel
, który udostępnia model dla zadań przetwarzania obrazów. Ten kod tworzy również dwa żądania przetwarzania obrazów: najpierw do znajdowania prostokątów na obrazie, a następnie do przetwarzania prostokąta za pomocą modelu 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);
Klasa nadal musi zaimplementować HandleRectangles
metody i HandleClassification
dla żądań przetwarzania obrazów, pokazane w krokach 3 i 4 poniżej.
2. Rozpoczęcie przetwarzania obrazów
Poniższy kod rozpoczyna przetwarzanie żądania. W przykładzie CoreMLVision ten kod jest uruchamiany po wybraniu obrazu przez użytkownika:
// 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);
});
Ta procedura obsługi przekazuje ciImage
element do struktury VNDetectRectanglesRequest
Vision utworzonej w kroku 1.
3. Obsługa wyników przetwarzania obrazów
Po zakończeniu wykrywania prostokąta wykonuje HandleRectangles
metodę, która przycina obraz w celu wyodrębnienia pierwszego prostokąta, konwertuje obraz prostokątny na skalę szarą i przekazuje go do modelu CoreML na potrzeby klasyfikacji.
Parametr request
przekazany do tej metody zawiera szczegóły żądania przetwarzania obrazów, a przy użyciu GetResults<VNRectangleObservation>()
metody zwraca listę prostokątów znalezionych na obrazie. Pierwszy prostokąt observations[0]
jest wyodrębniany i przekazywany do modelu 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);
});
}
Element ClassificationRequest
został zainicjowany w kroku 1, aby użyć HandleClassification
metody zdefiniowanej w następnym kroku.
4. Obsługa kodu CoreML
Parametr request
przekazany do tej metody zawiera szczegóły żądania CoreML, a przy użyciu GetResults<VNClassificationObservation>()
metody zwraca listę możliwych wyników uporządkowanych według ufności (najpierw najwyższe zaufanie):
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}%";
});
}