Создание красивых эффектов изображения

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

Передача стиля

Прежде чем мы перейдем к нашему приложению «Передача стилей», давайте уточним, чего мы стремимся достичь.

Давайте определим перенос стиля как процесс изменения стиля изображения с сохранением его содержания.

Учитывая входное изображение и изображение стиля, мы можем вычислить выходное изображение с исходным содержимым, но с новым стилем. Это было изложено в статье Леона А. Гэтиса Нейронный алгоритм художественного стиля, которая является отличной публикацией, и вам обязательно стоит ее проверить.

Input Image + Style Image -> Output Image (Styled Input)

Как это работает?

  1. Мы берем входное изображение и стили изображения и изменяем их размер до одинаковых форм.
  2. Загружаем предварительно обученную сверточную нейронную сеть (VGG16).
  3. Зная, что мы можем различать слои, отвечающие за стиль (основные формы, цвета и т. Д.), И слои, отвечающие за контент (особенности изображения), мы можем разделить слои для независимой работы с содержимым и стилем.
  4. Затем мы ставим нашу задачу как задачу оптимизации, в которой мы собираемся минимизировать:
  • потеря контента (расстояние между входным и выходным изображениями - мы стремимся сохранить контент)
  • потеря стиля (расстояние между стилем и выходными изображениями - мы стремимся применить новый стиль)
  • полная потеря вариации (регуляризация - пространственная гладкость для уменьшения шума на выходном изображении)

5. Наконец, мы устанавливаем наши градиенты и оптимизируем их с помощью алгоритма L-BFGS.

Хотя приведенный выше общий обзор может показаться запутанным, давайте сразу перейдем к коду!

«То, что я не могу создать, я не понимаю». - Ричард Фейнман

Реализация

Вы можете найти полную кодовую базу проекта Style Transfer в виде ядра Kaggle или, как обычно, на GitHub.

Вход

Начнем с определения нашего ввода

это панорама Сан-Франциско

Стиль

Затем давайте определим стиль изображения

что является видением Варшавы, Польша, Титусом Бжозовским.

Подготовка данных

Следующим шагом будет изменение формы и нормализация среднего на обоих изображениях.

Модель CNN

После этого, когда наши массивы изображений готовы к работе, мы можем перейти к нашей модели CNN.

Я рекомендую вам ознакомиться с моей предыдущей статьей об основах CNN, где я подробно объясняю, как работают сверточные нейронные сети.



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



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

Имейте в виду, что мы не собираемся использовать полностью связанные (синий) и softmax слои (желтый). Они действуют как классификатор, который нам здесь не нужен. Мы собираемся использовать только экстракторы признаков, т.е. сверточный (черный) и максимальный (красный) слои.

Давайте посмотрим, как конкретные функции выглядят на выбранных слоях VGG16, обученных на наборе данных ImageNet.

Мы не собираемся здесь визуализировать каждый слой CNN, но в соответствии с Johnson et al. для слоя контента мы должны выбрать

block2_conv2

и для слоев стилей

[block1_conv2, block2_conv2, block3_conv3, block4_conv3, block5_conv3]

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

Потеря контента

Определив нашу модель CNN, давайте определим функцию потери контента. Чтобы сохранить исходное содержание, мы собираемся минимизировать расстояние между входным изображением и выходным изображением.

Потеря стиля

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

Общая вариационная потеря

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

Оптимизация - потери и градиенты

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

Вместо того, чтобы рассматривать здесь основную математику (но я все же рекомендую вам проверить ее в статье Нейронный алгоритм художественного стиля Леона А. Гэтиса), подумайте об этом следующим образом:

На каждой итерации мы собираемся создавать выходное изображение, чтобы минимизировать расстояние (разницу) между выходом и входом / стилем на соответствующих векторных слоях.

Полученные результаты

В конце концов, давайте оптимизируем с помощью алгоритма L-BFGS и визуализируем результаты.

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

Довольно впечатляюще, да?

Мы ясно видим, что, хотя исходное содержание входного изображения (линия горизонта Сан-Франциско) было сохранено, мы успешно применили новый стиль (Варшава Титуса Бжозовского) к выходному изображению.

Другие примеры

Что дальше?

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

Не забудьте заглянуть на страницу проекта на github.



Вопросов? Комментарии? Не стесняйтесь оставлять свои отзывы в разделе комментариев или связываться со мной напрямую по адресу https://gsurma.github.io.

И не забудьте 👏 если вам понравилась эта статья 🙂.