Compartilhar via


Core ML 2 no Xamarin.iOS

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

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.

Gerar dados de exemplo

No ViewController, o método do aplicativo de ViewDidLoad exemplo chama LoadMLModel, que carrega o modelo de ML principal 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 para usar 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 hectares:

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 ingenuamente sobre o número especificado de entradas, chamando GetPrediction cada uma e descartando o resultado. O método calcula 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 a partir da matriz de entrada (já que esse é um parâmetro de entrada necessário para o GetPredictions método), cria um MLPredictionOptions objeto que impede que os cálculos de previsão sejam restritos à CPU e usa a GetPredictions API para buscar as previsões, novamente descartando 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

Tanto no simulador quanto no dispositivo, GetPredictions termina mais rapidamente do que as previsões do Core ML baseadas em loop.