как отличить пришельцев от хищников с помощью трансферного обучения

1656513143 kak otlichit prishelczev ot hishhnikov s pomoshhyu transfernogo obucheniya

автор Патрик Мизюла

Эту статью написали Петр Мигдал, Рафал Якубанис и я. В предыдущей публикации они предоставили вам обзор различий между Keras и PyTorch, чтобы помочь вам выбрать фреймворк, лучше отвечающий вашим потребностям.

Теперь пришло время для испытания в бою.

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

1*fAS0pLDYQAwRvLiZtzPDCg
Изображение взято из нашего набора данных. И Хищник, и Инопланетянин глубоко заинтересованы в ИИ.

Мы выполним классификацию изображений, одну из задач компьютерного зрения для глубокого обучения. Поскольку обучение с нуля в большинстве случаев невозможно (поскольку оно очень нуждается в данных), мы проведем обучение с переносом с помощью ResNet-50, предварительно обученного в ImageNet. Мы станем максимально практичными, чтобы показать как концептуальные отличия, так и условности.

В то же время, мы будем держать код достаточно минимальным, чтобы сделать его понятным и легким для чтения и повторного использования. Смотрите блокноты на ядрах GitHub, Kaggle или Neptune с модными диаграммами.

Подождите, а что такое трансферное обучение? А почему ResNet-50?

На практике очень мало людей обучают всю сверточную сеть с нуля (со случайной инициализацией), поскольку относительно редко бывает набор данных достаточного размера. Вместо этого обычным является предварительное обучение ConvNet на очень большом наборе данных (например, ImageNet, который содержит 1,2 миллиона изображений с 1000 категориями), а затем использовать ConvNet или как инициализацию, или как экстрактор фиксированных функций для интересующей задачи. — Андрей Карпати, Трансферное обучение — сверточные нейронные сети CS231n для визуального распознавания

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

В нашем случае мы работаем с моделью ResNet-50, обученной классифицировать изображение из набора данных ImageNet. Достаточно изучить многие текстуры и узоры, которые могут быть полезны в других визуальных задачах, даже таких инопланетных, как этот случай «Чужой против Хищника». Таким образом, мы будем использовать гораздо меньше вычислительной мощности, чтобы добиться гораздо лучших результатов.

В нашем случае мы сделаем это самым простым способом:

  • хранить предварительно натренированные сверточные слои (так называемый экстрактор признаков) с замороженными их весами и
  • удалите оригинальные плотные слои и замените их совершенно новыми плотными слоями, которые мы будем использовать для обучения.
1*BFIC_uZzi2v1p2254LLv2Q

Итак, какую сеть мы должны выбрать в качестве извлекателя функций?

ResNet-50 – популярная модель для классификации изображений ImageNet (AlexNet, VGG, GoogLeNet, Inception, Xception – другие популярные модели). Это 50-уровневая архитектура глубокой нейронной сети, основанная на остаточных соединениях, добавляющих модификации с каждым слоем, а не полностью изменяющих сигнал.

ResNet был самым современным в ImageNet в 2015 году. С тех пор были изобретены более новые архитектуры с высшими баллами в ImageNet. Однако они не обязательно лучше обобщают другие наборы данных (см. документ Better ImageNet Models Transfer Better? arXiv).

Ладно, пора погрузиться в код.

Пусть матч начинается!

Мы настроим наш вызов «Чужой против Хищника» в семь шагов:

0. Подготовьте набор данных
1. Импортные зависимости
2. Создание генераторов данных
3. Создайте сеть
4. Тренируйте модель
5. Сохраните и загрузите модель
6. Сделайте прогнозы по образцам тестовых изображений

Мы дополняем эту публикацию в блоге кодом Python в записных книжках Jupyter (Keras-ResNet50.ipynb, PyTorch-ResNet50.ipynb). Эта среда более удобна для создания прототипов, чем голые скрипты, поскольку мы можем выполнять его ячейку за ячейкой и достигать пика на выходе.

Ладно, пойдем!

0. Подготовьте набор данных

Мы создали набор данных, выполнив поиск в Google со словами «инопланетянин» и «хищник». Мы сохранили эскизы JPG (около 250х250 пикселей) и вручную отфильтровали результаты. Вот несколько примеров:

1*QmyVYru66iPvvWcITUKobg

Мы разделили наши данные на две части:

  • Данные обучения (347 образцов на класс) используются для обучения сети.
  • Данные проверки (100 образцов на класс) не используются во время обучения, но необходимы для проверки производительности модели на ранее невиданных данных.

Keras требует, чтобы наборы данных были организованы в папки следующим образом:

Если вы хотите увидеть процесс организации данных в каталогах, просмотрите файл data_prep.ipynb. Вы можете скачать набор данных из Kaggle.

1. Импортные зависимости

