Поделиться через


Руководство. Обучение модели классификации ML.NET для классификации изображений

Узнайте, как обучить модель классификации для классификации изображений с помощью предварительно обученной модели TensorFlow для обработки изображений.

Модель TensorFlow была обучена классифицировать изображения на тысячи категорий. Так как модель TensorFlow знает, как распознавать шаблоны в изображениях, модель ML.NET может использовать часть ее в конвейере для преобразования необработанных изображений в функции или входные данные для обучения модели классификации.

В этом руководстве описано, как:

  • Общие сведения о проблеме
  • Включение предварительно обученной модели TensorFlow в конвейер ML.NET
  • Обучение и оценка модели ML.NET
  • Классификация тестового образа

Исходный код для этого руководства можно найти в репозитории dotnet/samples. По умолчанию конфигурация проекта .NET для этого руководства предназначена для .NET Core 2.2.

Необходимые условия

Выберите нужную задачу машинного обучения

Глубокое обучение

Глубокое обучение — это подмножество машинного обучения, которое является революционизирующими областями, такими как компьютерное зрение и распознавание речи.

Модели глубокого обучения обучены с помощью больших наборов помеченных данных и нейронных сетей, содержащих несколько уровней обучения. Глубокое обучение:

  • Лучше работает над некоторыми задачами, такими как компьютерное зрение.
  • Требуется огромное количество обучающих данных.

Классификация изображений — это определенная задача классификации, которая позволяет автоматически классифицировать изображения в категории, такие как:

  • Обнаружение человеческого лица в изображении или его отсутствие.
  • Обнаружение кошек и собак.

Или, как показано на следующих изображениях, определяющие, является ли изображение едой, игрушкой или бытовым прибором.

изображение пиццы изображение медведя Тедди изображение тостера

Заметка

Предыдущие изображения принадлежат к Wikimedia Commons и атрибутированы следующим образом:

Для обучения модели классификации изображений с нуля требуется установка миллионов параметров, тонна помеченных обучающих данных и огромное количество вычислительных ресурсов (сотни часов GPU). Хотя это не так эффективно, как обучение пользовательской модели с нуля, использование предварительно обученной модели позволяет облегчить этот процесс, работая с тысячами изображений в отличие от миллионов помеченных изображений, и построить настраиваемую модель довольно быстро (в течение часа на компьютере без GPU). В этом руководстве этот процесс масштабируется еще больше, используя только дюжину обучающих изображений.

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

  • Пища
  • Игрушка
  • Приспособление

В этом руководстве используется модель глубокого обучения TensorFlow Inception, популярная модель распознавания изображений, обученная на наборе данных ImageNet. Модель TensorFlow классифицирует все изображения на тысячи классов, таких как "Umbrella", "Джерси" и "Посудомоечная машина".

Так как Inception model уже предварительно обучены на тысячах различных изображений, внутри нее содержатся функции изображений, необходимые для идентификации изображений. Мы можем задействовать эти характеристики внутренних изображений в модели для обучения новой модели с значительно меньшим количеством классов.

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

преобразование TensorFlow ML.NET архитектурная схема

Многоклассовая классификация

После использования модели TensorFlow Inception для извлечения признаков, подходящих в качестве входных данных для классического алгоритма машинного обучения, вы добавляете многоклассовый классификатор ML.NET .

Конкретный алгоритм тренировки, используемый в этом случае, это многономинальный алгоритм логистической регрессии .

Алгоритм, реализованный этим тренером, хорошо работает над проблемами с большим количеством функций, что относится к модели глубокого обучения, работающей на данных изображения.

Дополнительные сведения см. в разделе Глубокое обучение против машинного обучения.

Данные

Существует два источника данных: файл .tsv и файлы изображений. Файл tags.tsv содержит два столбца: первый определяется как ImagePath, а второй — это Label, соответствующий изображению. В следующем примере файла нет строки заголовка и выглядит следующим образом:

