Realización de predicciones con un modelo AutoML de ONNX en .NETMake predictions with an AutoML ONNX model in .NET

En este artículo, aprenderá a usar un modelo de ML automatizado (AutoML) de Neural Network Exchange (ONNX) para hacer predicciones en una aplicación de consola de .NET Core de C# con ML.NET.In this article, you learn how to use an Automated ML (AutoML) Open Neural Network Exchange (ONNX) model to make predictions in a C# .NET Core console application with ML.NET.

ML.NET es un marco de aprendizaje automático multiplataforma de código abierto del ecosistema de .NET que permite entrenar y consumir modelos de aprendizaje automático personalizados utilizando un enfoque Code First de C# o F# junto con herramientas que apenas requieren código, como Model Builder y la CLI de ML.NET.ML.NET is an open-source, cross-platform, machine learning framework for the .NET ecosystem that allows you to train and consume custom machine learning models using a code-first approach in C# or F# as well as through low-code tooling like Model Builder and the ML.NET CLI. Este marco puede ampliarse y permite utilizar otros marcos de aprendizaje automático populares, como TensorFlow y ONNX.The framework is also extensible and allows you to leverage other popular machine learning frameworks like TensorFlow and ONNX.

ONNX es un formato de código abierto para modelos de IA.ONNX is an open-source format for AI models. ONNX admite la interoperabilidad entre marcos.ONNX supports interoperability between frameworks. Esto significa que puede entrenar un modelo en uno de los muchos marcos de aprendizaje automático que son más conocidos, como PyTorch, convertirlo a un formato ONNX y consumir el modelo de ONNX en un marco de trabajo diferente, como ML.NET.This means you can train a model in one of the many popular machine learning frameworks like PyTorch, convert it into ONNX format, and consume the ONNX model in a different framework like ML.NET. Para más información, visite el sitio web de ONNX.To learn more, visit the ONNX website.

Requisitos previosPrerequisites

Creación de una aplicación de consola en C#Create a C# console application

En este ejemplo, va a utilizar la CLI de .NET Core para compilar la aplicación, pero puede realizar las mismas tareas con Visual Studio.In this sample, you use the .NET Core CLI to build your application but you can do the same tasks using Visual Studio. Más información sobre la CLI de .NET Core.Learn more about the .NET Core CLI.

  1. Abra un terminal y cree una aplicación de consola de .NET Core en C#.Open a terminal and create a new C# .NET Core console application. En este ejemplo, el nombre de la aplicación es AutoMLONNXConsoleApp.In this example, the name of the application is AutoMLONNXConsoleApp. Se creará un directorio que tendrá el mismo nombre con el contenido de la aplicación.A directory is created by that same name with the contents of your application.

    dotnet new console -o AutoMLONNXConsoleApp
    
  2. En el terminal, vaya al directorio AutoMLONNXConsoleApp.In the terminal, navigate to the AutoMLONNXConsoleApp directory.

    cd AutoMLONNXConsoleApp
    

Incorporación de los paquetes de softwareAdd software packages

  1. Instale los paquetes de NuGet Microsoft.ML, Microsoft.ML.OnnxRuntime y Microsoft.ML.OnnxTransformer mediante la CLI de .NET Core.Install the Microsoft.ML, Microsoft.ML.OnnxRuntime, and Microsoft.ML.OnnxTransformer NuGet packages using the .NET Core CLI.

    dotnet add package Microsoft.ML
    dotnet add package Microsoft.ML.OnnxRuntime
    dotnet add package Microsoft.ML.OnnxTransformer
    

    Estos paquetes contienen las dependencias necesarias para usar un modelo de ONNX en una aplicación .NET.These packages contain the dependencies required to use an ONNX model in a .NET application. ML.NET cuenta con una API que usa el entorno de ejecución de ONNX para realizar las predicciones.ML.NET provides an API that uses the ONNX runtime for predictions.

  2. Abra el archivo Program.cs y agregue al comienzo las siguientes instrucciones using para hacer referencia a los paquetes correspondientes.Open the Program.cs file and add the following using statements at the top to reference the appropriate packages.

    using System.Linq;
    using Microsoft.ML;
    using Microsoft.ML.Data;
    using Microsoft.ML.Transforms.Onnx;
    

Incorporación de una referencia al modelo de ONNXAdd a reference to the ONNX model