Во-первых, технические особенности. Мы предполагаем, что у вас есть Python 3.5+, Keras 2.2.2 (с серверной частью TensorFlow 1.10.1) и PyTorch 0.4.1. Проверьте файл requirements.txt в репо.

Итак, сначала нам нужно импортировать необходимые модули. Мы разделим код в Keras, PyTorch и общий (один необходим у обоих).

Мы можем проверить версии фреймворков, введя keras.__version__ и torch.__version__соответственно.

2. Создание генераторов данных

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

Мы также используем генераторы данных для предварительной обработки: мы изменяем размер и нормализуем изображения, чтобы сделать их такими, как нравится ResNet-50 (224 x 224 px, с масштабируемыми цветовыми каналами). И последнее, но не менее важное, мы используем генераторы данных для случайного возмущения изображений на лету:

1*G4WdPAp5x6Z22WiV4mMBqw

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

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

Здесь мы создаем генераторы, которые:

  • загрузить данные из папок,
  • нормализовать данные (как обучение, так и проверку), и
  • дополнять данные (лишь поезд).

В Keras вы получаете встроенные расширения и preprocess_input метод нормализации изображений помещается в ResNet-50, но вы не можете контролировать их порядок. В PyTorch вам нужно нормализовать изображение вручную, но вы можете организовать увеличение любым способом.

Есть и другие нюансы: например, Keras по умолчанию заполняет остальное дополненное изображение пикселями границы (как вы можете видеть на рисунке выше), тогда как PyTorch оставляет его черным. Каждый раз, когда один фреймворк справляется с вашей задачей гораздо лучше, чем другой, внимательнее посмотрите, одинаково ли они выполняют предварительную обработку; мы закладываем, что они этого не делают.

3. Создайте сеть

Следующим шагом является импорт предварительно подготовленной модели ResNet-50, что в обоих случаях легко. Мы заморозим все сверточные слои ResNet-50 и тренируем всего два последних полностью связанных (плотных) слоя. Поскольку наша задача классификации имеет всего 2 класса (по сравнению с 1000 классами ImageNet), нам нужно настроить последний слой.

Вот мы:

  • загрузите заранее подготовленную сеть, отрежьте ей голову и заморозьте ее весы,
  • добавить специальные плотные слои (мы выбираем 128 нейронов для скрытого слоя), и
  • установить оптимизатор и функцию утрат.

Мы загружаем ResNet-50 из Keras и PyTorch без всяких усилий. Они также предлагают многие другие хорошо известные предварительно обученные архитектуры: посмотрите модельный зоопарк Керраса и модельный зоопарк PyTorch. Итак, какие отличия?

В Keras мы можем импортировать только слои, извлекающие объекты, без загрузки посторонних данных (include_top=False). Затем мы создаем модель функционально, используя входные и исходящие данные базовой модели. Тогда используем model.compile(...) упекать в него функцию потерь, оптимизатор и другие метрики.

В PyTorch модель является объектом Python. В случае models.resnet50плотные слои хранятся в model.fc атрибут. Мы перепишем их. Функция потерь и оптимизаторы – это отдельные объекты. Для оптимизатора нужно явно передать список параметров, которые мы хотим обновить.

В PyTorch мы должны явно указать, что мы хотим загрузить в графический процессор с помощью .to(device) метод. Мы должны писать это всякий раз, когда мы собираемся поместить объект на GPU, если он доступен. Ну…

1*woYU8o65zMwH4UHvjWj7NA
Фото из фильма «AVP: Alien vs. Predator»: наручный компьютер хищников. Мы уверены, что Predator может использовать его для вычисления logsoftmax.

Аналогично работает замораживание слоев. Однако в слое пакетной нормализации Keras сломано (в текущей версии; спасибо Пшемиславу Побротину за представление этой проблемы), вы увидите, что некоторые слои все равно меняются, даже если trainable=False.

Keras и PyTorch справляются с утратой журналов по-разному.

У Keras сеть прогнозирует вероятности (имеет встроенную функцию softmax), а ее встроенные функции стоимости предполагают, что они работают с вероятностями.

У PyTorch у нас больше свободы, но лучший способ — вернуть логиты. Это делается по числовым причинам, выполнение softmax, а затем потеря журнала означает ненужность log(exp(x)) операции. Итак, вместо использования softmax мы используем LogSoftmaxNLLLoss) или объединить их в одно целое nn.CrossEntropyLoss функция утраты.

4. Тренируйте модель

Ладно, ResNet загружен, так что готовимся к космическому шуму!

1*uuFsm4SiVj5TbWtGPtZ0IQ
Кадр из фильма «AVP: Инопланетянин против Хищника»: Корабль-матери хищников. Да, мы слышали, что в космосе нет шума, но для Инопланетян и Хищников нет ничего невозможного.