broccoli.jpg	food
pizza.jpg	food
pizza2.jpg	food
teddy2.jpg	toy
teddy3.jpg	toy
teddy4.jpg	toy
toaster.jpg	appliance
toaster2.png	appliance

Изображения для обучения и тестирования находятся в папках ресурсов, которые вы скачаете в ZIP-файле. Эти изображения принадлежат Wikimedia Commons.

Wikimedia Commons— репозиторий бесплатных медиафайлов. Получено 10:48, 17 октября 2018 г. из: https://commons.wikimedia.org/wiki/Pizzahttps://commons.wikimedia.org/wiki/Toasterhttps://commons.wikimedia.org/wiki/Teddy_bear

Настройка

Создание проекта

  1. Создайте консольное приложение C# с именем TransferLearningTF. Нажмите кнопку Далее.

  2. Выберите .NET 8 в качестве платформы для использования. Нажмите кнопку Создать.

  3. Установите пакет NuGetMicrosoft.ML:

    Заметка

    В этом примере используется последняя стабильная версия упомянутых пакетов NuGet, если не указано иное.

    • В обозревателе решений щелкните проект правой кнопкой мыши и выберите Управление пакетами NuGet.
    • Выберите "nuget.org" в качестве источника пакета, перейдите на вкладку "Обзор", найдите Microsoft.ML.
    • Нажмите кнопку Установить.
    • Нажмите кнопку ОК в окне предварительного просмотра изменений .
    • Нажмите кнопку 'Принять' в диалоговом окне принятия лицензии, если вы согласны с условиями лицензии для указанных пакетов.
    • Повторите эти действия для Microsoft.ML.ImageAnalytics, SciSharp.TensorFlow.Redistи Microsoft.ML.TensorFlow.

Скачивание ресурсов

  1. Скачайте ZIP-файл каталога ресурсов проектаи распакуйте его.

  2. Скопируйте каталог assets в каталог проекта TransferLearningTF. Этот каталог и его подкаталоги содержат данные и файлы поддержки (за исключением модели Inception, которую вы скачаете и добавите на следующем этапе), которые необходимы для этого руководства.

  3. Скачайте модель Inception и распакуйте её.

  4. Скопируйте содержимое только что распакованного каталога inception5h в каталог проекта TransferLearningTFassets/inception. Этот каталог содержит модель и дополнительные файлы поддержки, необходимые для этого руководства, как показано на следующем рисунке:

    содержимое каталога Inception

  5. В обозревателе решений щелкните правой кнопкой мыши каждый из файлов в каталоге ресурсов и подкаталогах и выберите Свойства. В разделе Advancedизмените значение Копировать в выходной каталог на Копировать только если файл новее.

Создание классов и определение путей

  1. Добавьте следующие дополнительные директивы using в начало файла Program.cs:

    using Microsoft.ML;
    using Microsoft.ML.Data;
    
  2. Добавьте следующий код в строку справа от директив using, чтобы указать пути к ресурсу:

    string _assetsPath = Path.Combine(Environment.CurrentDirectory, "assets");
    string _imagesFolder = Path.Combine(_assetsPath, "images");
    string _trainTagsTsv = Path.Combine(_imagesFolder, "tags.tsv");
    string _testTagsTsv = Path.Combine(_imagesFolder, "test-tags.tsv");
    string _predictSingleImage = Path.Combine(_imagesFolder, "toaster3.jpg");
    string _inceptionTensorFlowModel = Path.Combine(_assetsPath, "inception", "tensorflow_inception_graph.pb");
    
  3. Создайте классы для входных данных и прогнозов.

    public class ImageData
    {
        [LoadColumn(0)]
        public string? ImagePath;
    
        [LoadColumn(1)]
        public string? Label;
    }
    

    ImageData является классом данных входного образа и имеет следующие String поля:

    • ImagePath содержит имя файла образа.
    • Label содержит значение метки изображения.
  4. Добавьте новый класс в проект для ImagePrediction:

    public class ImagePrediction : ImageData
    {
        public float[]? Score;
    
        public string? PredictedLabelValue;
    }
    

    ImagePrediction — это класс прогнозирования изображений и имеет следующие поля:

    • Score содержит процент достоверности для заданной классификации изображений.
    • PredictedLabelValue содержит значение для прогнозируемой метки классификации изображений.

    ImagePrediction — это класс, используемый для прогнозирования после обучения модели. Он имеет string (ImagePath) для пути к изображению. Label используется для повторного использования и обучения модели. PredictedLabelValue используется во время прогнозирования и оценки. Для оценки используются входные данные с данными обучения, прогнозируемые значения и модель.