Una forma de conseguir que la aplicación de consola acceda al modelo de ONNX es agregarla al directorio de salida de la compilación.A way for the console application to access the ONNX model is to add it to the build output directory. Para más información sobre los elementos comunes de MSBuild, consulte la guía de MSBuild.To learn more about MSBuild common items, see the MSBuild guide.

Agregue una referencia al archivo del modelo de ONNX de la aplicación.Add a reference to your ONNX model file in your application

  1. Copie el modelo ONNX en el directorio raíz AutoMLONNXConsoleApp de la aplicación.Copy your ONNX model to your application's AutoMLONNXConsoleApp root directory.

  2. Abra el archivo AutoMLONNXConsoleApp. csproj y agregue el siguiente contenido dentro del nodo Project.Open the AutoMLONNXConsoleApp.csproj file and add the following content inside the Project node.

    <ItemGroup>
        <None Include="automl-model.onnx">
            <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
        </None>
    </ItemGroup>
    

    En este caso, el nombre del archivo de modelo de ONNX es automl-model.onnx.In this case, the name of the ONNX model file is automl-model.onnx.

  3. Abra el archivo Program.cs y agregue la línea siguiente dentro de la clase Program.Open the Program.cs file and add the following line inside the Program class.

    static string ONNX_MODEL_PATH = "automl-model.onnx";
    

Inicialización de MLContextInitialize MLContext

Dentro del método Main de la clase Program, cree una nueva instancia de MLContext.Inside the Main method of your Program class, create a new instance of MLContext.

MLContext mlContext = new MLContext();

La clase MLContext es el punto de partida de todas las operaciones de ML.NET, mientras que la inicialización de mlContext crea un nuevo entorno de ML.NET que puede compartirse durante el ciclo de vida del modelo.The MLContext class is a starting point for all ML.NET operations, and initializing mlContext creates a new ML.NET environment that can be shared across the model lifecycle. Conceptualmente, es similar a DbContext en Entity Framework.It's similar, conceptually, to DbContext in Entity Framework.

Definición del esquema de datos del modeloDefine the model data schema

El modelo espera que los datos de entrada y salida estén en un formato específico.Your model expects your input and output data in a specific format. ML.NET permite definir el formato de los datos mediante clases.ML.NET allows you to define the format of your data via classes. En ocasiones, es posible que ya sepa cuál es el formato.Sometimes you may already know what that format looks like. De lo contrario, puede usar herramientas como Netron para inspeccionar el modelo de ONNX.In cases when you don't know the data format, you can use tools like Netron to inspect your ONNX model.

El modelo de este ejemplo utiliza la información del conjunto de datos NYC TLC Taxi Trip.The model used in this sample uses data from the NYC TLC Taxi Trip dataset. A continuación, se muestra un ejemplo de los datos:A sample of the data can be seen below:

vendor_idvendor_id rate_coderate_code passenger_countpassenger_count trip_time_in_secstrip_time_in_secs trip_distancetrip_distance payment_typepayment_type fare_amountfare_amount
VTSVTS 11 11 11401140 3,753.75 CRDCRD 15,515.5
VTSVTS 11 11 480480 2.722.72 CRDCRD 10.010.0
VTSVTS 11 11 16801680 7.87.8 CSHCSH 26,526.5

Inspección del modelo de ONNX (opcional)Inspect the ONNX model (optional)

Utilice una herramienta como Netron para inspeccionar las entradas y salidas del modelo.Use a tool like Netron to inspect your model's inputs and outputs.

  1. Abra Netron.Open Netron.

  2. En la barra de menús superior, seleccione File > Open (Archivo > Abrir) y use el explorador de archivos para seleccionar el modelo.In the top menu bar, select File > Open and use the file browser to select your model.

  3. Se abre el modelo.Your model opens. Por ejemplo, la estructura del modelo automl-model.onnx se parece a la siguiente:For example, the structure of the automl-model.onnx model looks like the following:

    Modelo AutoML de ONNX en Netron

  4. Seleccione el último nodo de la parte inferior del grafo (variable_out1 en este caso) para ver los metadatos del modelo.Select the last node at the bottom of the graph (variable_out1 in this case) to display the model's metadata. Las entradas y salidas de la barra lateral representan las entradas, salidas y tipos de datos esperados del modelo.The inputs and outputs on the sidebar show you the model's expected inputs, outputs, and data types. Utilice esta información para definir el esquema de entrada y salida del modelo.Use this information to define the input and output schema of your model.

Definición del esquema de entrada del modeloDefine model input schema

