С возвращением в серию Tensorflow !!

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

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

Генеративные состязательные сети (GAN) - это архитектуры глубоких нейронных сетей, состоящие из набора двух сетей, которые конкурируют друг с другом, отсюда и название состязательные. GAN были представлены в статье Иэна Гудфеллоу и других исследователей из Монреальского университета, в том числе Йошуа Бенжио, в 2014 году.

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

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

Сети GAN требуют больших вычислительных ресурсов в том смысле, что для получения хороших результатов требуются мощные графические процессоры. Ниже приведены некоторые из фальшивых лиц знаменитостей, созданных GAN после нескольких эпох обучения на 8 GPU Tesla V 100 в течение 4 дней !!

Мы будем использовать менее аппаратный пример. В этом посте мы будем использовать набор данных MNIST, чтобы поиграть с простым GAN, который будет создан с использованием Tensorflow Layers API. Прежде чем перейти к коду, я рассмотрю две проблемы, которые обычно возникают с GAN:

  1. Дискриминатор, превосходящий генератор: Иногда дискриминатор начинает классифицировать все сгенерированные примеры как поддельные из-за малейших различий. Итак, чтобы исправить это, мы сделаем вывод дискриминатора немасштабированным, а не сигмоидальным (который дает только ноль или единицу).
  2. Свертывание режима: генератор обнаруживает некоторые потенциальные слабые места в дискриминаторе и использует эту слабость для непрерывного создания аналогичного примера независимо от вариации входных данных.

Итак, наконец, перейдем к коду !!

Во-первых, мы импортируем необходимые библиотеки и считываем набор данных MNIST из tensorflow.examples.tutorials.mnist.

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

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

Теперь мы создаем плахолдеры для наших входов. real_images - это фактические изображения из MNIST, а z - это 100 случайных пикселей из фактических изображений. Чтобы дискриминатор мог его классифицировать, сначала необходимо знать, как выглядят реальные изображения, поэтому у нас есть два вызова функции дискриминатора: первые два изучают фактические изображения, а вторые два идентифицируют поддельные изображения. reuse имеет значение true, потому что, когда одни и те же переменные используются в двух вызовах функций, граф вычисления тензорного потока получает неоднозначные сигналы и имеет тенденцию выдавать ошибки значений. Следовательно, мы устанавливаем параметр повторного использования на True, чтобы избежать таких ошибок.

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

Когда у нас есть две отдельные сети, взаимодействующие друг с другом, мы должны учитывать переменные в каждой сети. Следовательно, при определении функций был установлен tf.variable_scope. В этом примере мы будем использовать оптимизатор Adam. Устанавливаем batch_size и количество эпох. Увеличение эпох приводит к лучшим результатам, так что поиграйте с этим (желательно, если у вас есть доступ к графическому процессору).

Наконец, мы инициируем сеанс и используем метод next_batch() из вспомогательных функций тензорного потока для обучения сетей. Мы берем случайную выборку из сгенерированных выборок Генератора и добавляем ее в список выборок.

График первого значения из samples показывает производительность генератора после первой эпохи. Сравнение с последним значением из samples показывает, насколько хорошо работает генератор.

Выходы выглядят примерно так:

Это очень плохие результаты, но поскольку мы обучаем нашу модель только на CPU, обучение довольно слабое. Но, как мы видим, модель начинает генерировать пиксели более кратким образом, и мы можем как бы догадаться, что эта цифра - «3».

GAN предназначены для обучения на графических процессорах, поэтому попробуйте получить доступ к графическому процессору или просто попробуйте Google Colab, чтобы получить гораздо лучшие результаты.

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

До следующего раза!!