То что мы сделаем ещё называется Нейронный перенос стиля – это метод смешивания двух изображений и создания нового изображения из изображения-контента путём копирования стиля другого изображения, которое называется изображением стиля. Созданное изображение часто называют стилизованным изображением.
В этой статье мы скопируем стиль Энди Уорхола с «Мэрилин Диптих» на наши фотографии. Уорхол создал диптих Монро в 1962 году, сначала раскрасив холст разными цветами, а затем разместив теперь знаменитое изображение Мэрилин поверх холста. Хотя Уорхол не является основателем поп-арта, он – одна из самых влиятельных фигур в этом жанре.
Рис. 1. «Мэрилин Диптих» Уорхола, а на кдпв показан наш результат нейронного переноса стиля в поп-арт, которого мы добились с помощью сети VGG-19
Что касается технического аспекта туториала, вместо использования готовой сети Magenta мы используем предварительно обученную модель компьютерного зрения VGG-19 и настроим её. Таким образом, эта статья представляет собой руководство по переносному обучению, а также по компьютерному зрению. Применяя возможности трансферного обучения, мы можем достичь лучших результатов, если сможем правильно настроить модель и иметь широкий спектр дополнительных возможностей настройки.
переносное обучение – это подраздел машинного обучения и искусственного интеллекта, цель которого – применить знания, полученные в результате выполнения одной задачи (исходной задачи), к другой, но похожей задаче (целевой задаче).
Кратко расскажу о модели, которую мы будем настраивать: VGG-19.
VGG-19
VGG – это свёрточная нейронная сеть с глубиной 19 слоев. Она была построена и обучена К. Симоняном и А. Зиссерманом в Оксфордском университете в 2014 году. Вся информация об этом есть в статье Very Deep Convolutional Networks for Large-Scale Image Recognition, опубликованной в 2015 году. Сеть VGG-19 обучена с использованием более одного миллиона изображений из базы данных ImageNet. Она обучалась на цветных изображениях размером 224x224 пикселей. Естественно, вы можете импортировать модель ImageNet с уже обученными весами. Эта предварительно обученная сеть может классифицировать до тысячи объектов. В этом туториале мы избавимся от верхней части, используемой для классификации, и добавим наши собственные дополнительные слои, чтобы её можно было использовать для нейронного переноса стиля. Вот официальная визуализация сети из научной работы:
Рис. 3. Иллюстрация сети VGG-19
Как я уже упоминал, чей стиль мог бы быть более культовым и более подходящим, чем стиль Энди Уорхолла для переноса в поп-арт. Мы будем использовать его культовую работу Мэрилин Диптих в качестве основы стиля и портретное фото из Unsplash в качестве основного контента:
Рис. 4. Мэрилин Диптих и выбранное для эксперимента фото
Уакзываем пути к изображениям
Используя TensorFlow, я могу написать
get_files
[получить файлы] с внешних URL-адресов. С помощью приведённого ниже кода я загружу изображения в свой блокнот Colab, одно для стиля, а другое для контента:Масштабирование изображений
Поскольку наши изображения имеют высокое разрешение, нам необходимо масштабировать их, чтобы обучение не занимало слишком много времени. Приведённый ниже код преобразует данные изображения в подходящий формат, масштабирует изображение (не стесняйтесь изменять параметр
max_dim
) и создаёт новый объект, который можно использовать для загрузки в модель:Загрузка изображений
Теперь, когда мы определяем нашу функцию
img_scaler
, мы можем создать функцию обёртывания для загрузки изображения из контуров изображения, которые мы установили выше, масштабировать их, чтобы ускорить обучение (с помощью вызова img_scaler()
) и создть 4-мерный тензор, чтобы он подходил для VGG-19:Теперь можно просто создать тензоры
content_image
и style_image
, используя функции, которые мы перечислили выше:Отображение изображения
Используя matplotlib, мы можем легко отобразить контент и изображения стиля рядом:
И вот вывод:
Рис. 5. Визуализация изображений контента и стиля
Теперь, когда у нас есть изображения, подготовленные для нейронного переноса стиля, мы можем создать нашу модель VGG-19 и подготовить её для точной настройки. Этот процесс требует большего внимания, но внимательное чтение и программирование приведут вас к результату. В этом разделе мы:
- Загружаем VGG-19 с помощью API Keras ФЗШ от TensorFlow и загружаем его с весами ImageNet.
- Создаём матричную функцию Грама для расчёта потери стиля.
- Выбирам слои обученной модели VGG-19 для контента и стиля.
- Создаём пользовательскую модель на основе ранее загруженной модели VGG-19 с опцией Keras Model Subclassing.
- Настраиваем оптимизатор и функции потерь.
- Определяем настроенный шаг обучения.
- Запускаем написанный нами цикл обучения.
Обратите внимание на комментарии в gist
Загружаем VGG с Functional API
Поскольку в Keras размещена предварительно обученная модель VGG-19, мы можем загрузить модель из Keras Application API. Сначала создадим функцию, чтобы использовать её позже в разделе «Создание подклассов». Эта функция позволяет нам создавать пользовательскую модель VGG с желаемыми слоями, по-прежнему имея доступ к атрибутам модели:
Основная модель с Model Subclassing
Вместо того чтобы сравнивать необработанные промежуточные выходные данные изображения контента и изображения стиля, мы сравним матрицы Грама двух выводов с помощью функции gram_matrix; она даёт результаты точнее:
Модель VGG-19 состоит из 5 блоков со слоями внутри каждого блока, как показано выше. Мы выберем первый свёрточный слой каждого блока, чтобы получить знания о стиле. Поскольку информация промежуточного уровня более ценна для трансферного обучения, мы оставим второй свёрточный слой пятого блока для слоя контента. Следующие строки создают два списка с информацией об этом слое:
Теперь, когда у нас есть выбранные слои, функция gram_matrix() для расчёта потерь и функция vgg_layers() для загрузки желаемого в VGG-19, мы можем создать нашу основную модель с опцией Keras Model Subclassing. С помощью следующих строк мы делаем
preprocess_input
[предварительно обрабатываем входные] данные, пропуская их через нашу пользовательскую модель VGG и gram_matrix
. Cоздаём модель и называем её extractor. Модель выводит словарь, который содержит выходные значения для контента и информации стиля:Оптимизатор и настройки потерь
Теперь, когда мы можем выводить прогнозы для /информации о/ стиля и содержимого, пришло время настроить оптимизатор нашей модели с помощью Adam и создать пользовательскую функцию потерь:
Пользовательский шаг обучения
Теперь мы определим пользовательскую функцию train_step, в которой воспользуемся преимуществом GradientTape, который, в свою очередь, позволяет выполнять автоматическое дифференцирование для расчёта потерь. GradientTape записывает операции во время прямого прохода, а затем может вычислить градиент нашей функции потерь для входного изображения уже для обратного прохода. Обратите внимание, что мы используем декоратор
tf.function()
, чтобы TensorFlow знал, что мы передаём функцию trainstep. Свободно экспериментируйте с total_variation_weight
, чтобы получить разные результаты переноса стиля.Настраиваемый цикл обучения
Теперь, когда всё прочитано, мы можем запустить пользовательский цикл обучения, чтобы оптимизировать веса и получить наилучшие результаты. Запустим модель на 20 эпох и 100
steps_per_epoch
[шагов на эпоху]. Это даст нам красивую версию фотографии, которую мы загрузили вначале, в стиле поп-арт. Кроме того, наш цикл будет выводить стилизованную фотографию после каждой эпохи (это временно).Если вы используете Google Colab, чтобы повторить шаги туториала, убедитесь, что вы включили аппаратный ускоритель в настройках блокнота. Это значительно сократит время обучения.
Сохраняем и отображаем стилизованное изображение
Теперь, когда наша модель завершила обучение, мы можем сохранить стилизованную фотографию контента с помощью API предварительной обработки TensorFlow. Следующая строка сохранит фотографию в вашем окружении:
Вот результат:
Рис. 6. Фото и стилизованная версия
Поздравляю!
Вы только что построили модель передачи нейронного стиля с помощью трансферного обучения. Очевидно, что есть возможности сделать её лучше, но если вы присмотритесь, то увидите, что наша модель скопировала стиль Уорхола, когда он стилизовал волосы Монро. Модель также позаимствовала цвет фона из диптиха Монро. Поэкспериментируйте с числами
img_scale
, total_variation_weight
, epoch
, steps_per_epoch
, чтобы получить разные результаты. Вы также можете использовать другие художественные стили, чтобы получить интересные результаты. А если хотите научиться применять машинное обучение иначе — приходите учиться, а промокод HABR, дающий 10% дополнительно к скидке на баннере вам в этом поможет.- Курс по Machine Learning
- Курс «Математика и Machine Learning для Data Science»
- Профессия Data Scientist
- Профессия Data Analyst
Другие профессии и курсы
ПРОФЕССИИ
КУРСЫ
- Профессия Java-разработчик
- Профессия QA-инженер на JAVA
- Профессия Frontend-разработчик
- Профессия Этичный хакер
- Профессия C++ разработчик
- Профессия Разработчик игр на Unity
- Профессия Веб-разработчик
- Профессия iOS-разработчик с нуля
- Профессия Android-разработчик с нуля
КУРСЫ
- Курс по Data Engineering
- Курс «Python для веб-разработки»
- Курс «Алгоритмы и структуры данных»
- Курс по аналитике данных
- Курс по DevOps
omikron24
Столько времени, усилий и труда, а в конце даже не напоминает, просто выглядит как дико пережатый жипег с выкрученной сатурацией =)
addewyd
Уорхол же. Интересно, что бы получилось, если бы за образец взяли, например, Модильяни.
Tenebrius
Ну так результат прям очень далек от Уорхола.
Всякие Призмы и PicsArt с фильтрами делают подобное гораздо качественнее.