Итак, сегодня я был вдохновлен этим сообщением в блоге Генеративные состязательные сети в TensorFlow, и я хотел сам реализовать GAN с помощью Numpy. Вот оригинальная статья GAN от @ goodfellow_ian. Ниже - гифка со всеми изображениями, сгенерированными из Simple GAN.

Прежде чем читать дальше, обратите внимание, что я не буду слишком много рассказывать о математике. Скорее реализация кода и результатов, я расскажу о математике, возможно, позже. И я использую Adam Optimizer, однако я не буду вдаваться в объяснение реализации Adam в этом посте.

Прямая подача / частичное обратное распространение дискриминатора в GAN

Опять же, я не буду вдаваться в подробности, но обратите внимание на область с красной рамкой под названием Данные. Для сети дискриминатора в GAN эти данные могут быть либо реальным изображением, либо поддельным изображением, созданным сетью генератора. Наши изображения представляют собой (1,784) вектора набора данных MNIST.

Еще одно замечание: Красный (L2A) и Синий (L2A). Красный (L2A) - это конечный результат нашей сети дискриминатора с реальным изображением на входе. И синий (L2A) - это окончательный результат нашей сети дискриминатора с фальшивым изображением на входе.

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

Строка 128 - Получение данных реального изображения
Строка 147 - Получение данных поддельного изображения (сгенерировано сетью генератора)

Строка 162 - Функция затрат нашей сети дискриминаторов.

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

Разница в том, что мы ставим знак минус (-) перед первым членом log (L2A).

Как видно выше, в реализации TensorFlow мы переворачиваем знаки, если хотим максимизировать какое-то значение, поскольку автоматическая дифференциация TF может только минимизировать.

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

Прямая подача / частичное обратное распространение генератора в GAN

Процесс обратного распространения для генераторной сети в GAN немного сложен.

Синий ящик - сгенерированные поддельные данные из сети генератора
Зеленое поле (левый угол) - дискриминатор принимает сгенерированный (синий ящик) ввод и выполняет процесс прямой подачи

Оранжевая коробка - функция затрат для сети генератора (мы снова хотим максимизировать вероятность получения реалистичных данных)

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

Ниже приведен снимок экрана с реализованным кодом.

Стандартное обратное распространение, ничего особенного.

Результаты обучения: неудачные попытки

Я быстро понял, что обучать GAN чрезвычайно сложно, даже с Adam Optimizer сеть просто не очень хорошо сходилась. Итак, сначала я представлю вам все неудачные попытки и сетевые архитектуры.

  1. Генератор, 2 слоя: 200, 560 скрытых нейронов, размер входного вектора 100

2. Генератор, активация tanh (), 2 слоя: 245, 960 скрытых нейронов, IVS 100

3. Генератор, 3 слоя: 326, 356 412 скрытых нейронов, размер входного вектора 326

4. Генератор, 2 слоя: 420, 640 скрытых нейронов, размер входного вектора 350

5. Генератор, 2 слоя: 660, 780 скрытых нейронов, размер входного вектора 600

6. Генератор, 2 слоя: 320, 480 скрытых нейронов, размер входного вектора 200

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

Extreme Step Wise Gradient Decay

Выше гифка, я знаю, что разница тонкая, но поверьте мне: Я не Рик Роллинг. Уловка предельно проста и легко реализуема. Сначала мы устанавливаем высокую скорость обучения для первого обучения, а после первого обучения мы устанавливаем снижение скорости обучения с коэффициентом 0,01. И по неизвестной причине (я хочу подробнее изучить это, похоже, это работает.)

Но я думаю, что с огромными затратами мы приближаемся к «месту», где сеть может генерировать только определенные виды данных. Это означает, что из равномерного распределения чисел между -1 и 1. Генератор будет генерировать только изображение, которое ТОЛЬКО выглядит как 3 или 2 и т.д. Но ключевым моментом здесь является то, что сеть не может генерировать другой набор чисел. Об этом свидетельствует тот факт, что все числа, представленные на картинке, имеют вид 3.

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

Как видно выше, с течением времени цифры становятся более резкими. Хорошим примером является сгенерированное изображение 3 или 9.

Интерактивный код

Обновление: я перешел на Google Colab для интерактивных кодов! Таким образом, вам понадобится учетная запись Google для просмотра кодов, также вы не можете запускать сценарии только для чтения в Google Colab, поэтому сделайте копию на своей игровой площадке. Наконец, я никогда не буду спрашивать разрешения на доступ к вашим файлам на Google Диске, просто к сведению. Удачного кодирования!

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

При запуске кода убедитесь, что вы находитесь на кране «main.py», как показано выше в зеленой рамке. Программа запросит у вас случайное число для посева, как показано в синей рамке. После того, как он сгенерирует одно изображение, чтобы просмотреть это изображение, нажмите на вкладку Click Me выше, Red Box.

Заключительные слова

Обучение GAN даже частичной работе - это огромный кусок работы, и я хочу изучить более эффективный способ обучения GAN. И последнее, спасибо @ replit, эти парни потрясающие!

Если будут обнаружены какие-либо ошибки, напишите мне по адресу [email protected].

Тем временем подпишитесь на меня в моем твиттере здесь и посетите мой веб-сайт или мой канал Youtube для получения дополнительной информации. Я также сделал сравнение Decoupled Neural Network здесь, если вам интересно.

Ссылки

  1. Гудфеллоу, И., Пуже-Абади, Дж., Мирза, М., Сюй, Б., Вард-Фарли, Д., Озаир, С.,… и Бенжио, Ю. (2014). Генеративные состязательные сети. В книге Достижения в области нейронных систем обработки информации (стр. 2672–2680).
  2. Бесплатный онлайн-создатель анимированных GIF-изображений - легко создавайте изображения в формате GIF. (нет данных). Получено 31 января 2018 г. с сайта http://gifmaker.me/.
  3. Генеративные состязательные сети в TensorFlow. (нет данных). Получено 31 января 2018 г. с сайта https://wiseodd.github.io/techblog/2016/09/17/gan-tensorflow/.
  4. J. (нет данных). Jrios6 / Адам против SGD-Numpy. Получено 31 января 2018 г. с сайта https://github.com/jrios6/Adam-vs-SGD-Numpy/blob/master/Adam%20vs%20SGD%20-%20On%20Kaggles%20Titanic%20Dataset.ipynb.
  5. Рудер, С. (19 января 2018 г.). Обзор алгоритмов оптимизации градиентного спуска. Получено 31 января 2018 г. с сайта http://ruder.io/optimizing-gradient-descent/index.html#adam.
  6. Э. (1970, 01 января). Эрик Джанг. Получено 31 января 2018 г. с сайта https://blog.evjang.com/2016/06/generative-adversarial-nets-in.html.