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

«Здесь мы представляем искусственную систему, основанную на глубокой нейронной сети, которая создает художественные изображения высокого качества восприятия. Система использует нейронные представления для разделения и объединения содержимого и стиля произвольных изображений, обеспечивая нейронный алгоритм для создания художественных изображений ». - Гэтис, Эккер и Бетге

Что такое передача нейронного стиля?

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

Глубокое обучение - для экспертов, экспертами. Мы используем наш многолетний опыт, чтобы еженедельно доставлять в ваш почтовый ящик лучшие ресурсы для глубокого обучения.

Как работает алгоритм передачи нейронного стиля?

Чтобы понять всю математику этого алгоритма, я рекомендую вам прочитать оригинальную статью Леона А. Гэтиса и др. При реализации этого алгоритма мы определяем два расстояния; один для содержимого (Dc) и один для стиля (Ds). Ds измеряет, насколько различается контент между двумя изображениями, а Ds измеряет, насколько отличается стиль между двумя изображениями. Мы берем третье изображение - входное - и трансформируем его, чтобы минимизировать расстояние между содержимым с помощью изображения содержимого и расстояние между стилями с помощью изображения стиля.

Реализация в PyTorch

Для реализации этого алгоритма нам необходимо импортировать следующие пакеты:

  • torch, torch.nn, numpy для реализации нейронной сети и научных вычислений соответственно.
  • torch.optim для реализации различных алгоритмов оптимизации.
  • PIL, PIL.Image, matplotlib.pyplot для загрузки и отображения изображений.
  • torchvision.transforms обрабатывает изображения PIL и преобразует их в тензоры факелов.
  • torchvision.models для обучения и загрузки предварительно обученных моделей.
  • copy для глубокого копирования моделей.

Использование Cuda

Если вы используете компьютер с графическим процессором, вы можете запускать более крупные сети. Запуск torch.cuda.is_available() вернет true, если ваш компьютер поддерживает графический процессор. Затем вам нужно будет установить torch.device, который будет использоваться для этого скрипта. Метод .to(device) перемещает тензор или модуль на желаемое устройство. Чтобы переместить этот тензор или модуль обратно в ЦП, используйте метод .cpu().

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

Загрузка изображений

Начнем с импорта стиля и изображений содержимого. Затем мы масштабируем изображения до желаемого размера выходного изображения и преобразуем их в тензоры факела. Загруженные изображения должны быть одинакового размера. Изображения, используемые в этом руководстве, доступны на Pixabay и могут быть загружены здесь и здесь. Я также использовал GIMP, чтобы изменить их размер до тех же размеров.

Изображения преобразуются в тензоры факелов, и их значения находятся в диапазоне от 0 до 1. Это важно, потому что нейронные сети обучаются с помощью тензоров изображений 0–1.

Отображение изображений

Мы используем Matplotlib’s plt.imshow для отображения изображений. Это включает в себя несколько шагов:

  1. Преобразуйте изображения в изображения PIL.
  2. Клонируйте тензор, чтобы не вносить в него изменения.
  3. Удалите поддельный размер партии.
  4. Сделайте паузу, чтобы графики обновились.
  5. Постройте изображения, используя imshow.

Функция потери контента

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

Среднеквадратичная ошибка между двумя наборами карт характеристик может быть вычислена с использованием критерия nn.MSELoss, который образует третий параметр. Потери контента добавляются на каждом желаемом уровне в качестве дополнительных модулей нейронной сети. Таким образом, каждый раз, когда в сеть поступает входное изображение, все потери контента будут вычисляться на желаемых уровнях. autograd обрабатывает вычисление всех градиентов. Для этого мы заставляем forward модуля возвращать ввод.

Модуль становится прозрачным слоем нейронной сети, и вычисленные потери вычисляются как параметр модуля. Затем мы определяем поддельный backward метод, который вызывает обратный метод nn.MSELoss для восстановления градиента. Этот метод возвращает вычисленные потери, которые будут использоваться при запуске градиентного спуска для отображения эволюции стиля и потерь содержимого.

Потеря стиля

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

Модуль потери стиля реализован точно так же, как модуль потери контента; тем не менее, он сравнивает разницу в граммах матрицы цели и ввода.

Загрузка нейронной сети

Подобно тому, что описано в документе, мы используем предварительно обученную сеть VGG с 19 уровнями (VGG19). Модуль в PyTorch, который позволяет нам это делать, разделен на два последовательных дочерних уровня; объекты, содержащие слои свертки и объединения, а также классификатор с полностью связанными слоями.

Сети VGG обучаются на изображениях с каждым каналом, нормализованным по среднему значению = [0,485, 0,456, 0,406] и стандартному значению = [0,229, 0,224, 0,225]. Мы используем их для нормализации изображения перед отправкой в ​​сеть.

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

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

Автор предлагает использовать алгоритм L-BFGS для запуска градиентного спуска. Мы обучаем входное изображение, чтобы минимизировать потери контента / стиля. Мы создаем оптимизатор PyTorch L-BFGS optim.LBFGS и передаем изображение в качестве тензора для оптимизации. Мы используем .requires_grad_(), чтобы гарантировать, что изображение требует градиента.

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

При этом возникает небольшая проблема: оптимизированное изображение может принимать значения от −∞ до + ∞ вместо значений от 0 до 1, как требуется. Поэтому мы должны выполнить оптимизацию при ограничениях, чтобы гарантировать, что мы поддерживаем правильные значения в нашем входном изображении. Мы достигаем этого, корректируя изображение так, чтобы его значения попадали в интервал от 0 до 1 на каждом шаге.

Заключение

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

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

Ссылка

Расширенное руководство по нейронной передаче



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

Являясь независимой редакцией, Heartbeat спонсируется и публикуется Comet, платформой MLOps, которая позволяет специалистам по данным и группам машинного обучения отслеживать, сравнивать, объяснять и оптимизировать свои эксперименты. Мы платим участникам и не продаем рекламу.

Если вы хотите внести свой вклад, отправляйтесь на наш призыв к участникам. Вы также можете подписаться на наши еженедельные информационные бюллетени (Deep Learning Weekly и Comet Newsletter), присоединиться к нам в » «Slack и подписаться на Comet в Twitter и LinkedIn для получения ресурсов, событий и гораздо больше, что поможет вам быстрее создавать лучшие модели машинного обучения.