Faça previsões com um modelo AutoML ONNX no .NET
Neste artigo, você aprenderá a usar um modelo ONNX (Open Neural Network Exchange) de ML automatizado (AutoML) para fazer previsões em um aplicativo de console C# com ML.NET.
ML.NET é uma estrutura de aprendizado de máquina de código aberto, multiplataforma, para o ecossistema .NET que permite treinar e consumir modelos personalizados de aprendizado de máquina usando uma abordagem code-first em C# ou F#, ou por meio de ferramentas low-code como o Model Builder e o ML.NET CLI. A estrutura é extensível e permite que você aproveite outras estruturas populares de aprendizado de máquina, como TensorFlow e ONNX.
ONNX é um formato de código aberto para modelos de IA. O ONNX suporta a interoperabilidade entre frameworks. Isso significa que você pode treinar um modelo em uma das muitas estruturas populares de aprendizado de máquina como o PyTorch, convertê-lo no formato ONNX e consumir o modelo ONNX em uma estrutura diferente, como ML.NET. Para saber mais, visite o site da ONNX.
Pré-requisitos
- SDK do .NET 6 ou posterior
- Editor de texto ou IDE (como Visual Studio ou Visual Studio Code)
- Modelo ONNX. Para saber como treinar um modelo AutoML ONNX, consulte o seguinte bloco de anotações de classificação de marketing bancário.
- Netron (opcional)
Criar um aplicativo de console C#
Neste exemplo, você usa a CLI do .NET para criar seu aplicativo, mas pode fazer as mesmas tarefas usando o Visual Studio. Saiba mais sobre a CLI do .NET.
Abra um terminal e crie um novo aplicativo de console C# .NET. Neste exemplo, o nome do aplicativo é
AutoMLONNXConsoleApp
. Um diretório é criado com esse mesmo nome com o conteúdo do seu aplicativo.dotnet new console -o AutoMLONNXConsoleApp
No terminal, navegue até o diretório AutoMLONNXConsoleApp .
cd AutoMLONNXConsoleApp
Adicionar pacotes de software
Instale os pacotes NuGet Microsoft.ML, Microsoft.ML.OnnxRuntime e Microsoft.ML.OnnxTransformer usando a CLI do .NET.
dotnet add package Microsoft.ML dotnet add package Microsoft.ML.OnnxRuntime dotnet add package Microsoft.ML.OnnxTransformer
Esses pacotes contêm as dependências necessárias para usar um modelo ONNX em um aplicativo .NET. ML.NET fornece uma API que usa o tempo de execução ONNX para previsões.
Abra o arquivo Program.cs e adicione as seguintes
using
diretivas na parte superior.using System.Linq; using Microsoft.ML; using Microsoft.ML.Data; using Microsoft.ML.Transforms.Onnx;
Adicionar uma referência ao modelo ONNX
Uma maneira para o aplicativo de console acessar o modelo ONNX é adicioná-lo ao diretório de saída de compilação. Se ainda não tiver um modelo, siga este bloco de notas para criar um modelo de exemplo.
Adicione uma referência ao seu arquivo de modelo ONNX em seu aplicativo:
Copie seu modelo ONNX para o diretório raiz AutoMLONNXConsoleApp do seu aplicativo.
Abra o arquivo AutoMLONNXConsoleApp.csproj e adicione o seguinte conteúdo dentro do
Project
nó.<ItemGroup> <None Include="automl-model.onnx"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </None> </ItemGroup>
Nesse caso, o nome do arquivo de modelo ONNX é automl-model.onnx.
(Para saber mais sobre os itens comuns do MSBuild, consulte o Guia do MSBuild.)
Abra o arquivo Program.cs e adicione a seguinte linha dentro da
Program
classe.static string ONNX_MODEL_PATH = "automl-model.onnx";
Inicializar MLContext
Dentro do Main
método da sua Program
classe, crie uma nova instância do MLContext
.
MLContext mlContext = new MLContext();
A MLContext
classe é um ponto de partida para todas as operações ML.NET, e a mlContext
inicialização cria um novo ambiente de ML.NET que pode ser compartilhado em todo o ciclo de vida do modelo. É semelhante, conceitualmente, ao DbContext Entity Framework.
Definir o esquema de dados do modelo
Um modelo espera os dados de entrada e saída em um formato específico. ML.NET permite-lhe definir o formato dos seus dados através de classes. Às vezes, você já pode saber como é esse formato. Nos casos em que você não sabe o formato de dados, você pode usar ferramentas como Netron para inspecionar o modelo ONNX.
O modelo usado neste exemplo usa dados do conjunto de dados NYC TLC Taxi Trip. Uma amostra dos dados é mostrada na tabela a seguir:
vendor_id | rate_code | passenger_count | trip_time_in_secs | trip_distance | payment_type | fare_amount |
---|---|---|---|---|---|---|
VTS | 1 | 1 | 1140 | 3.75 | DRFP | 15,5 |
VTS | 1 | 1 | 480 | 2.72 | DRFP | 10,0 |
VTS | 1 | 1 | 1680 | 7.8 | CSH | 26,5 |
Inspecione o modelo ONNX (opcional)
Use uma ferramenta como o Netron para inspecionar as entradas e saídas do seu modelo.
Abra o Netron.
Na barra de menu superior, selecione Abrir arquivo > e use o navegador de arquivos para selecionar seu modelo.
O seu modelo abre. Por exemplo, a estrutura do modelo automl-model.onnx tem a seguinte aparência:
Selecione o último nó na parte inferior do gráfico (
variable_out1
neste caso) para exibir os metadados do modelo. As entradas e saídas na barra lateral mostram as entradas, saídas e tipos de dados esperados do modelo. Use essas informações para definir o esquema de entrada e saída do seu modelo.
Definir esquema de entrada de modelo
Crie uma nova classe chamada OnnxInput
com as seguintes propriedades dentro do arquivo Program.cs .
public class OnnxInput
{
[ColumnName("vendor_id")]
public string VendorId { get; set; }
[ColumnName("rate_code"),OnnxMapType(typeof(Int64),typeof(Single))]
public Int64 RateCode { get; set; }
[ColumnName("passenger_count"), OnnxMapType(typeof(Int64), typeof(Single))]
public Int64 PassengerCount { get; set; }
[ColumnName("trip_time_in_secs"), OnnxMapType(typeof(Int64), typeof(Single))]
public Int64 TripTimeInSecs { get; set; }
[ColumnName("trip_distance")]
public float TripDistance { get; set; }
[ColumnName("payment_type")]
public string PaymentType { get; set; }
}
Cada uma das propriedades é mapeada para uma coluna no conjunto de dados. As propriedades são ainda anotadas com atributos.
O ColumnName
atributo permite especificar como ML.NET deve fazer referência à coluna ao operar nos dados. Por exemplo, embora a TripDistance
propriedade siga convenções de nomenclatura padrão do .NET, o modelo só conhece uma coluna ou recurso conhecido como trip_distance
. Para resolver essa discrepância de nomenclatura, o atributo mapeia ColumnName
a TripDistance
propriedade para uma coluna ou recurso pelo nome trip_distance
.
Para valores numéricos, ML.NET opera apenas em tipos de Single
valor. No entanto, o tipo de dados original de algumas das colunas são inteiros. O OnnxMapType
atributo mapeia tipos entre ONNX e ML.NET.
Para saber mais sobre atributos de dados, consulte o guia ML.NET carregar dados.
Definir esquema de saída do modelo
Uma vez que os dados são processados, ele produz uma saída de um determinado formato. Defina seu esquema de saída de dados. Crie uma nova classe chamada OnnxOutput
com as seguintes propriedades dentro do arquivo Program.cs .
public class OnnxOutput
{
[ColumnName("variable_out1")]
public float[] PredictedFare { get; set; }
}
Semelhante ao OnnxInput
, use o ColumnName
atributo para mapear a variable_out1
saída para um nome PredictedFare
mais descritivo.
Definir um pipeline de previsão
Um pipeline em ML.NET é normalmente uma série de transformações encadeadas que operam nos dados de entrada para produzir uma saída. Para saber mais sobre transformações de dados, consulte o ML.NET guia de transformação de dados.
Criar um novo método chamado
GetPredictionPipeline
dentro daProgram
classestatic ITransformer GetPredictionPipeline(MLContext mlContext) { }
Defina o nome das colunas de entrada e saída. Adicione o seguinte código dentro do
GetPredictionPipeline
método.var inputColumns = new string [] { "vendor_id", "rate_code", "passenger_count", "trip_time_in_secs", "trip_distance", "payment_type" }; var outputColumns = new string [] { "variable_out1" };
Defina seu pipeline. Um
IEstimator
fornece um plano das operações e os esquemas de entrada e saída do seu pipeline.var onnxPredictionPipeline = mlContext .Transforms .ApplyOnnxModel( outputColumnNames: outputColumns, inputColumnNames: inputColumns, ONNX_MODEL_PATH);
Nesse caso, é a única transformação no pipeline, que recebe os nomes das colunas de entrada e saída,
ApplyOnnxModel
bem como o caminho para o arquivo de modelo ONNX.Um
IEstimator
define apenas o conjunto de operações a serem aplicadas aos seus dados. O que opera em seus dados é conhecido comoITransformer
. Use oFit
método para criar um a partir do seuonnxPredictionPipeline
arquivo .var emptyDv = mlContext.Data.LoadFromEnumerable(new OnnxInput[] {}); return onnxPredictionPipeline.Fit(emptyDv);
O
Fit
método espera umaIDataView
entrada as para executar as operações. AnIDataView
é uma maneira de representar dados em ML.NET usando um formato tabular. Como neste caso o pipeline é usado apenas para previsões, você pode fornecer um vazioIDataView
para fornecer as informações necessárias doITransformer
esquema de entrada e saída. O encaixeITransformer
é então devolvido para posterior utilização na sua aplicação.Gorjeta
Neste exemplo, o pipeline é definido e usado dentro do mesmo aplicativo. No entanto, é recomendável que você use aplicativos separados para definir e usar seu pipeline para fazer previsões. Além ML.NET, seus pipelines podem ser serializados e salvos para uso posterior em outros aplicativos de usuário final .NET. ML.NET suporta vários destinos de implantação, como aplicativos de desktop, serviços Web, aplicativos WebAssembly e muito mais. Para saber mais sobre como salvar pipelines, consulte o guia ML.NET salvar e carregar modelos treinados.
Dentro do
Main
método, chame oGetPredictionPipeline
método com os parâmetros necessários.var onnxPredictionPipeline = GetPredictionPipeline(mlContext);
Use o modelo para fazer previsões
Agora que você tem um pipeline, é hora de usá-lo para fazer previsões. ML.NET fornece uma API de conveniência para fazer previsões em uma única instância de dados chamada PredictionEngine
.
Dentro do
Main
método, crie umPredictionEngine
usando oCreatePredictionEngine
método.var onnxPredictionEngine = mlContext.Model.CreatePredictionEngine<OnnxInput, OnnxOutput>(onnxPredictionPipeline);
Crie uma entrada de dados de teste.
var testInput = new OnnxInput { VendorId = "CMT", RateCode = 1, PassengerCount = 1, TripTimeInSecs = 1271, TripDistance = 3.8f, PaymentType = "CRD" };
Use o
predictionEngine
para fazer previsões com base nos novostestInput
dados usando oPredict
método.var prediction = onnxPredictionEngine.Predict(testInput);
Envie o resultado da sua previsão para o console.
Console.WriteLine($"Predicted Fare: {prediction.PredictedFare.First()}");
Use a CLI do .NET para executar seu aplicativo.
dotnet run
O resultado deve ser semelhante à seguinte saída:
Predicted Fare: 15.621523
Para saber mais sobre como fazer previsões no ML.NET, consulte Usar um modelo para fazer previsões.