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

Для первого поста я решил использовать Generative Adversarial Networks. Я рассмотрю весь процесс проектирования сетей GAN с учетом промежуточных настроек, если кто-то попытается выполнить и воспроизвести код.

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

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

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

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

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

Все сказано и сделано, если бы у нас было что-то попроще для имитации (например, просто дистрибутив), это сработало бы. Так что простая часть (правда ли?) Сделана.

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

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

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

Таким образом, сеть с 2 плотными слоями и 3 слоями дек-свертки будет работать с изображениями размером до 32 x 32 x каналов.

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

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

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

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

Мы снова используем модуль tf.layers для реализации по уровням нормализации размера, чтобы оптимизировать обучение. После этого мы можем запустить эту модель, обучить и получить хорошие изображения.

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

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

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

Результаты

Эта модель GAN изучает большую часть того, что может около 50-й эпохи, и только позже переходит в режим коллапса во время обучения, даже если обучение проводится более чем примерно в 600 эпох.

использованная литература

  1. Салиманс, Т., Гудфеллоу, И., Заремба, В., Чунг, В., Рэдфорд, А., и Чен, X. (2016). Улучшенные методы обучения GAN, 1–10. Https://doi.org/arXiv:1504.01391
  2. Код доступен по адресу https://github.com/prannayk/thedeeplearning.

Следующий

На следующей неделе я напишу в блоге сообщения о вариантах WGAN и EBGAN, а также еще один пост о GAN с вариационным автокодировщиком.