Инициализация переменных

  1. Инициализируйте переменную mlContext новым экземпляром MLContext. Замените строку Console.WriteLine("Hello World!") следующим кодом:

    MLContext mlContext = new MLContext();
    

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

Создайте структуру для параметров модели Inception

  1. Inception модель имеет несколько параметров, которые необходимо передать. Создайте структуру для сопоставления значений параметров с понятными именами со следующим кодом сразу после инициализации переменной mlContext:

    struct InceptionSettings
    {
        public const int ImageHeight = 224;
        public const int ImageWidth = 224;
        public const float Mean = 117;
        public const float Scale = 1;
        public const bool ChannelsLast = true;
    }
    

Создайте метод утилиты отображения

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

  1. Создайте метод DisplayResults() сразу после структуры InceptionSettings с помощью следующего кода:

    void DisplayResults(IEnumerable<ImagePrediction> imagePredictionData)
    {
    
    }
    
  2. Заполните текст метода DisplayResults:

    foreach (ImagePrediction prediction in imagePredictionData)
    {
        Console.WriteLine($"Image: {Path.GetFileName(prediction.ImagePath)} predicted as: {prediction.PredictedLabelValue} with score: {prediction.Score?.Max()} ");
    }
    

Создание метода для прогнозирования

  1. Создайте метод ClassifySingleImage() непосредственно перед методом DisplayResults() с помощью следующего кода:

    void ClassifySingleImage(MLContext mlContext, ITransformer model)
    {
    
    }
    
  2. Создайте объект ImageData, который содержит полный путь и имя файла изображения для единственного ImagePath. Добавьте следующий код в качестве следующих строк в методе ClassifySingleImage():

    var imageData = new ImageData()
    {
        ImagePath = _predictSingleImage
    };
    
  3. Создайте один прогноз, добавив следующий код в следующую строку в методе ClassifySingleImage:

    // Make prediction function (input = ImageData, output = ImagePrediction)
    var predictor = mlContext.Model.CreatePredictionEngine<ImageData, ImagePrediction>(model);
    var prediction = predictor.Predict(imageData);
    

    Чтобы получить прогноз, используйте метод Predict(). PredictionEngine — это удобный API, который позволяет выполнять прогнозирование на одном экземпляре данных. PredictionEngine не является потокобезопасным. Его можно использовать в однопоточных или прототипных средах. Для повышения производительности и потокобезопасности в промышленных средах используйте службу PredictionEnginePool, которая создает ObjectPool объектов PredictionEngine для использования во всем приложении. В этом руководстве показано, как использовать и PredictionEnginePool в веб-API ASP.NET Core.

    Заметка

    PredictionEnginePool расширение услуги в настоящее время находится в предварительной версии.

  4. Отображение результата прогнозирования в следующей строке кода в методе ClassifySingleImage():

    Console.WriteLine($"Image: {Path.GetFileName(imageData.ImagePath)} predicted as: {prediction.PredictedLabelValue} with score: {prediction.Score?.Max()} ");
    

Постройте конвейер модели ML.NET