Cree una nueva clase llamada OnnxInput con las siguientes propiedades en el archivo Program.cs.Create a new class called OnnxInput with the following properties inside the Program.cs file.

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 una de las propiedades se asigna a una columna del conjunto de datos.Each of the properties maps to a column in the dataset. Además, se incluirán atributos en las notas de las propiedades.The properties are further annotated with attributes.

El atributo ColumnName permite especificar cómo ML.NET debe hacer referencia a la columna al trabajar con los datos.The ColumnName attribute lets you specify how ML.NET should reference the column when operating on the data. Por ejemplo, aunque la propiedad TripDistance sigue las convenciones de nomenclatura estándar de .NET, el modelo solo tiene información de una columna o característica llamada trip_distance.For example, although the TripDistance property follows standard .NET naming conventions, the model only knows of a column or feature known as trip_distance. Para solucionar esta discrepancia de nomenclatura, el atributo ColumnName asigna la propiedad TripDistance a una columna o característica con el nombre trip_distance.To address this naming discrepancy, the ColumnName attribute maps the TripDistance property to a column or feature by the name trip_distance.

En el caso de los valores numéricos, ML.NET solo trabaja con tipos de valor Single.For numerical values, ML.NET only operates on Single value types. Sin embargo, el tipo de datos original de algunas de las columnas es un entero.However, the original data type of some of the columns are integers. El atributo OnnxMapType asigna tipos entre ONNX y ML.NET.The OnnxMapType attribute maps types between ONNX and ML.NET.

Para más información sobre los atributos de datos, consulte la guía de datos de carga de ML.NET.To learn more about data attributes, see the ML.NET load data guide.

Definición del esquema de salida del modeloDefine model output schema

Una vez procesados los datos, se genera una salida con un formato determinado.Once the data is processed, it produces an output of a certain format. Defina el esquema de salida de los datos.Define your data output schema. Cree una nueva clase llamada OnnxOutput con las siguientes propiedades en el archivo Program.cs.Create a new class called OnnxOutput with the following properties inside the Program.cs file.

public class OnnxOutput
{
    [ColumnName("variable_out1")]
    public float[] PredictedFare { get; set; }
}

Al igual que con OnnxInput, utilice el atributo ColumnName para asignar a la salida variable_out1 un nombre más descriptivo: PredictedFare.Similar to OnnxInput, use the ColumnName attribute to map the variable_out1 output to a more descriptive name PredictedFare.

Definición de una canalización de prediccionesDefine a prediction pipeline

