Создание прогнозов с помощью модели AutoML ONNX в .NET

Из этой статьи вы узнаете, как использовать модель автоматизированного машинного обучения (AutoML) Open Neural Network Exchange (ONNX) для создания прогнозов в консольном приложении .NET Core на C# с помощью ML.NET.

Ml.NET — это кроссплатформенная инфраструктура машинного обучения с открытым исходным кодом для экосистемы .NET, которая позволяет обучать и задействовать пользовательские модели машинного обучения, используя написанный на C# или F# программный код, а также средства, почти не требующие написания кода, такие как Построитель моделей и интерфейс командной строки ML.NET. Эта инфраструктура также является расширяемой и позволяет задействовать другие популярные платформы машинного обучения, такие как TensorFlow и ONNX.

ONNX — это открытый формат для моделей на базе искусственного интеллекта. ONNX поддерживает взаимодействие между разными платформами. Это означает, что модель можно обучить в одной из многих популярных платформ машинного обучения, таких как PyTorch, преобразовать ее в формат ONNX и использовать модель ONNX в другой инфраструктуре, такой как ML.NET. Дополнительные сведения см. на веб-сайте ONNX.

Предварительные требования

Создание консольного приложения на C#

В этом примере для сборки приложения используется .NET Core CLI, но те же задачи можно выполнять с помощью Visual Studio. Дополнительные сведения о .NET Core CLI см. здесь.

  1. Откройте терминал и создайте новое консольное приложение .NET Core на C#. В этом примере имя приложения — AutoMLONNXConsoleApp. При этом создается каталог под тем же именем с содержимым приложения.

    dotnet new console -o AutoMLONNXConsoleApp
    
  2. В окне терминала перейдите в каталог AutoMLONNXConsoleApp.

    cd AutoMLONNXConsoleApp
    

Добавление пакетов программного обеспечения

  1. Установите пакеты NuGet Microsoft.ML, Microsoft.ML.OnnxRuntime и Microsoft.ML.OnnxTransformer с помощью .NET Core CLI.

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

    Эти пакеты содержат зависимости, необходимые для использования модели ONNX в приложении .NET. ML.NET предоставляет API, который использует среду выполнения ONNX для прогнозов.

  2. Откройте файл Program.cs и добавьте в начало следующие инструкции using для создания ссылок на соответствующие пакеты.

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

Добавление ссылки в модель ONNX

Чтобы консольное приложение может получить доступ к модели ONNX, добавьте ее в выходной каталог сборки. Дополнительные сведения об общих элементах MSBuild см. в руководстве по MSBuild.

Добавление ссылки на файл модели ONNX в приложение

  1. Скопируйте модель ONNX в корневой каталог приложения AutoMLONNXConsoleApp.

  2. Откройте файл AutoMLONNXConsoleApp.csproj и добавьте следующее содержимое в узел Project.

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

    В данном случае имя файла модели ONNX — automl-model.onnx.

  3. Откройте файл Program.cs и добавьте указанную ниже строку в класс Program.

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

Инициализация MLContext

В методе Main класса Program создайте новый экземпляр MLContext.

MLContext mlContext = new MLContext();

Класс MLContext является отправной точкой для любых операций ML.NET. В результате инициализации класса mlContext создается среда ML.NET, которая может использоваться всеми объектами в рамках жизненного цикла модели. По существу он аналогичен классу DbContext в Entity Framework.

Определение схемы данных модели

Модель ожидает, что входные и выходные данные будут иметь определенный формат. ML.NET позволяет определить формат данных с помощью классов. Иногда бывает сразу известно, каким он должен быть. В случаях, когда формат данных неизвестен, для проверки модели ONNX можно использовать такие средства, как Netron.

Модель в этом примере использует набор данных о поездках такси Нью-Йорка TLC. Пример данных приведен ниже.

vendor_id rate_code passenger_count trip_time_in_secs trip_distance payment_type fare_amount
VTS 1 1 1140 3,75 % CRD 15.5
VTS 1 1 480 2.72 CRD 10.0
VTS 1 1 1680 7.8 CSH 26,5

Проверка модели ONNX (необязательно)

Для проверки входных и выходных данных модели используйте такой инструмент, как Netron.

  1. Откройте Netron.

  2. В строке верхнего меню выберите Файл > открыть и выберите модель в обозревателе файлов.

  3. Модель откроется. Например, структура модели automl-model.onnx выглядит следующим образом:

    Модель AutoML ONNX в Netron

  4. Выберите последний узел в нижней части графа (в данном случае — variable_out1), чтобы отобразить метаданные модели. На боковой панели указаны ожидаемые входные и выходные значения и типы данных модели. На основе этих сведений составьте схему входных и выходных данных модели.

Создание схемы входных данных модели

Создайте новый класс под названием OnnxInput с указанными ниже свойствами в файле 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; }
}

