Создание красивых эффектов изображения
В сегодняшней статье мы собираемся создать замечательные эффекты передачи стилей. Для этого нам нужно будет глубже понять, как работают сверточные нейронные сети и их слои. К концу этой статьи вы сможете создать приложение для передачи стилей, которое сможет применять новый стиль к изображению, сохраняя при этом его исходное содержимое.
Передача стиля
Прежде чем мы перейдем к нашему приложению «Передача стилей», давайте уточним, чего мы стремимся достичь.
Давайте определим перенос стиля как процесс изменения стиля изображения с сохранением его содержания.
Учитывая входное изображение и изображение стиля, мы можем вычислить выходное изображение с исходным содержимым, но с новым стилем. Это было изложено в статье Леона А. Гэтиса Нейронный алгоритм художественного стиля, которая является отличной публикацией, и вам обязательно стоит ее проверить.
Input Image + Style Image -> Output Image (Styled Input)
Как это работает?
- Мы берем входное изображение и стили изображения и изменяем их размер до одинаковых форм.
- Загружаем предварительно обученную сверточную нейронную сеть (VGG16).
- Зная, что мы можем различать слои, отвечающие за стиль (основные формы, цвета и т. Д.), И слои, отвечающие за контент (особенности изображения), мы можем разделить слои для независимой работы с содержимым и стилем.
- Затем мы ставим нашу задачу как задачу оптимизации, в которой мы собираемся минимизировать:
- потеря контента (расстояние между входным и выходным изображениями - мы стремимся сохранить контент)
- потеря стиля (расстояние между стилем и выходными изображениями - мы стремимся применить новый стиль)
- полная потеря вариации (регуляризация - пространственная гладкость для уменьшения шума на выходном изображении)
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.
И не забудьте 👏 если вам понравилась эта статья 🙂.