Core ML 2 in Xamarin.iOS

Core ML è una tecnologia di Machine Learning disponibile in iOS, macOS, tvOS e watchOS. Consente alle app di eseguire stime basate su modelli di Machine Learning.

In iOS 12 Core ML include un'API di elaborazione batch. Questa API rende Core ML più efficiente e offre miglioramenti delle prestazioni negli scenari in cui viene usato un modello per eseguire una sequenza di stime.

App di esempio: MarsHabitatCoreMLTimer

Per illustrare le stime batch con Core ML, vedere l'app di esempio MarsHabitatCoreMLTimer . Questo esempio usa un modello Core ML sottoposto a training per stimare il costo della creazione di un habitat su Marte, in base a vari input: numero di pannelli solari, numero di serra e numero di acri.

I frammenti di codice in questo documento provengono da questo esempio.

Generare dati di esempio

In ViewControlleril metodo dell'app di ViewDidLoad esempio chiama LoadMLModel, che carica il modello Core ML incluso:

void LoadMLModel()
{
    var assetPath = NSBundle.MainBundle.GetUrlForResource("CoreMLModel/MarsHabitatPricer", "mlmodelc");
    model = MLModel.Create(assetPath, out NSError mlErr);
}

L'app di esempio crea quindi 100.000 MarsHabitatPricerInput oggetti da usare come input per le stime sequenziali di Core ML. Ogni campione generato ha un valore casuale impostato per il numero di pannelli solari, il numero di serra e il numero di acri:

async void CreateInputs(int num)
{
    // ...
    Random r = new Random();
    await Task.Run(() =>
    {
        for (int i = 0; i < num; i++)
        {
            double solarPanels = r.NextDouble() * MaxSolarPanels;
            double greenHouses = r.NextDouble() * MaxGreenHouses;
            double acres = r.NextDouble() * MaxAcres;
            inputs[i] = new MarsHabitatPricerInput(solarPanels, greenHouses, acres);
        }
    });
    // ...
}

Toccando uno dei tre pulsanti dell'app vengono eseguite due sequenze di stime: una usando un for ciclo e un'altra usando il nuovo metodo batch GetPredictions introdotto in iOS 12:

async void RunTest(int num)
{
    // ...
    await FetchNonBatchResults(num);
    // ...
    await FetchBatchResults(num);
    // ...
}

for (ciclo)

La for versione del ciclo del test scorre in modo ingenuo il numero specificato di input, chiamando GetPrediction per ognuno e rimuovendo il risultato. Il tempo necessario per il metodo per eseguire le stime:

async Task FetchNonBatchResults(int num)
{
    Stopwatch stopWatch = Stopwatch.StartNew();
    await Task.Run(() =>
    {
        for (int i = 0; i < num; i++)
        {
            IMLFeatureProvider output = model.GetPrediction(inputs[i], out NSError error);
        }
    });
    stopWatch.Stop();
    nonBatchMilliseconds = stopWatch.ElapsedMilliseconds;
}

GetPredictions (nuova API batch)

La versione batch del test crea un MLArrayBatchProvider oggetto dalla matrice di input (poiché si tratta di un parametro di input obbligatorio per il GetPredictions metodo ), crea un oggetto MLPredictionOptions oggetto che impedisce ai calcoli di stima di essere limitato alla CPU e usa l'API GetPredictions per recuperare le stime, ignorando di nuovo il risultato:

async Task FetchBatchResults(int num)
{
    var batch = new MLArrayBatchProvider(inputs.Take(num).ToArray());
    var options = new MLPredictionOptions()
    {
        UsesCpuOnly = false
    };

    Stopwatch stopWatch = Stopwatch.StartNew();
    await Task.Run(() =>
    {
        model.GetPredictions(batch, options, out NSError error);
    });
    stopWatch.Stop();
    batchMilliseconds = stopWatch.ElapsedMilliseconds;
}

Risultati

Sia nel simulatore che nel dispositivo, GetPredictions termina più rapidamente rispetto alle stime di Core ML basate sul ciclo.