Теперь мы перейдем к важнейшему шагу – обучению модели. Нам нужно передать данные, вычислить функцию потерь и соответственно изменить вес сети. Хотя мы уже имели некоторые отличия между Keras и PyTorch в расширении данных, длина кода была похожей. Для тренировок… разница огромная. Давайте посмотрим, как это работает!

Вот мы:

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

В Керасе, в model.fit_generator проводит обучение… и все! Учеба в Керасе – это так удобно. И, как вы можете найти в блокноте, Keras также бесплатно дает нам индикатор прогресса и функцию времени. Но если ты хочешь сделать что-то нестандартное, то начинается боль.

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

1*2WwHB_QkewusJM_ELzYXmg
Сюрикен хищника автоматически возвращается к владельцу. Хотите ли вы реализовать его возможность отслеживания в Keras или PyTorch?

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

  • эпохи,
  • этапы обучения и проверки и
  • партии.

Цикл epoch не делает ничего кроме повторения кода внутри. Фазы обучения и проверки проводятся по трем причинам:

  • Некоторые специальные слои, например пакетная нормализация (присутствует в ResNet-50) и извлечение (отсутствует в ResNet-50), работают по-разному во время обучения и проверки. Мы определяем их поведение model.train() и model.eval()соответственно.
  • Мы используем разные изображения для обучения и проверки, конечно.
  • Самое главное и менее удивительно: мы обучаем сеть только во время обучения. Волшебные команды optimizer.zero_grad(), loss.backward() и optimizer.step() (в таком порядке) проделайте работу. Если вы знаете, что такое обратное распространение, вы дорожите их элегантностью.

Затем мы сами беремся за вычисление эпоховых потерь и печатаем.

5. Сохраните и загрузите модель

Сохранение

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

  • сохранение всей архитектуры модели и обученных весов (и состояния оптимизатора) в файл, и
  • сохранение обученных весов в файл (сохраняя архитектуру модели в коде).

Какой путь вы выберете, решать вам.

Вот мы:

В обеих фреймворках достаточно одной строки кода. В Keras вы можете либо сохранить все в файле HDF5, либо сохранить весы в HDF5 и архитектуру в файл JSON для чтения. Кстати: позже можно скачать модель и запустить ее в браузере.

1*WQupj2OpGHFnD6CrgSaPxA
Кадр из фильма «Чужой: Воскресение»: Alien развивается, как и PyTorch.

Разработчики PyTorch рекомендуют хранить только весы. Они не рекомендуют сохранять всю модель, поскольку API все еще развивается.

Загрузка

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

Вот мы:

В Keras мы можем загружать модель из файла JSON вместо того, чтобы создавать ее на Python (по крайней мере, когда мы не используем собственные слои). Такой вид сериализации делает его удобным для передачи моделей.

PyTorch может использовать любой Python код. Так что нам приходится заново создавать модель на Python.

Загрузка весов модели сходна в обоих фреймворках.

6. Сделайте прогнозы по образцам тестовых изображений

Ладно, наконец пора сделать некоторые прогнозы! Чтобы справедливо проверить качество нашего решения, мы попросим модель предугадать тип монстров по изображениям, не используемым для обучения. Мы можем использовать набор проверки или любого другого изображения.

Вот мы:

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

Прогнозирование, как и обучение, работает пакетами (здесь мы используем пакет из 3; хотя мы, несомненно, также можем использовать пакет из 1).

И в Keras, и в PyTorch нам нужно скачать и предварительно обработать данные. Ошибка новичка – забыть об этапе предварительной обработки (включая цветовой зум). Это, скорее всего, сработает, но приведет к худшим прогнозам (поскольку он эффективно видит те же формы, но с разными цветами и контрастами).

У PyTorch есть еще два шага, поскольку нам нужно:

  • превращение логитов в вероятности, и
  • передать данные в центральный процессор и конвертировать в NumPy (к счастью, сообщения об ошибках достаточно ясны, когда мы забываем об этом шаге).

И вот что мы получаем:

1*a6XeWuUwwtBjFMfUlN-eyw

Это работает!

А как насчет других изображений? Если вы не можете ничего (или кого-нибудь) придумать, попробуйте использовать фотографии своих коллег. ?

Вывод

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

Keras работает на гораздо более высоком уровне абстракции. Это гораздо больше plug&play и, как правило, более лаконичны, но ценой гибкости.

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

Трансферное обучение – большая тема. Попробуйте настроить параметры (например, плотные слои, оптимизатор, скорость обучения, расширение) или выберите другую архитектуру сети.

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

Выберите Keras или PyTorch, выберите набор данных и сообщите нам, как это было в разделе комментариев ниже?

Кстати, в ноябре мы проводим серию практических тренингов, где вы сможете узнать больше о Keras и PyTorch. Петр Мигдал и я будем вести некоторые сессии, поэтому не стесняйтесь проверить это.

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

Ваш адрес email не будет опубликован.