Normalmente, las canalizaciones de ML.NET son una serie de transformaciones en cadena que se realizan en los datos de entrada para generar una salida.A pipeline in ML.NET is typically a series of chained transformations that operate on the input data to produce an output. Para más información sobre las transformaciones de datos, consulte la guía de transformación de datos de ML.NET.To learn more about data transformations, see the ML.NET data transformation guide.

  1. Cree un nuevo método llamado GetPredictionPipeline dentro de la clase Program.Create a new method called GetPredictionPipeline inside the Program class

    static ITransformer GetPredictionPipeline(MLContext mlContext)
    {
    
    }
    
  2. Defina el nombre de las columnas de entrada y de salida.Define the name of the input and output columns. Agregue el código siguiente dentro del método GetPredictionPipeline.Add the following code inside the GetPredictionPipeline method.

    var inputColumns = new string []
    {
        "vendor_id", "rate_code", "passenger_count", "trip_time_in_secs", "trip_distance", "payment_type"
    };
    
    var outputColumns = new string [] { "variable_out1" };
    
  3. Defina la canalización.Define your pipeline. Un objeto IEstimator proporciona un proyecto de las operaciones y de los esquemas de entrada y salida de la canalización.An IEstimator provides a blueprint of the operations, input, and output schemas of your pipeline.

    var onnxPredictionPipeline =
        mlContext
            .Transforms
            .ApplyOnnxModel(
                outputColumnNames: outputColumns,
                inputColumnNames: inputColumns,
                ONNX_MODEL_PATH);
    

    En este caso, ApplyOnnxModel es la única transformación de la canalización, que toma los nombres de las columnas de entrada y salida, y la ruta de acceso al archivo del modelo de ONNX.In this case, ApplyOnnxModel is the only transform in the pipeline, which takes in the names of the input and output columns as well as the path to the ONNX model file.

  4. Los objetos IEstimator solo definen el conjunto de operaciones que se van a aplicar a los datos.An IEstimator only defines the set of operations to apply to your data. Lo que realmente trabaja con los datos se conoce como ITransformer.What operates on your data is known as an ITransformer. Utilice el método Fit para crear uno a partir de onnxPredictionPipeline.Use the Fit method to create one from your onnxPredictionPipeline.

    var emptyDv = mlContext.Data.LoadFromEnumerable(new OnnxInput[] {});
    
    return onnxPredictionPipeline.Fit(emptyDv);
    

    El método Fit espera un objeto IDataView como entrada para realizar las operaciones.The Fit method expects an IDataView as input to perform the operations on. Los objetos IDataView permiten representar los datos en ML.NET con un formato tabular.An IDataView is a way to represent data in ML.NET using a tabular format. Dado que en este caso la canalización solo se usa para realizar predicciones, puede proporcionar un objeto IDataView para que ITransformer tenga la información necesaria del esquema de entrada y de salida.Since in this case the pipeline is only used for predictions, you can provide an empty IDataView to give the ITransformer the necessary input and output schema information. A continuación, se devolverá el objeto ITransformer al que se le ha aplicado el método Fit para que siga utilizándose en la aplicación.The fitted ITransformer is then returned for further use in your application.

    Sugerencia

    En este ejemplo, la canalización se define y se utiliza dentro de la misma aplicación.In this sample, the pipeline is defined and used within the same application. Sin embargo, cuando se creen predicciones, se recomienda usar diferentes aplicaciones para definir y usar la canalización.However, it is recommended that you use separate applications to define and use your pipeline to make predictions. En ML.NET, las canalizaciones se pueden serializar y guardar para utilizarse en otras aplicaciones NET dirigidas a usuarios finales.In ML.NET your pipelines can be serialized and saved for further use in other .NET end-user applications. ML.NET admite varios destinos de implementación, como aplicaciones de escritorio, servicios web, aplicaciones de WebAssembly * y muchos otros.ML.NET supports various deployment targets such as desktop applications, web services, WebAssembly applications*, and many more. Para más información acerca de cómo guardar las canalizaciones, consulte la guía para guardar y cargar modelos entrenados de ML.NET.To learn more about saving pipelines, see the ML.NET save and load trained models guide.

    *WebAssembly solo se admite en .NET Core 5 o versiones posteriores*WebAssembly is only supported in .NET Core 5 or greater

  5. En el método Main, llame al método GetPredictionPipeline con los parámetros necesarios.Inside the Main method, call the GetPredictionPipeline method with the required parameters.

    var onnxPredictionPipeline = GetPredictionPipeline(mlContext);
    

Uso del modelo para realizar prediccionesUse the model to make predictions

Ahora que tiene una canalización, es el momento de utilizarla para realizar predicciones.Now that you have a pipeline, it's time to use it to make predictions. ML.NET dispone de una práctica API que permite llevar a cabo predicciones en una única instancia de datos denominada PredictionEngine.ML.NET provides a convenience API for making predictions on a single data instance called PredictionEngine.

  1. En el método Main, cree un objeto PredictionEngine utilizando el método CreatePredictionEngine.Inside the Main method, create a PredictionEngine by using the CreatePredictionEngine method.

    var onnxPredictionEngine = mlContext.Model.CreatePredictionEngine<OnnxInput, OnnxOutput>(onnxPredictionPipeline);
    
  2. Cree una entrada de datos de prueba.Create a test data input.

    var testInput = new OnnxInput
    {
        VendorId = "CMT",
        RateCode = 1,
        PassengerCount = 1,
        TripTimeInSecs = 1271,
        TripDistance = 3.8f,
        PaymentType = "CRD"
    };
    
  3. Utilice el objeto predictionEngine para hacer predicciones basadas en los nuevos datos de testInput con el método Predict.Use the predictionEngine to make predictions based on the new testInput data using the Predict method.

    var prediction = onnxPredictionEngine.Predict(testInput);
    
  4. Envíe la salida de la predicción a la consola.Output the result of your prediction to the console.

    Console.WriteLine($"Predicted Fare: {prediction.PredictedFare.First()}");
    
  5. Use la CLI de .NET Core para ejecutar la aplicación.Use the .NET Core CLI to run your application.

    dotnet run
    

    La salida debe ser parecida a esta:The result should look as similar to the following output:

    Predicted Fare: 15.621523
    

Para más información acerca de cómo realizar predicciones en ML.NET, consulte la guía sobre el uso de un modelo para hacer predicciones.To learn more about making predictions in ML.NET, see the use a model to make predictions guide.

Pasos siguientesNext steps