Учитывая набор данных mugshots из Национального института стандартов и технологий (NIST), у нас есть обычные фронтальные и боковые хедшоты.

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

Идея

Нет, это не моя первоначальная идея, это заслуга Адама Чина, бывшего коллеги и друга.

Основная литература, которую я собираюсь использовать в своих исследованиях, это
* noise2noise
* U-Net
* Image-to-Image

Есть также большое количество сообщений в блогах, посвященных этой теме. У Джонатана Хуэя, например, есть целая серия, охватывающая Серия GAN - GAN (от начала до конца), которая мне очень помогла.

Некоторое время назад в разговоре с Адамом он сказал мне, что видел выступление Яакко Лехтинена из NVIDIA на SIGGRAPH 2018 в Лос-Анджелесе, Калифорния, рассказывающего об их работе в области машинного обучения и Noise2Noise: обучение восстановлению изображений без чистых данных. . И по его словам:

… Это меня просто взорвало.

Я должен признать, что все достижения в области машинного обучения за последние несколько лет очень увлекательны и являются одной из причин, почему я вообще заинтересовался этой областью. В качестве примечания здесь, TensorFlow Graphics, которая была опубликована в начале мая 2019 года, определенно в моем списке, чтобы проверить ее в следующий раз.

Доклад Noise2Noise: обучение восстановлению изображений без чистых данных был первоначально представлен на ICML и неоднократно выступал в докладах на SIGGRAPH 2018.

Во введении к статье говорится

… Мы применяем базовые статистические рассуждения для реконструкции сигналов с помощью машинного обучения - обучения отображать искаженные наблюдения в чистые сигналы - с простым и убедительным выводом: можно научиться восстанавливать изображения, только глядя на поврежденные примеры, с производительностью на уровне, а иногда и превышающим обучение с использованием чистых данных без явных априорных значений изображений или моделей вероятности повреждения. На практике мы показываем, что одна модель изучает удаление фотографического шума, шумоподавление синтетических изображений Монте-Карло и реконструкцию изображений МРТ с недостаточной дискретизацией - все они повреждены различными процессами - только на основе зашумленных данных.

Итак, каковы следующие шаги в моем исследовании?
1. Прочтите документы, перечисленные выше, в основном статью Преобразование изображения в изображение с условными состязательными сетями
2. TensorFlow имеет отличную коллекцию материалов Что касается грядущей версии 2.0 (в настоящее время в стадии бета), меня особенно интересует часть о pix2pix.
3. Примените все, что я узнал, и используйте это в наборе данных снимков.

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

Прежде чем мы углубимся в статью pix2pix, несколько слов о базе данных снимков:
* Набор данных состоит из 3248 изображений различных размеров в формате PNG с соответствующими метаданными в виде файлов TXT.
* Есть изображения 1573 человек. из них 1495 мужчин и 78 женщин.
* База данных содержит виды спереди и сбоку (в профиль), если они доступны. Имеется 131 ящик с двумя или более видами спереди и 1418 ящиков только с одним видом спереди.
* Всего 89 ящиков с двумя или более профилями и 1268 ящиков только с одним профилем. Ящики с обоими фасадами и профилями имеют 89 ящиков с двумя или более фасадами и профилями, 27 с двумя или более фасадами и одним профилем и 1217 ящиков только с одной лицевой стороной и одним профилем.

Бумаги)

Для проекта mugshot я хотел лучше понять используемые в настоящее время методы в отношении Generative Adversarial Network (GAN). Сейчас я просто пытаюсь сосредоточиться на статье Преобразование изображения в изображение с условными состязательными сетями Калифорнийского университета в Беркли, опубликованной в 2017 году. А также на статье U-Net: сверточные сети для биомедицинских Сегментация изображений из Университета Фрайбурга, Германия, опубликованная в 2015 году.

Изображение в изображение - Введение

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

