Это простое руководство предоставит вам необходимые знания о переобучении моделей ML.NET.
ПРОБЛЕМА
Как только я начал играть с библиотекой ML.NET, я попытался использовать несколько руководств Microsoft, чтобы иметь возможность определить и использовать модель, отвечающую всем моим требованиям. К сожалению, в этих руководствах есть неясная часть, которая, вероятно, сбивает с толку новичков в библиотеке машинного обучения, которые еще не знакомы с ее функциями. Я говорю о примере переобучения модели, который опускает важные детали в своем объяснении.
РЕШЕНИЕ
Я собрал простой пример кода, иллюстрирующий процесс переобучения. Давайте рассмотрим пример шаг за шагом и объясним каждый блок кода. Вы также можете найти исходный код здесь.
Конфигурация моего проекта, отраженная в файле .csproj, выглядит следующим образом:
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>net7.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <Nullable>enable</Nullable> </PropertyGroup> <ItemGroup> <PackageReference Include="Microsoft.ML" Version="2.0.0" /> </ItemGroup> </Project>
В моем файле Program.cs в классе Program я определил два дополнительных класса, которые представляют типы данных, используемые моей моделью, а также статический метод, который инициирует тренировочный процесс.
namespace Tutorial { class Program { private class HouseData { public float Size { get; set; } public float Price { get; set; } } private class Prediction { [ColumnName("Score")] public float Price { get; set; } } public static void Main() { ... } } }
Прежде чем мы углубимся в содержание метода Main, я хотел бы высказать несколько соображений.
- Не все алгоритмы могут быть переобучены. Список переобучаемых алгоритмов смотрите здесь.
- Этот учебник становится более полезным, если вы используете функцию сохранить-загрузить вашей модели. Путеводитель можно найти здесь.
- Свяжите свою модель в цепочку независимых трансформеров (мы опишем позже в этом руководстве). Итак, большую часть времени это не структура, а набор структур.
Наша первая остановка в коде — создание MLContext:
MLContext mlContext = new MLContext();
Затем мы должны подготовить некоторые обучающие данные для нашей модели:
// 1. Import or create training data HouseData[] houseData = { new HouseData() { Size = 1.1F, Price = 1.2F }, new HouseData() { Size = 1.9F, Price = 2.3F }, new HouseData() { Size = 2.8F, Price = 3.0F }, new HouseData() { Size = 3.4F, Price = 3.7F } }; IDataView trainingData = mlContext.Data.LoadFromEnumerable(houseData); // Define data preparation estimator IEstimator<ITransformer> dataPrepEstimator = mlContext.Transforms.Concatenate( "Features", new[] { "Size" } ); // Create data preparation transformer ITransformer dataPrepTransformer = dataPrepEstimator.Fit(trainingData); // Pre-process data using data prep operations IDataView transformedData = dataPrepTransformer.Transform(trainingData);
Обратите внимание, что на этом шаге нам нужно вызвать метод Fit для оценщика, чтобы иметь возможность создать объект ITransformer. Трансформатор станет «первой ступенью» в цепочке модели.
Теперь нам нужно определить алгоритм обучения (тренажер) для модели. Этого можно легко добиться, если использовать следующий код:
// 2. Specify model trainer // Define regression algorithm estimator OnlineGradientDescentTrainer? regressionEstimator = mlContext.Regression.Trainers.OnlineGradientDescent( labelColumnName: "Price", numberOfIterations: 100 ); // Create algorithm preparation transformer var regressionTransformer = regressionEstimator.Fit(transformedData);
Мы снова используем метод Fit, потому что он станет «вторым этапом» в цепочке модели.
Наконец, цепочка модели выглядит так:
// 3. Create model var model = dataPrepTransformer.Append(regressionTransformer);
Мы можем протестировать модель и вывести ее вывод на консоль.
// 4. Make a prediction var size = new HouseData() { Size = 2.5F }; var price = mlContext.Model .CreatePredictionEngine<HouseData, Prediction>(model) .Predict(size); Console.WriteLine( $"//4 Predicted price for size: {size.Size * 1000} sq ft= {price.Price * 100:C}k" ); //4 Predicted price for size: 2500 sq ft= £276.98k
На этом этапе мы можем сохранить наши трансформеры, чтобы переобучить и использовать их позже.
// 5. Save model and and data transformer string regressionTransformerlPath = "./models/TutorialRegressionTransformer.zip"; string dataTransformerPath = "./models/TutorialDataTransformer.zip"; // Save Data Prep Transformer mlContext.Model.Save(dataPrepTransformer, trainingData.Schema, dataTransformerPath); // Save Trained Model mlContext.Model.Save( regressionTransformer, transformedData.Schema, regressionTransformerlPath ); // 5.1 (OPTIONAL) Load model and data transformer // Define DataViewSchema of data prep pipeline and trained model DataViewSchema dataPrepPipelineSchema, modelSchema; // Load data preparation pipeline dataPrepTransformer = mlContext.Model.Load( dataTransformerPath, out dataPrepPipelineSchema ); // Load trained model regressionTransformer = (RegressionPredictionTransformer<LinearRegressionModelParameters>) mlContext.Model.Load(regressionTransformerlPath, out modelSchema);
Для переобучения модели необходимо получить две вещи:
- Новый набор данных
- Исходные параметры модели
Мы можем создать новый набор данных точно так же, как создали набор данных transformedData.
// 6. Get new data (repeat step 1) HouseData[] newDataSet = { new HouseData { Size = 4F, Price = 3F }, new HouseData { Size = 2F, Price = 2.3F } }; IDataView newTrainingData = mlContext.Data.LoadFromEnumerable(newDataSet); // Preprocess Data IDataView transformedNewData = dataPrepTransformer.Transform(newTrainingData);
Получение исходного параметра является немного более сложной задачей.
// 7. Extract trained model parameters // model.Last() is used here to extract weights and biases from model // as it is added to the end of the chain var originalModelParameters = ((ISingleFeaturePredictionTransformer<object>)model.Last()).Model as LinearRegressionModelParameters; var retrainedRegressionTransformer = regressionEstimator.Fit( transformedNewData, originalModelParameters );
На этом этапе мы также воссоздаем преобразователь регрессии, поскольку он должен использовать обновленные данные. Обратите внимание, что мы передаем исходные параметры в метод Fit. Эта опция доступна только для переобучаемых алгоритмов.
Пришло время воссоздать модель.
// 8. Recreate model model = dataPrepTransformer.Append(retrainedRegressionTransformer);
В качестве последнего шага мы можем протестировать обновленную модель.
// 9 Make a prediction on re-trained model var newPrice = mlContext.Model .CreatePredictionEngine<HouseData, Prediction>(model) .Predict(size); Console.WriteLine( $"//9 Predicted price for size: {size.Size * 1000} sq ft= {newPrice.Price * 100:C}k" ); //9 Predicted price for size: 2500 sq ft= £228.00k
ЗАКЛЮЧЕНИЕ
Следуя этим простым шагам, модель можно легко сохранить, загрузить и повторно обучить с новыми данными.