Конвейер модели ML.NET — это цепочка оценщиков. Во время строительства конвейера выполнение не выполняется. Объекты оценки создаются, но не выполняются.

  1. Добавление метода для создания модели

    Этот метод является сердцем учебника. Он создает конвейер для модели и обучает конвейер для создания модели ML.NET. Он также оценивает модель на некоторых ранее невидимых тестовых данных.

    Создайте метод GenerateModel() сразу после структуры InceptionSettings и непосредственно перед методом DisplayResults() с помощью следующего кода:

    ITransformer GenerateModel(MLContext mlContext)
    {
    
    }
    
  2. Добавьте оценщики для загрузки, изменения размера и извлечения пикселей из данных изображения:

    IEstimator<ITransformer> pipeline = mlContext.Transforms.LoadImages(outputColumnName: "input", imageFolder: _imagesFolder, inputColumnName: nameof(ImageData.ImagePath))
                    // The image transforms transform the images into the model's expected format.
                    .Append(mlContext.Transforms.ResizeImages(outputColumnName: "input", imageWidth: InceptionSettings.ImageWidth, imageHeight: InceptionSettings.ImageHeight, inputColumnName: "input"))
                    .Append(mlContext.Transforms.ExtractPixels(outputColumnName: "input", interleavePixelColors: InceptionSettings.ChannelsLast, offsetImage: InceptionSettings.Mean))
    

    Данные изображения должны обрабатываться в формате, который ожидает модель TensorFlow. В этом случае изображения загружаются в память, изменяются до согласованного размера, а пиксели извлекаются в числовые векторы.

  3. Добавьте оценщик, чтобы загрузить модель TensorFlow и произвести оценку:

    .Append(mlContext.Model.LoadTensorFlowModel(_inceptionTensorFlowModel).
        ScoreTensorFlowModel(outputColumnNames: new[] { "softmax2_pre_activation" }, inputColumnNames: new[] { "input" }, addBatchDimensionInput: true))
    

    Этот этап в конвейере загружает модель TensorFlow в память, а затем обрабатывает вектор значений пикселей через сеть модели TensorFlow. Применение входных данных к модели глубокого обучения и генерация выходных данных называется Scoring. При использовании модели в целом оценка делает вывод или прогноз.

    В этом случае используется все модели TensorFlow, кроме последнего слоя, который является слоем, который делает вывод. Выходные данные предпоследнего слоя обозначены как softmax_2_preactivation. Выходные данные этого слоя фактически являются вектором признаков, характеризующих исходные входные изображения.

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

  4. Добавьте оценщик для сопоставления строковых меток в обучающих данных со значениями целочисленных ключей:

    .Append(mlContext.Transforms.Conversion.MapValueToKey(outputColumnName: "LabelKey", inputColumnName: "Label"))
    

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

  5. Добавьте алгоритм обучения ML.NET:

    .Append(mlContext.MulticlassClassification.Trainers.LbfgsMaximumEntropy(labelColumnName: "LabelKey", featureColumnName: "softmax2_pre_activation"))
    
  6. Добавьте оценщик, чтобы сопоставить прогнозируемое значение ключа снова со строкой.

    .Append(mlContext.Transforms.Conversion.MapKeyToValue("PredictedLabelValue", "PredictedLabel"))
    .AppendCacheCheckpoint(mlContext);
    

Обучение модели

  1. Загрузите обучающие данные с помощью оболочки LoadFromTextFile. Добавьте следующий код в следующую строку в методе GenerateModel():

    IDataView trainingData = mlContext.Data.LoadFromTextFile<ImageData>(path:  _trainTagsTsv, hasHeader: false);
    

    Данные в ML.NET представлены в виде интерфейса IDataView. IDataView — это гибкий и эффективный способ описания табличных данных (числовых и текстовых данных). Данные можно загрузить из текстового файла или в режиме реального времени (например, базы данных SQL или файлы журналов) в объект IDataView.

  2. Обучить модель с данными, загруженными выше:

    ITransformer model = pipeline.Fit(trainingData);
    

    Метод Fit() обучает модель, применяя набор данных обучения к конвейеру.

Оценка точности модели

  1. Загрузите и преобразуйте тестовые данные, добавив следующий код в следующую строку метода GenerateModel:

    IDataView testData = mlContext.Data.LoadFromTextFile<ImageData>(path: _testTagsTsv, hasHeader: false);
    IDataView predictions = model.Transform(testData);
    
    // Create an IEnumerable for the predictions for displaying results
    IEnumerable<ImagePrediction> imagePredictionData = mlContext.Data.CreateEnumerable<ImagePrediction>(predictions, true);
    DisplayResults(imagePredictionData);
    

    Существует несколько примеров изображений, которые можно использовать для оценки модели. Как и данные для обучения, их необходимо загрузить в IDataView, чтобы они могли быть преобразованы моделью.

  2. Добавьте следующий код в метод GenerateModel() для оценки модели:

    MulticlassClassificationMetrics metrics =
        mlContext.MulticlassClassification.Evaluate(predictions,
            labelColumnName: "LabelKey",
            predictedLabelColumnName: "PredictedLabel");
    

    После создания прогнозирующего набора метод Evaluate():

    • Оценивает модель (сравнивает прогнозируемые значения с тестируемым набором данных labels).
    • Возвращает метрики производительности модели.
  3. Отображение метрик точности модели

    Используйте следующий код, чтобы отобразить метрики, предоставить общий доступ к результатам и действовать над ними:

    Console.WriteLine($"LogLoss is: {metrics.LogLoss}");
    Console.WriteLine($"PerClassLogLoss is: {String.Join(" , ", metrics.PerClassLogLoss.Select(c => c.ToString()))}");
    

    Для классификации изображений оцениваются следующие метрики:

    • Log-loss — см. потери логарифмической функции . Вы хотите, чтобы логарифмическая потеря была как можно ближе к нулю.
    • Per class Log-loss. Вы хотите, чтобы для каждого класса log-loss было максимально близко к нулю.
  4. Добавьте следующий код, чтобы вернуть обученную модель в виде следующей строки:

    return model;
    

Запуск приложения

  1. Добавьте вызов к GenerateModel после создания класса MLContext:

    ITransformer model = GenerateModel(mlContext);
    
  2. Добавьте вызов метода ClassifySingleImage() после вызова метода GenerateModel():

    ClassifySingleImage(mlContext, model);
    
  3. Запустите консольное приложение (CTRL + F5). Результаты должны совпадать со следующими выходными данными. (Вы можете увидеть предупреждения или сообщения о ходе выполнения, но эти сообщения были удалены из следующих результатов для ясности.)

    =============== Training classification model ===============
    Image: broccoli2.jpg predicted as: food with score: 0.8955513
    Image: pizza3.jpg predicted as: food with score: 0.9667718
    Image: teddy6.jpg predicted as: toy with score: 0.9797683
    =============== Classification metrics ===============
    LogLoss is: 0.0653774699265059
    PerClassLogLoss is: 0.110315812569315 , 0.0204391272836966 , 0
    =============== Making single image classification ===============
    Image: toaster3.jpg predicted as: appliance with score: 0.9646884
    

Поздравляю! Теперь вы успешно создали модель классификации в ML.NET для классификации изображений с помощью предварительно обученного TensorFlow для обработки изображений.

Исходный код для этого руководства можно найти в репозитории dotnet/samples.

В этом руководстве вы узнали, как:

  • Общие сведения о проблеме
  • Включение предварительно обученной модели TensorFlow в конвейер ML.NET
  • Обучение и оценка модели ML.NET
  • Классификация тестового образа

Ознакомьтесь с репозиторием GitHub с примерами машинного обучения, чтобы изучить расширенный пример классификации изображений.