Как сохранить нейросеть после обучения
Перейти к содержимому

Как сохранить нейросеть после обучения

Как дообучить обученную нейросеть?

Есть обученная нейронная сеть. Требуется произвести её дообучение на новом датасете.

Архитектура сети:

PS: Как можно улучшить архитектуру данной нейросети?

user avatar

По идее все должно получиться если просто прочитать с диска сохраненную модель и продолжить обучение:

PS я не был уверен сохраняется ли learning rate оптимизатора во время сохранения модели. Некоторые оптимизаторы уменьшают шаг обучения / realning rate чтобы начинать градиентный спуск с большим шагом (для более быстрой сходимости) и уменьшать его в процессе работы, чтобы не проскочить минимум (при слишком большом шаге градиентный спуск может не сойтись). Проверил на обученной ранее и сохраненной модели — learning rate сохраняется и читается load_model() :

Transfer Learning: как быстро обучить нейросеть на своих данных

Машинное обучение становится доступнее, появляется больше возможностей применять эту технологию, используя «готовые компоненты». Например, Transfer Learning позволяет использовать накопленный при решении одной задачи опыт для решения другой, аналогичной проблемы. Нейросеть сначала обучается на большом объеме данных, затем — на целевом наборе.

Food recognition

В этой статье я расскажу, как использовать метод Transfer Learning на примере распознавания изображений с едой. Про другие инструменты машинного обучения я расскажу на воркшопе «Machine Learning и нейросети для разработчиков».

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

Для таких типовых задач, как классификация изображений, можно воспользоваться готовой архитектурой (AlexNet, VGG, Inception, ResNet и т.д.) и обучить нейросеть на своих данных. Реализации таких сетей с помощью различных фреймворков уже существуют, так что на данном этапе можно использовать одну из них как черный ящик, не вникая глубоко в принцип её работы.

Однако, глубокие нейронные сети требовательны к большим объемам данных для сходимости обучения. И зачастую в нашей частной задаче недостаточно данных для того, чтобы хорошо натренировать все слои нейросети. Transfer Learning решает эту проблему.

Transfer Learning для классификации изображений

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

Transfer learning

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

Существуют различные стратегии дообучения модели. Мы воспользуемся следующей: будем тренировать всю сеть из конца в конец (end-to-end), а предобученные веса не будем фиксировать, чтобы дать им немного скорректироваться и подстроиться под наши данные. Такой процесс называется тонкой настройкой (fine-tuning).

Структурные компоненты

Для решения задачи нам понадобятся следующие компоненты:

  1. Описание модели нейросети
  2. Пайплайн обучения
  3. Инференс пайплайн
  4. Предобученные веса для этой модели
  5. Данные для обучения и валидации

В нашем примере компоненты (1), (2) и (3) я буду брать из собственного репозитория, который содержит максимально легковесный код — при желании с ним можно легко разобраться. Наш пример будет реализован на популярном фреймворке TensorFlow. Предобученные веса (4), подходящие под выбранный фреймворк, можно найти, если они соответствуют одной из классических архитектур. В качестве датасета (5) для демонстрации я возьму Food-101.

Модель

В качестве модели воспользуемся классической нейросетью VGG (точнее, VGG19). Несмотря на некоторые недостатки, эта модель демонстрирует довольно высокое качество. Кроме того, она легко поддается анализу. На TensorFlow Slim описание модели выглядит достаточно компактно:

Веса для VGG19, обученные на ImageNet и совместимые с TensorFlow, скачаем с репозитория на GitHub из раздела Pre-trained Models.

Датасет

В качестве обучающей и валидационной выборки будем использовать публичный датасет Food-101, где собрано более 100 тысяч изображений еды, разбитых на 101 категорию.

Food-101 dataset

Скачиваем и распаковываем датасет:

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

  1. Список классов (категорий)
  2. Обучающий набор: список путей к картинкам и список правильных ответов
  3. Валидационный набор: список путей к картинкам и список правильных ответов

Все вспомогательные функции, ответственные за обработку данных, вынесены в отдельный файл data.py :

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