Мы можем переосмыслить проблему, используя терминологию, которую мы можем найти в программном обеспечении для обработки изображений, таком как Photoshop, например, морфинг, смешивание, размытие, улучшение, обнаружение краев и многое другое. Давайте посмотрим на приведенный выше пример, у нас есть левая сторона в качестве входных данных и мы хотим получить правую часть в качестве выходного изображения. Центральное изображение, называемое «наземной истиной», - это изображение, на котором мы обучаем нашу сеть вместе с входным изображением для генерации выходного изображения. Другой способ взглянуть на это: мы создаем «карту», ​​которая будет помещена поверх нашего наземного истинного изображения, и на основе разноцветных полей grep (узнаем) информацию, найденную в наземном истинном изображении. Затем это используется для создания нашего выходного изображения. Итак, там, где у нас есть салатовый цвет на входном изображении, мы можем найти на исходном изображении балкон. Каждый цвет выделяет разные части фасада, и наша сеть изучает, что это такое, чтобы сгенерировать выходное изображение. Так же просто, как создать что-нибудь из лего. Или скопируйте и вставьте фрагменты информации из одного изображения, чтобы создать новое изображение. В этом конкретном примере важно отметить, что разные цвета на входном изображении в основном являются нашими метками для определения частей фасада. В то время как в других случаях мы можем использовать изображение в оттенках серого для создания цветного изображения или использовать рисунок краев для создания сумочки или обуви. Короче говоря, GAN - это генеративные модели, которые изучают отображение вектора случайного шума z на выходное изображение y, G: z → y ¹.

Метод

Для достижения показанных здесь результатов исследователи используют архитектуру на основе «U-Net» для своего генератора и сверточный классификатор «PatchGAN» для дискриминатора. Чтобы добиться того, что генератор выдает выходной сигнал, который нельзя отличить от «реальных» изображений, исследователи использовали условный GAN для изучения сопоставления с изображением x и вектором случайного шума z , чтобы сгенерировать выходное изображение y, G: {x, z} → y. Как описано выше, «связывая» входное изображение с наземным истинным изображением, мы определяем условие.

Сетевые архитектуры

Компоненты генератора и дискриминатора архитектуры были адаптированы из статьи «Неконтролируемое обучение представлений с глубокими сверточными порождающими состязательными сетями» ², и оба используют модули свертки-BatchNorm-ReLu³.

Генератор

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

В подходе Image-to-Image были добавлены пропуски соединений, чтобы обойти узкое место, следуя общей форме «U-Net». Здесь исследователь добавил пропускные соединения между каждым слоем i и слоем n-i, где n - общее количество слоев.

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

Как говорится в статье, хорошо известно, что потери L2 и L1 дают нечеткие результаты; тем не менее, они правильно передают низкие частоты изображения. Это переключает внимание на высокочастотную структуру изображения, и исследователи разработали архитектуру дискриминатора - которую они назвали Patch GAN - которая ограничивает структуру только в масштабе фрагментов. Здесь дискриминатор пытается определить, является ли каждый фрагмент N x N в изображении реальным или нет. Фактически, как марковское случайное поле и, следовательно, может рассматриваться как форма потери текстуры / стиля.

Оптимизация

В исходной статье GAN [¹] описан подход к оптимизации сети путем чередования одного шага градиентного спуска на D, а затем одного шага на G. И, как там также предлагается, вместо этого они тренируются, чтобы максимизировать log D (x, G (x, z)).

Эксперименты

Чтобы проверить условную GAN и ее универсальность, исследователи использовали множество задач и наборов данных:

* Семантические метки↔photo, обученные на наборе данных Cityscapes⁴.
* Архитектурные надписи → фото, обученные на CMP Facades⁹.
* Карта Аэрофотоснимок, обучен на данных, собранных с Google Maps.
* BW → цветные фотографии, обучен на¹⁰.
* Края → фото , обученный на данных из [¹¹] и [¹²]; бинарные края, созданные с помощью детектора краев HED¹³ плюс постобработка.
* Эскиз → фото: тестирует края → фотомодели на человеческих эскизах из [⁵].
* День → ночь, обучение на [⁸].
* Тепловое → цветные фотографии, обучение на данных из [⁷].
* Фотография с пропущенными пикселями → раскрашенная фотография, обученная на Paris StreetView из [⁶].

Уже

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

Более того, я, читая газету с мыслями о проекте «mugshot», считаю, что возможно - надеюсь - перейти от выстрела в голову к виду сбоку. Для более глубокого чтения я рекомендую вам прочитать сам документ.

Архитектура

Простая идея проекта «mugshots» состоит в том, чтобы создать вид сбоку из заданного изображения, показывающего вид лица спереди. Я знаю, о чем вы, вероятно, думаете: «… это невозможно». Тем не менее, после прочтения статьи Image-to-Image и U-Net, а также некоторых других статей, посвященных теме генеративной состязательной сети (GAN), я подумал, что это будет интересный тестовый проект, чтобы попробовать это. Реализованная мной модель GAN основана на этих документах с некоторыми изменениями.

В предыдущем посте я рассмотрел статью о преобразовании изображения в изображение. В документе Image-to-Image говорится, что он использует архитектуру на основе «U-Net» для своего генератора и сверточный классификатор «PatchGAN» для дискриминатора. Все внесенные мной изменения есть в U-Net. U-Net имеет с левой стороны канал понижающей дискретизации и канал повышающей дискретизации с правой стороны. «Незначительным» дополнением здесь является то, что я добавил полностью связанные слои, чтобы детали могли перемещаться.

Flatten ->
Dense -> LeakyReLU ->
Dense -> LeakyReLU ->
Dense -> LeakyReLU ->
Dense -> LeakyReLU ->
Dense -> LeakyReLU ->
Reshape

В общем, я сохранил данную структуру, как описано в документе, как есть:

Набор данных

В распакованном наборе данных есть несколько подкаталогов, из которых мы используем только каталог sd18. Чтобы упростить обработку данных, я организовал изображения, разделив их на набор для поездов и тестов, и в конечном итоге сохранил все в файл hdf5. Всего у нас есть 2434 изображения, одна половина - вид спереди, а другая половина - вид сбоку.

1. Я скопировал все изображения из подкаталогов sd18 в отдельный каталог и переименовал их.
2. Поскольку все изображения имеют разный размер и соотношение, я изменил их размер до 256x256.
3. Чтобы упростить задачу, я убедился, что все изображения вида сбоку соответствуют правому, перевернув левое изображение с помощью numpy (np.fliplr (image)).
4. После этого я разделил набор данных на каталоги для обучения и тестирования (80/20).

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

def random_jitter(image):
  image = tf.image.resize(image, [286, 286],
             method=tf.image.ResizeMethod.NEAREST_NEIGHBOR)
  image = tf.image.random_crop(image, size=[256, 256, 3])
  image = tf.image.random_flip_left_right(image)
  return image
for filename in filenames:
  image = load(filename)
  for i in range(4):
    image = random_jitter(image)

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

Примечание. Мы могли бы захотеть изучить класс Keras `ImageDataGenerator` для генерации пакетов расширенных данных тензорного изображения. Подобно тому, что я сделал выше с изображениями, мы можем вращать, масштабировать, переворачивать и т. Д.

datagen = ImageDataGenerator(
              featurewise_center=True,
              featurewise_std_normalization=True,
              rotation_range=20,
              width_shift_range=0.2,
              height_shift_range=0.2,
              horizontal_flip=True)

Генерировать

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

x = tf.keras.layers.Flatten()(conv7)
x = tf.keras.layers.Dense(512, input_shape=(1, 1, 512), 
                          name=’dense1')(x)
x = tf.keras.layers.LeakyReLU(alpha=0.2)(x)
x = tf.keras.layers.Dense(512, input_shape=(1, 1, 512), 
                          name=’dense2')(x)
x = tf.keras.layers.LeakyReLU(alpha=0.2)(x)
x = tf.keras.layers.Dense(512, input_shape=(1, 1, 512), 
                          name=’dense3')(x)
x = tf.keras.layers.LeakyReLU(alpha=0.2)(x)
x = tf.keras.layers.Dense(512, input_shape=(1, 1, 512), 
                          name=’dense4')(x)
x = tf.keras.layers.LeakyReLU(alpha=0.2)(x)
x = tf.keras.layers.Dense(512, input_shape=(1, 1, 512),
                          name=’dense5')(x)
x = tf.keras.layers.LeakyReLU(alpha=0.2)(x)
x = tf.keras.layers.Reshape((1, 1, 512))(x)

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

Что касается модели дискриминатора, я не вносил никаких изменений в то, что описано в документе и реализовано как есть. Точно так же я использовал те же гипер-значения для «настройки» модели и функций потерь.

Результат (пока)

Мысли

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

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

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

Сноски

[¹]: И. Гудфеллоу, Дж. Пуже-Абади, М. Мирза, Б. Сюй, Д. Вард-Фарли, С. Озаир, А. Курвиль и Ю. Бенжио. Генеративные состязательные сети. В NIPS, 2014.
[²]: А. Рэдфорд, Л. Мец и С. Чинтала. Неконтролируемое обучение представлений с глубокими сверточными порождающими состязательными сетями. В ICLR, 2016.
[³]: С. Иоффе и К. Сегеди. Пакетная нормализация: ускорение глубокого обучения сети за счет уменьшения внутреннего ковариантного сдвига. В ICML, 2015.
[⁴]: М. Кордтс, М. Омран, С. Рамос, Т. Рефельд, М. Энцвейлер, Р. Бененсон, У. Франке, С. Рот и Б. Шиле. Набор данных cityscapes для семантического понимания городской сцены. В CVPR, 2016 г.
[⁵]: М. Эйтц, Дж. Хейс и М. Алекса. Как люди рисуют предметы? В SIGGRAPH, 2012.
[]: C. Doersch, S. Singh, A. Gupta, J. Sivic и A. Efros. Чем Париж похож на Париж? ACM Transactions on Graphics, 31 (4), 2012.
[⁷]: С. Хван, Дж. Пак, Н. Ким, Я. Чой и И. Со Квеон. Обнаружение мультиспектральных пешеходов: контрольный набор данных и базовая линия. В CVPR, 2015
[⁸]: P.-Y. Laffont, Z. Ren, X. Tao, C. Qian и J. Hays. Переходные атрибуты для высокоуровневого понимания и редактирования наружных сцен. ACM Transactions on Graphics (TOG), 33 (4): 149, 2014.
[⁹]: R.S. Радим Тайлечек. Шаблоны пространственных узоров для распознавания объектов с регулярной структурой. На немецкой конференции по распознаванию образов, 2013.
[¹⁰]: О. Русаковский, Дж. Денг, Х. Су, Дж. Краузе, С. Сатиш, С. Ма, З. Хуанг, А. Карпати, А. Хосла, М. Бернштейн и др. Imagenet - проблема распознавания изображений в большом масштабе. Международный журнал компьютерного зрения, 115 (3): 211–252, 2015.
[¹¹]: J.-Y. Чжу, П. Крахенбуль, Э. Шехтман и А. А. Эфрос. Генеративная визуальная манипуляция на многообразии естественных изображений. В ECCV, 2016.
[¹²]: А.Ю., К. Грауман. Детальные визуальные сравнения с местным обучением. В CVPR, 2014.
[¹³]: С. Се и З. Ту. Обнаружение краев с целостным вложением. В ICCV, 2015.