Core ML 2 en Xamarin.iOS
Core ML es una tecnología de aprendizaje automático disponible en iOS, macOS, tvOS y watchOS. Permite que las aplicaciones realicen predicciones basadas en modelos de aprendizaje automático.
En iOS 12, Core ML incluye una API de procesamiento por lotes. Esta API hace que Core ML sea más eficaz y proporciona mejoras de rendimiento en escenarios en los que se usa un modelo para realizar una secuencia de predicciones.
Generación de datos de ejemplo
En ViewController
, el método ViewDidLoad
de la aplicación de muestra llama a LoadMLModel
, que carga el modelo Core ML incluido:
void LoadMLModel()
{
var assetPath = NSBundle.MainBundle.GetUrlForResource("CoreMLModel/MarsHabitatPricer", "mlmodelc");
model = MLModel.Create(assetPath, out NSError mlErr);
}
A continuación, la aplicación de ejemplo crea 100 000 objetos MarsHabitatPricerInput
que se usarán como entrada para predicciones de Core ML secuenciales. Cada muestra generada tiene un valor aleatorio establecido para el número de paneles solares, el número de invernaderos y el 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);
}
});
// ...
}
Al pulsar cualquiera de los tres botones de la aplicación, se ejecutan dos secuencias de predicciones: una que usa un bucle for
y otra con el nuevo método por lotes GetPredictions
introducido en iOS 12:
async void RunTest(int num)
{
// ...
await FetchNonBatchResults(num);
// ...
await FetchBatchResults(num);
// ...
}
for (bucle)
La versión del bucle for
de la prueba recorre en iteración el número de entradas especificado, llamando a GetPrediction
para cada una y descartando el resultado. El método cronometra el tiempo que lleva hacer las predicciones:
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 (nueva API por lotes)
La versión por lotes de la prueba crea un objeto MLArrayBatchProvider
a partir de la matriz de entrada (ya que se trata de un parámetro de entrada necesario para el método GetPredictions
), crea un objeto MLPredictionOptions
que impide que los cálculos de predicción estén restringidos a la CPU y usa la API GetPredictions
para capturar las predicciones, de nuevo descartando el 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;
}
Results
En el simulador y el dispositivo, GetPredictions
finaliza más rápidamente que las predicciones de Core ML basadas en bucles.