Генеративные и дискриминативные вычисления

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

Например, учитывая каждое из слов в электронном письме (информационный случай), дискриминационные вычисления могут предвидеть, является ли сообщение спамом или нет_спамом. Спам – это одно из имен, а набор слов, накопленный в электронном письме, – это ярлыки, составляющие информационную информацию. В момент, когда этот вопрос передается научным путем, имя называется y, а основные моменты – x. Определение p(y|x) используется для обозначения “вероятность того, что y дано x”, что в данной ситуации означает “вероятность того, что письмо является спамом, учитывая слова, которые в нем содержатся”.

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

На вопрос, на который пытаются ответить генеративные вычисления, они пытаются ответить: Ожидая, что это письмо будет спамом, какова вероятность того, что эти ярлыки будут выделяться? В то время как дискриминационные модели заботятся о связи между y и x, генеративные модели заботятся о том, “как вы получите x”. Они позволяют вам поймать p(x|y), вероятность x, заданную y, или вероятность светлых участков, заданных именем или классом. (Все, что учитывается, генеративные вычисления также могут быть использованы в качестве классификаторов. По какой-то странной причине они могут выполнить больше, чем просто ввести информацию о порядке).

Другой подход к рассмотрению этого вопроса заключается в распознавании дискриминационного от генеративного типа:

Дискриминантные модели знакомятся с пределом между классами.

Генеративные модели моделирование дисперсии отдельных классов

Как работают GAN

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

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

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

Вот средства, которые принимает GAN:

Генератор берет произвольное число и возвращает картинку.

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

Дискриминатор делает как подлинные, так и поддельные снимки и возвращает вероятности, число где-то в диапазоне 0 и 1, при этом 1 говорит об ожидании достоверности и 0 говорит о подделке.

Таким образом, у вас есть двойной входной круг:

Дискриминатор находится в входном круге с основной правдой картинок, которую мы знаем.

Генератор находится в круге ввода с дискриминатором.

Схема GAN
Кредит: О’Райли

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

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

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

GANs
GAN, автокодировщики и VAE.

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

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

схема автокодера
Советы по подготовке GAN

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

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

Каждая сторона GAN может перегрузить другую. В случае, если дискриминатор слишком велик, он вернет почтение, настолько близкое к 0 или 1, что генератор будет бороться за то, чтобы проследить за наклоном. В случае, если генератор слишком велик, он будет упорно искать приключений, которые приведут к фальшивым негативам. Это может сдерживаться индивидуальной скоростью обучения сети. Две нейронные системы должны иметь сопоставимый “уровень способностей”. 1

GAN отложили долгие усилия, чтобы подготовиться. На одиночном GPU GAN может потребоваться несколько часов, а на одиночном CPU – более одного дня. Несмотря на то, что GAN трудно настраивать и, следовательно, использовать, они вдохнули новую жизнь в увлекательное исследование и композиторское мастерство.

Вот пример GAN, закодированного в Keras, из которого модели могут быть импортированы в Deeplearning4j.

Class GAN():

Def __init__(self):

    self.img_rows = 28

    self.img_cols = 28

    self.каналы = 1

    self.img_shape = (self.img_rows, self.img_cols, self.img_cols, self.channels)

    оптимизатор = Адам(0.0002, 0.5)

    # Сборка и компиляция дискриминатора

    self.discriminator = self.build_discriminator()

    self.discriminator.compile(loss='binary_crossentropy',

        Оптимизатор=оптимизатор,

        метрика=['точность'])

    # Сборка и компиляция генератора

    self.generator = self.build_generator()

    self.generator.compile(loss='binary_crossentropy', оптимизатор=оптимизатор)

    # Генератор принимает шум как входной сигнал и генерирует imgs.

    z = Input(shape=(100,))

    img = self.generator(z)

    # Для комбинированной модели мы будем тренировать только генератор.

    само.дискриминатор.обучаемый = Ложный

    # " Валидный принимает сгенерированные изображения в качестве входных и определяет валидность

    действительный = self-.discriminator(img)

    # Комбинированная модель (уложенный в стек генератор и дискриминатор) берет

    # noise as input => генерирует изображения => определяет достоверность

    self.combined = модель(z, действительна)

    self.combined.compile(loss='binary_crossentropy', оптимизатор=оптимизатор)

def build_generator(self):

    noise_shape = (100,)

    model = Sequential()

    model.add(Dense(256, input_shape=noise_shape)))

    model.add(LeakyReLU(alpha=0.2))

    model.add(Пакетная нормализация (импульс = 0.8))

    model.add(Dense(512))

    model.add(LeakyReLU(alpha=0.2))

    model.add(Пакетная нормализация (импульс = 0.8))

    model.add(Dense(1024))

    model.add(LeakyReLU(alpha=0.2))

    model.add(Пакетная нормализация (импульс = 0.8))

    model.add(Dense(np.prod(self.img_shape), activation='tanh')))

    model.add(Reshape(self.img_shape)))

    model.summary()

    noise = Input(shape=noise_shape)

    img = модель (шум)

    возврат Модель (шум, мг)

def build_discriminator(self):

    img_shape = (self.img_rows, self.img_cols, self.channels)

    model = Sequential()

    model.add(Flatten(input_shape=img_shape)))

    model.add(Dense(512))

    model.add(LeakyReLU(alpha=0.2))

    model.add(Dense(256))

    model.add(LeakyReLU(alpha=0.2))

    model.add(Dense(1, activation=сигмоид')))

    model.summary()

    img = Input(shape=img_shape)

    действительность = модель(img)

    Вернуться Модель (img, действительность)

def train(self, epochs, batch_size=128, save_interval=50):

    # Загрузить набор данных

    (X_train, _), (_, _) = mnist.load_data()

    # Шкала -1 к 1

        X_train = (X_train.astype(np.float32) - 127.5) / 127.5

        X_train = np.expand_dims(X_train, axis=3)

        half_batch = int(размер_пакета / 2)

        для эпох в диапазоне (эпохах):

            # ---------------------

            # Дискриминатор поезда

            # ---------------------

            # Выберите случайную полупартию изображений

            idx = np.random.randint(0, X_train.shape[0], half_batch)

            imgs = X_train[idx]

            шум = np.random.normal(0, 1, (half_batch, 100))

            # Сгенерируйте пол-партии новых изображений

            gen_imgs = self.generator.predict(шум)

            # Тренируйте селектор

            d_loss_real = self.discriminator.train_on_batch(imgs, np.ones((half_batch, 1))))

            d_loss_fake = self.discriminator.train_on_batch(gen_imgs, np.zeros((half_batch, 1))))

            d_loss = 0.5 * np.add(d_loss_real, d_loss_fake)

            # ---------------------

            # Генератор поезда

            # ---------------------

            шум = np.random.normal(0, 1, (batch_size, 100))

            # Генератор хочет, чтобы дискриминатор пометил сгенерированные образцы.

            # как действующие (те)

            valid_y = np.array([1] * batch_size)

            # Тренируйте генератор

            g_loss = self.combined.train_on_batch(шум, valid_y)

            # Заложите прогресс

            распечатать ("%d [D loss: %f, acc.: %.2f%%] [G loss: %f]" % (эпоха, d_loss[0], 100*d_loss[1], g_loss))

            # Если на интервале сохранения => сохранить сгенерированные образцы изображений

            если эпоха % save_interval == 0:

                self.save_imgs(epoch)

    def save_imgs(self, epoch):

        r, c = 5, 5

        шум = np.random.normal(0, 1, (r * c, 100))

        gen_imgs = self.generator.predict(шум)

        # Масштабирование изображений 0 - 1

        gen_imgs = 0.5 * gen_imgs + 0.5

        fig, axs = plt.subplots(r, c)

        коэффициент усиления = 0

        для i в диапазоне(r):

            для j в диапазоне(c):

                axs[i,j].imshow(gen_imgs[cnt, :,:,0], cmap='gray')

                axs[i,j].axis('off')

                коэффициент += 1

        fig.savefig("gan/images/mnist_%d.png" % эпоха)

        plt.close()

если __name_ == '__main__':

    gan = GAN()

    gan.train(epochs=30000, batch_size=32, save_interval=200)