Core ML 2 no Xamarin.iOS

O Core ML é uma tecnologia de machine learning disponível no iOS, macOS, tvOS e watchOS. Ele permite que os aplicativos façam previsões com base em modelos de machine learning.

No iOS 12, o Core ML inclui uma API de processamento em lote. Essa API torna o Core ML mais eficiente e fornece melhorias de desempenho em cenários em que um modelo é usado para fazer uma sequência de previsões.

Aplicativo de exemplo: MarsHabitatCoreMLTimer

Para demonstrar previsões em lote com o Core ML, dê uma olhada no aplicativo de exemplo MarsHabitatCoreMLTimer . Este exemplo usa um modelo ML Principal treinado para prever o custo da construção de um habitat em Marte, com base em várias entradas: número de painéis solares, número de estufas e número de acres.

Os snippets de código neste documento são provenientes deste exemplo.

Gerar dados de exemplo

No ViewController, o método do aplicativo de ViewDidLoad exemplo chama LoadMLModel, que carrega o modelo do Core ML incluído:

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

Em seguida, o aplicativo de exemplo cria 100.000 MarsHabitatPricerInput objetos a serem usados como entrada para previsões sequenciais do Core ML. Cada amostra gerada tem um valor aleatório definido para o número de painéis solares, o número de estufas e o número de acres:

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

Tocar em qualquer um dos três botões do aplicativo executa duas sequências de previsões: uma usando um for loop e outra usando o novo método de lote GetPredictions introduzido no iOS 12:

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

para loop

A for versão de loop do teste itera naively sobre o número especificado de entradas, chamando GetPrediction para cada e descartando o resultado. O método vezes quanto tempo leva para fazer as previsões:

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 (nova API em lote)

A versão em lote do teste cria um MLArrayBatchProvider objeto da matriz de entrada (já que esse é um parâmetro de entrada necessário para o GetPredictions método ), cria umMLPredictionOptions que impede que os cálculos de previsão sejam restritos à CPU e usa a GetPredictions API para buscar as previsões, descartando novamente o resultado:

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

Resultados

No simulador e no dispositivo, GetPredictions o é concluído mais rapidamente do que as previsões do Core ML baseadas em loop.