Код обучения модели состоит из следующих шагов:

  1. Построение train/validation пайплайнов данных
  2. Построение train/validation графов (сетей)
  3. Надстраивание классификационной функция потерь (cross entropy loss) поверх train графа
  4. Код, необходимый для вычисления точности предсказания на валидационной выборке во время обучения
  5. Логика загрузки предобученных весов из снэпшота
  6. Создание различных структур для обучения
  7. Непосредственно сам цикл обучения (итерационная оптимизация)

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

В конце обучения в TensorBoard мы наблюдаем практически идеальную картину: снижение Train loss и рост Validation Accuracy

TensorBoard loss and accuracy

В результате мы получаем сохранённый снэпшот в checkpoints/vgg19_food , который будем использовать во время тестирования нашей модели (inference).

Тестирование модели

Теперь протестируем нашу модель. Для этого:

  1. Cконструируем новый граф, предназначенный специально для инференса ( is_training=False )
  2. Загрузим обученные веса из снэпшота
  3. Загрузим и предобработем входное тестовое изображение
  4. Прогоним изображение через нейронную сеть и получим предсказание

Inference

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

На воркшопе «Machine Learning и нейросети для разработчиков» я разберу и другие задачи машинного обучения, а студенты к концу интенсива сами представят свои проекты.

Нейросеть за пять минут! Is it real?!

Добрый день, уважаемые читатели. Сатирический заголовок говорит о том, что сегодняшней темой станут нейронные сети, а точнее «алгоритм» их обучения. Ведь обучить нейросеть не значит создать класс модели и вызвать метод fit (sklearn) или заполнить её слоями (keras). Это значит предобработать данные, подобрать гиперпараметры, сохранить её для дальнейшего использования и многое другое. Сегодня мы и сделаем это, исключив подбор гиперпараметров модели, это я доверяю вам, чтобы добавить интерактива.

Импорт

В качестве примера мы будем использовать обычную реализацию нейросети из sklearn.

Команды для установки пакетов:

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

Предобработка (preprocessing) данных

Загрузим данные с помощью pandas , в частности функции read_csv.

Нам необходимо получше «узнать» датасет, чтобы продолжить с ним работу. В этом нам поможет профилирование.

Мы создали отчет по нашей таблице и загрузили его в отдельный файл. Не буду раскрывать карты и демонстрировать, что находится в нём, но могу сказать, что вы будете приятно удивлены, если ранее не сталкивались с pandas_profiling .

У нас довольно много категориальных данных, которые мы будем кодировать с помощью One-Hot encoding.

Однако столбец education-num является кодированием меток из столбца education , потому он нам не нужен.

Также нам необходимо закодировать наш target — столбец salary . Для этого воспользуемся методом map класса Series . Он принимает словарь типа:

Метод возвращает новый объект Series , потому следующая наша команда выглядит так:

По привычке, в качестве Out в Jupyter Notebook я выдаю первые 5 строк таблицы, дабы посмотреть, корректно ли сработала та или иная конструкция.

Далее нам необходимо закодировать категориальные переменные. Мы не будем делать это вручную: за нас это сделает функция get_dummies из библиотеки pandas .

Итого у нас получилось 108 столбцов — не так много, как могло казаться ранее. Теперь проверим информацию о таблице, чтобы точно убедиться, что всё верно.

Отлично, мы имеем все столбцы в числовом виде, однако это ещё не всё.

Нам необходимо нормализировать данные: именно в таком виде лучше передавать числовые значения

Отделим нашу цель и образцы из общего набора:

Теперь же разделим данные на тренировочные и тестовые с помощью train_test_split :

26 тысячи тренировочных образцов мы получили в итоге. Теперь начнём создавать наш классификатор.

Нейросеть (neural network)

100 скрытых слоёв, сигмоидальная функция активации, штраф L2-регуляризации в 0.0001, перемешивание и т.д. указываем при создании экземпляра класса. Далее обучаем модель:

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

Недавно от меня была статья про консервацию объектов Python с помощью pickle и json . Однако сегодня мы будем использовать joblib — подмодуль sklearn для сохранения модели в бинарный файл и её загрузки в объект Python.

Программный интерфейс joblib , который нам необходим, такой же, как и у pickle :

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

Отлично, всё сходится.

Заключение

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

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

Также рекомендую прочитать статью Начальные функции NumPy. Подпишитесь на группу ВКонтакте, Telegram и YouTube-канал. Там еще больше полезного и интересного для разработчиков.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *