Учебник по зебрафике Дональда Трампа и Ким Чен Ына

В этой статье вы присоединитесь к нашему путешествию по созданию и обучению модели cycleGAN (Cycle-Consistent Generative Adversarial Networks), которая превращает лошадей в зебр. Сначала мы рассмотрим структуру cycleGAN, а также четыре функции потерь, реализованные для его обучения. Мы также познакомимся с микроархитектурой каждого дискриминатора и генератора, развернутого в cycleGAN. Наконец, мы поговорим о том, как обучить cycleGAN с некоторыми очень впечатляющими результатами перевода, прикрепленными в самом конце. Прежде, чем вы начнете читать, было бы лучше иметь базовые представления о сверточных нейронных сетях и GAN. Эта статья представляет собой краткое изложение проекта курса Advanced Predictive Modeling, выполненного Джошем Артманном, Имин Джин, Кевином Ченгом и Хао Хэ из UT Austin.

Обзор проекта

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

Традиционно для обучения модели Преобразование изображения в изображение нам понадобится набор данных парных образцов, то есть, если мы хотим перенести картину в реальную фотографию, нам понадобятся сотни картин и соответствующих реальных фотографий, с которых были написаны произведения искусства. Однако проблема, с которой мы сталкиваемся, заключается в том, что нам невозможно найти парные изображения зебры для наших лошадей, поскольку таких вещей вообще не существует. Вот почему мы используем модель под названием cycleGAN, которая не требует таких парных выборок при обучении для достижения трансформации. Представленный Цзюнь-янь Чжу и его коллегами из Калифорнийского университета в Беркли в 2017 году, cycleGAN представляет новый способ выполнения преобразования изображения в изображение. Хотя для обучения по-прежнему требуется набор изображений лошадей и набор изображений зебры, изображения лошади и зебры больше не нуждаются в прямой корреляции друг с другом.

Чтобы обучить модель cycleGAN от лошади к зебре, нам нужны два набора данных: изображения реальных лошадей и изображения зебры. В нашем проекте мы используем хорошо организованный набор данных, взятый с официальной страницы Github для cycleGAN. Набор данных содержит две тренировочные папки, каждая из которых содержит около 1200 фотографий лошадей или зебр. Эти фотографии используются для обучения модели. Кроме того, еще 10 фотографий лошадей и 10 фотографий зебры сохраняются в тестовых папках набора данных для оценки производительности модели.

Введение в CycleGAN

Традиционного преобразования изображения в изображение можно достичь с помощью одной модели GAN, которая образована двумя модулями нейронной сети: один называется генератором, а другой - дискриминатором. Для модели cycleGAN она фактически построена двумя моделями GAN. Прежде чем вы спросите, зачем нам два, давайте сначала поговорим о том, как эти два GAN сконфигурированы внутри cycleGAN.

Причина, по которой это называется cycleGAN, заключается в том, что мы будем использовать две модели GAN для построения цикла для какой-то цели, о которой мы скоро поговорим. Чтобы выполнить такой цикл, нам нужно заставить две модели GAN выполнять одну и ту же работу, то есть выполнять преобразование изображения в изображение, но в обратном направлении. В частности, мы хотим, чтобы GAN A передавал изображение лошади в изображение зебры, а GAN B имел возможность передавать изображение зебры в изображение лошади. Каждая из двух моделей GAN состоит из условного генератора и дискриминатора PatchGAN. О структуре генератора и дискриминаторов мы поговорим в следующем разделе. Подводя итог, в нашем наборе инструментов у нас есть две модели GAN. Каждый из них содержит один генератор и один дискриминатор.

Погодите, какого черта нам нужны два?

Вернемся к поднятому ранее вопросу: если мы выполняем только односторонний перевод изображений или переход от лошади к зебре без перевода с зебры на лошадь, зачем нам нужны два GAN в нашей модели, в то время как один из них может получить работа сделана? Что ж, чтобы ответить на этот вопрос, давайте вернемся к главному преимуществу cycleGAN: ему больше не нужны парные сэмплы в процессе обучения. Однако наличие парных образцов - не всегда плохо. Одним из достоинств парных образцов является то, что они накладывают строгие ограничения на сгенерированные изображения, так что, за исключением желаемых настроек (например, зебры), остальная часть сгенерированных изображений не изменится по сравнению с исходными изображениями. Хотя мы принимаем это ограничение как должное, когда у нас есть парные образцы, потому что оно естественно приходит с сильно коррелированными парными изображениями, это уже не так, когда мы переключаемся на непарные образцы, где нет корреляции между исходными изображениями и целевыми изображениями. Это может вызвать проблемы, если мы продолжим обучать один GAN на этих непарных выборках, то есть в какой-то момент обучения мы можем понять, что наша GAN начинает генерировать случайные изображения зебры, которые имеют небольшую корреляцию или вообще не коррелируют с изображениями лошадей. мы его кормим. Это точно та ситуация, с которой мы не хотим сталкиваться. Поэтому, чтобы избавиться от этого, гениальные создатели cycleGAN изобрели концепцию под названием C ycle Consistency, которая вернет ограничение на сгенерированные изображения с помощью дополнительной функции потерь. Сами создатели прекрасно объяснили последовательность цикла в своей статье:

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

