Partilhar via


Introdução ao CoreML no Xamarin.iOS

O CoreML traz o aprendizado de máquina para o iOS – os aplicativos podem aproveitar os modelos de aprendizado de máquina treinados para executar todos os tipos de tarefas, desde a resolução de problemas até o reconhecimento de imagens.

Esta introdução abrange o seguinte:

Introdução ao CoreML

Estas etapas descrevem como adicionar CoreML a um projeto iOS.

Captura de tela da amostra do Mars Habitat Price Predictor

1. Adicionar o modelo CoreML ao projeto

Adicione um modelo CoreML (um arquivo com a extensão .mlmodel ) ao diretório Resources do projeto.

Nas propriedades do arquivo de modelo, sua ação Build é definida como CoreMLModel. Isso significa que ele será compilado em um arquivo .mlmodelc quando o aplicativo for criado.

2. Carregue o modelo

Carregue o modelo usando o MLModel.Create método estático:

var assetPath = NSBundle.MainBundle.GetUrlForResource("NameOfModel", "mlmodelc");
model = MLModel.Create(assetPath, out NSError error1);

3. Defina os parâmetros

Os parâmetros do modelo são passados para dentro e para fora usando uma classe de contêiner que implementa IMLFeatureProvider.

As classes de provedor de recursos se comportam como um dicionário de cadeia de caracteres e MLFeatureValues, em que cada valor de recurso pode ser uma cadeia de caracteres ou um número simples, uma matriz ou dados ou um buffer de pixels contendo uma imagem.

O código para um provedor de recursos de valor único é mostrado abaixo:

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
  }

Usando classes como essa, os parâmetros de entrada podem ser fornecidos de uma maneira que seja compreendida pelo CoreML. Os nomes dos recursos (como myParam no exemplo de código) devem corresponder ao que o modelo espera.

4. Execute o modelo

O uso do modelo requer que o provedor de recursos seja instanciado e os parâmetros definidos e, em seguida, que o GetPrediction método seja chamado:

var input = new MyInput {MyParam = 13};
var outFeatures = model.GetPrediction(inputFeatures, out NSError error2);

5. Extraia os resultados

O resultado outFeatures da previsão também é uma instância de ; os valores de IMLFeatureProvidersaída podem ser acessados usando GetFeatureValue com o nome de cada parâmetro de saída (como theResult), como neste exemplo:

var result = outFeatures.GetFeatureValue("theResult").DoubleValue; // eg. 6227020800

Usando o CoreML com o Vision Framework

O CoreML também pode ser usado em conjunto com a estrutura de visão para executar operações na imagem, como reconhecimento de forma, identificação de objetos e outras tarefas.

As etapas abaixo descrevem como o CoreML e o Vision podem ser usados juntos. O exemplo combina o reconhecimento de retângulos da estrutura Vision com o modelo MNINSTClassifier CoreML para identificar um dígito manuscrito em uma fotografia.

Reconhecimento de imagem do número 3 Reconhecimento de imagem do número 5

1. Criar um modelo CoreML de visão

O modelo CoreML MNISTClassifier é carregado e, em seguida, encapsulado em um VNCoreMLModel que disponibiliza o modelo para tarefas de visão. Esse código também cria duas solicitações de visão: primeiro para localizar retângulos em uma imagem e, em seguida, para processar um retângulo com o modelo 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);

A classe ainda precisa implementar os HandleRectangles métodos and HandleClassification para as solicitações Vision, mostradas nas etapas 3 e 4 abaixo.

2. Inicie o processamento da visão

O código a seguir inicia o processamento da solicitação. No exemplo CoreMLVision, esse código é executado depois que o usuário seleciona uma imagem:

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

Esse manipulador passa o ciImage para a estrutura VNDetectRectanglesRequest Vision que foi criada na etapa 1.

3. Lidar com os resultados do processamento da visão

Depois que a detecção do retângulo é concluída, ele executa o HandleRectangles método, que corta a imagem para extrair o primeiro retângulo, converte a imagem do retângulo em escala de cinza e a passa para o modelo CoreML para classificação.

O request parâmetro passado para esse método contém os detalhes da solicitação Vision e, usando o GetResults<VNRectangleObservation>() método, ele retorna uma lista de retângulos encontrados na imagem. O primeiro retângulo observations[0] é extraído e passado para o modelo 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);
  });
}

O ClassificationRequest foi inicializado na etapa 1 para usar o HandleClassification método definido na próxima etapa.

4. Manipular o CoreML

O request parâmetro passado para esse método contém os detalhes da solicitação CoreML e, usando o GetResults<VNClassificationObservation>() método, ele retorna uma lista de resultados possíveis ordenados por confiança (confiança mais alta primeiro):

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}%";
  });
}