Каждое из свойств связано со столбцом в наборе данных. Свойства также обладают атрибутами.

Атрибут ColumnName позволяет указать, как система ML.NET должна ссылаться на столбец при работе с данными. Например, хотя свойство TripDistance соответствует стандартным соглашениям об именовании .NET, модели известен только столбец или признак под названием trip_distance. Чтобы устранить несоответствие имен, атрибут ColumnName сопоставляет свойство TripDistance со столбцом или признаком trip_distance.

Для числовых значений ML.NET работает только с типами значений Single. Однако исходные типы данных некоторых столбцов являются целыми числами. Атрибут OnnxMapType сопоставляет типы между ONNX и ML.NET.

Дополнительные сведения об атрибутах данных см. в руководстве по загрузке данных ML.NET.

Создание схемы выходных данных модели

После обработки данных формируются выходные данные определенного формата. Создайте схему вывода данных. Создайте новый класс под названием OnnxOutput с указанными ниже свойствами в файле Program.cs.

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

Аналогично OnnxInput, используйте атрибут ColumnName, чтобы сопоставить выходное значение variable_out1 с более понятным названием PredictedFare.

Создание конвейера прогнозирования

Конвейер в ML.NET обычно представляет собой последовательность связанных преобразований, которые на основе входных данных получают выходные. Дополнительные сведения о преобразовании данных см. в руководстве по преобразованию данных ML.NET.

  1. Создайте новый метод GetPredictionPipeline в классе Program.

    static ITransformer GetPredictionPipeline(MLContext mlContext)
    {
    
    }
    
  2. Задайте названия входных и выходных столбцов. Добавьте следующий код в метод GetPredictionPipeline.

    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. Создайте конвейер. IEstimator содержит схему операций, с также схемы входных и выходных данных конвейера.

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

    В данном случае ApplyOnnxModel является единственным преобразованием в конвейере, которое принимает имена входных и выходных столбцов, а также путь к файлу модели ONNX.

  4. IEstimator определяет только набор операций, применяемых к данным. Операции с данными совершает ITransformer. С помощью метода Fit создайте этот объект из onnxPredictionPipeline.

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

    Метод Fit принимает IDataView в качестве входных данных для выполнения с ними операций. IDataView — способ представления данных в ML.NET в табличном формате. Поскольку в данном случае конвейер используется только для прогнозов, можно передать пустое значение IDataView, чтобы предоставить объекту ITransformer необходимые сведения о схеме входных и выходных данных. После этого возвращается заполненный объект ITransformer для дальнейшего использования в приложении.

    Совет

    В этом примере конвейер определяется и используется в том же приложении. Однако для определения и использования конвейера для прогнозов рекомендуется задействовать отдельные приложения. В ML.NET конвейеры можно сериализовать и сохранить для дальнейшего использования в других приложениях конечных пользователей .NET. ML.NET поддерживает различные целевые объекты развертывания, такие как классические приложения, веб-службы, приложения WebAssembly* и многие другие. Дополнительные сведения о сохранении конвейеров см. в руководстве по сохранению и загрузке обученных моделей ML.NET.

    *WebAssembly поддерживается только в .NET Core 5 и более поздних версиях.

  5. Внутри метода Main вызовите метод GetPredictionPipeline с необходимыми параметрами.

    var onnxPredictionPipeline = GetPredictionPipeline(mlContext);
    

Использование модели для прогнозирования

Теперь, когда у вас есть конвейер, его можно использовать для создания прогнозов. ML.NET предоставляет удобный API PredictionEngine для создания прогнозов на одном экземпляре данных с под названием.

  1. Внутри метода Main создайте PredictionEngine с помощью метода CreatePredictionEngine.

    var onnxPredictionEngine = mlContext.Model.CreatePredictionEngine<OnnxInput, OnnxOutput>(onnxPredictionPipeline);
    
  2. Создайте тестовые входные данные.

    var testInput = new OnnxInput
    {
        VendorId = "CMT",
        RateCode = 1,
        PassengerCount = 1,
        TripTimeInSecs = 1271,
        TripDistance = 3.8f,
        PaymentType = "CRD"
    };
    
  3. С помощью predictionEngine создайте прогноз на основе новых данных testInput с помощью метода Predict.

    var prediction = onnxPredictionEngine.Predict(testInput);
    
  4. Выведите результаты прогноза на консоль.

    Console.WriteLine($"Predicted Fare: {prediction.PredictedFare.First()}");
    
  5. Запустите приложение с помощью .NET Core CLI.

    dotnet run
    

    Результат должен выглядеть примерно так:

    Predicted Fare: 15.621523
    

Дополнительные сведения о создании прогнозов в ML.NET см. в руководстве по использованию модели для создания прогнозов.

Дальнейшие действия