- Непарный преобразование изображения в изображение с использованием согласованных с циклом состязательных сетей, 2017.

Допустим, вы хотите перевести французское предложение на английский и хотите увидеть, насколько хорошо вы справились с работой. Хороший способ оценить ваш перевод - это повторно перевести английское предложение обратно на французский, и в идеале ваш результат должен быть точно таким же, как и исходное французское предложение. Та же самая логика может быть применена здесь: чтобы убедиться, что наша модель находится на правильном пути, сохраняя сгенерированное изображение коррелированным с входными данными, мы сначала позволяем GAN A взять изображение лошади и передать его в сгенерированное изображение зебры, а затем скормить его непосредственно в GAN B, который по своей природе возвращает нам сгенерированное изображение лошади. В идеале окончательно сгенерированное изображение лошади должно выглядеть точно так же, как и исходное изображение лошади, точно так же, как повторно переведенное французское предложение соответствует исходному французскому предложению. Если выяснится, что между ними есть существенная разница, тогда мы будем знать, что GAN A может работать не очень хорошо и нуждается в обновлении путем обучения. Все, что нам нужно сделать, это преобразовать разницу между двумя изображениями лошади в функцию потерь. Этот процесс называется Forward Cycle, половина структуры цикла, которая фокусируется на оценке GAN A. Другая половина цикла, которая называется Backward Cycle, будет иметь точно такой же рабочий процесс, что и его аналог, но в обратном направлении, так что он может оценивать GAN B. Комбинируя две функции потерь из прямого и обратного циклов, мы получаем общую функцию потерь, называемую Cycle Consistency Loss, и мы будем задействовать ее как часть окончательной функции потерь, которую мы будем использовать для обновления модели cycleGAN.

Утрата личности

После реализации Cycle Consistency Loss, похоже, нам больше не нужно беспокоиться о непоследовательности нашей модели. Однако в ходе своих экспериментов создатели CycleGAN выяснили, что, хотя исходные зебры, похоже, имеют ту же форму и другие элементы, что и входные лошади при ограничении согласованности цикла, согласованность цветового профиля между входами и выходами не поддерживалась очень хорошо с помощью модель. Чтобы решить эту проблему, они изобрели другую структуру под названием Identity Mapping. Эта структура снова состоит из двух компонентов, как и Cycle Consistency, где один из них фокусируется на производительности GAN A, а другой оценивает GAN B. Чтобы оценить GAN A, например, вместо того, чтобы кормить его изображением лошади, мы дадим ему изображение зебры. По своей природе GAN A сгенерирует новое изображение зебры на основе исходной зебры. В идеале все элементы, лежащие на двух изображениях, включая цвета, должны выглядеть одинаково. Опять же, мы преобразуем разницу между двумя изображениями в функцию потерь и объединяем ее с функцией потерь из других компонентов, чтобы сформировать функцию потери идентичности, которая также будет частью окончательной функции потерь.

Архитектуры модулей

Взглянув на макроструктуру циклаGAN, давайте погрузимся в микроструктуру каждого дискриминатора и генератора внутри циклаGAN.

Дискриминатор

Напомним, что для дискриминатора задача состоит в том, чтобы взять изображение и вывести двоичный результат (Истина или Ложь), который отражает его суждение о том, является ли входное изображение реальным или поддельным.

Структура дискриминаторов, развернутых в cycleGAN, несколько традиционна: полностью сверточные нейронные сети с пятью блоками слоев, где каждый блок содержит слой двумерной свертки с размером ядра 4x4 и шагом 2, слой нормализации экземпляра и слой утечки ReLU (за исключением выходной блок, который использует сигмовидный слой в качестве активации). Каждый раз, когда изображение помещается в дискриминатор, каждый из первых четырех блоков слоев будет уменьшать размер изображения вдвое и удваивать количество каналов. Следовательно, после четвертого уровня вход будет иметь размер 16x16 с 512 каналами (вход модели имеет размер 256x256). Наконец, блок выходного слоя свернет 512 каналов в одну матрицу 16x16 в качестве окончательного вывода.

Подождите, почему у нас в результате матрица 16x16 вместо двоичной True / False? Это потому, что в cycleGAN мы используем структуру под названием PatchGAN для дискриминатора. В отличие от обычного дискриминатора, который рассматривает изображение в целом, чтобы определить, настоящее оно или поддельное, дискриминатор PatchGAN сначала разделит входное изображение на несколько участков, а затем вынесет индивидуальные суждения по каждому из них. В нашем случае входное изображение делится на патчи 16x16, в конце каждый патч имеет размер 70x70. Элементы в нашей выходной матрице обозначают возможность реального или ложного предсказания модели, сделанной для каждого патча. Чтобы получить окончательное двоичное суждение, мы могли либо просто усреднить их, либо сравнить выходную матрицу с матрицей ожидаемых значений и вычислить разницу. Более подробную информацию о PatchGAN можно найти здесь.

Генератор

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

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

Трансформатор добавляет желаемые функции к входу, сохраняя при этом его размер неизменным. Он содержит шесть остаточных сетевых блоков, или сокращенно ResNet. Каждый ResNet содержит два блока слоев: первый блок слоя содержит слой 2D свертки (с шагом = 1), слой нормализации экземпляра и слой утечки ReLU. Блок второго слоя содержит слой двумерной свертки (с шагом = 1) и слой нормализации экземпляра. Преобразованный ввод затем передается в декодер.

Декодер увеличивает входной сигнал до исходного размера и сворачивает все каналы в RGB, чтобы сформировать окончательное выходное изображение. Процесс увеличения достигается стеком из двух транспонированных слоев свертки. Для простоты вы можете рассматривать транспонированный сверточный слой как комбинацию 2D-слоя с повышенной дискретизацией и 2D-сверточного слоя с шагом = 1. Вообще говоря, это увеличит размер ввода при уменьшении количества каналов. В конце концов, данные 256x256 пикселей с 64 каналами, созданные двумя транспонированными сверточными слоями, будут поданы на выходной слой, который свернет каналы в RGB и, таким образом, выведет его как окончательное выходное изображение.

Обучение CycleGAN

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

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

Обновление веса генератора с помощью составной модели

Составные модели, которые мы используем здесь для обучения генераторов в cycleGAN, более сложны, чем обычные случаи. Традиционно составная модель генерирует только одну функцию потерь - состязательную потерю, которая отражает, насколько хорошо дискриминатор идентифицирует поддельные изображения, созданные генератором. Однако для генератора cycleGAN, как мы обсуждали ранее, должны быть задействованы еще три функции потерь - потеря идентичности и потеря согласованности в прямом / обратном направлении. В результате в нашей составной модели есть четыре независимых компонента, которые дают четыре функции потерь. В то время как состязательная потеря представлена ​​функцией потерь L2, остальные три представлены функцией L1. После вычисления четырех функций потерь они усредняются по весу для получения окончательной функции потерь, в которой потеря согласованности цикла имеет наибольший вес, а эффект от состязательной потери преуменьшается. В конце каждой итерации мы записываем окончательную функцию потерь и используем Adam SGD для обновления веса модели генератора.

Обновление веса дискриминатора с помощью пула изображений

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

Пул изображений - это набор не более 50 поддельных изображений, созданных генератором в прошлых итерациях. Согласно статье Сары Вольф, цель пулов изображений - предотвратить резкое изменение модели cycleGAN от итерации к итерации. Для этого на каждой итерации мы будем случайным образом выбирать одно поддельное изображение из пула для обучения дискриминатора вместо того, чтобы загружать его изображением, созданным непосредственно генератором. Ниже представлена ​​диаграмма, показывающая, как пул изображений реализуется и обновляется.

Когда у нас есть два изображения, все, что нам нужно сделать, это поместить их в дискриминатор по отдельности и просуммировать две функции потерь, представленные L2. Мы записываем сумму потерь и обновляем вес дискриминатора с помощью Adam SGD.

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

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

Отображение результатов

Модель, полученная после 75 эпох, на самом деле демонстрирует впечатляющую способность естественно и точно наносить зебру на лошадь.

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

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

Некоторые неудачи

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

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

Ошибка перевода также возникает, когда кто-то другой оказывается слишком близко к лошади, например, очаровательный мистер Ким Чен Ын.

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

Ссылка

Непарный преобразование изображения в изображение с использованием согласованных по циклу состязательных сетей (страница Github)

Непарный преобразование изображения в изображение с использованием согласованных по циклу состязательных сетей (Бумага)

CycleGAN: обучение переводу изображений (без парных обучающих данных)

Как реализовать модели CycleGAN с нуля с помощью Keras

Как использовать слои UpSampling2D и Conv2DTranspose в Keras

Спасибо за чтение! Не стесняйтесь заглядывать на нашу страницу Github, чтобы узнать о данных и коде этого проекта.