Сложность в обучении GAN

Я пытаюсь обучить GAN изучать распределение ряда функций в мероприятии. Обученные Дискриминатор и Генератор имеют низкие потери, но сгенерированные события имеют разное распределение по форме, но я не уверен, почему.

Я определяю GAN следующим образом:

def create_generator():

    generator = Sequential()

    generator.add(Dense(50,input_dim=noise_dim))
    generator.add(LeakyReLU(0.2))    
    generator.add(Dense(25))
    generator.add(LeakyReLU(0.2))
    generator.add(Dense(5))
    generator.add(LeakyReLU(0.2))
    generator.add(Dense(len(variables), activation='tanh'))

    return generator


def create_descriminator():
    discriminator = Sequential()

    discriminator.add(Dense(4, input_dim=len(variables)))
    discriminator.add(LeakyReLU(0.2))
    discriminator.add(Dense(4))
    discriminator.add(LeakyReLU(0.2))
    discriminator.add(Dense(4))
    discriminator.add(LeakyReLU(0.2))
    discriminator.add(Dense(1, activation='sigmoid'))   
    discriminator.compile(loss='binary_crossentropy', optimizer=optimizer)
    return discriminator


discriminator = create_descriminator()
generator = create_generator()

def define_gan(generator, discriminator):
    # make weights in the discriminator not trainable
    discriminator.trainable = False
    model = Sequential()
    model.add(generator)
    model.add(discriminator)
    model.compile(loss = 'binary_crossentropy', optimizer=optimizer)
    return model

gan = define_gan(generator, discriminator)

И я обучаю GAN с помощью этого цикла:

for epoch in range(epochs):
    for batch in range(steps_per_epoch):
        noise = np.random.normal(0, 1, size=(batch_size, noise_dim))
        fake_x = generator.predict(noise)

        real_x = x_train[np.random.randint(0, x_train.shape[0], size=batch_size)]

        x = np.concatenate((real_x, fake_x))
        # Real events have label 1, fake events have label 0
        disc_y = np.zeros(2*batch_size)
        disc_y[:batch_size] = 1

        discriminator.trainable = True
        d_loss = discriminator.train_on_batch(x, disc_y)

        discriminator.trainable = False
        y_gen = np.ones(batch_size)
        g_loss = gan.train_on_batch(noise, y_gen)

Мои реальные события масштабируются с помощью стандартного масштабатора sklearn:

scaler = StandardScaler()
x_train = scaler.fit_transform(x_train)

Генерация событий:

X_noise = np.random.normal(0, 1, size=(n_events, GAN_noise_size))
X_generated = generator.predict(X_noise)

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

введите описание изображения здесь

А сопоставление двух характеристик друг с другом для реальных и поддельных событий дает:  введите описание изображения здесь

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


person pythonthrowaway    schedule 12.03.2020    source источник


Ответы (1)


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

person csteel    schedule 27.03.2020
comment
Спасибо за советы, при более внимательном рассмотрении, создавая графики, которые я представлял каждое определенное количество эпох, я понял, что вывод GAN застрял между -1 и 1, но я не совсем уверен, что в моем коде вызывает застревание вывода. этот диапазон - person pythonthrowaway; 29.03.2020
comment
Какой у вас исходный набор данных x_train? Диапазон от -1 до 1 вызван выходным слоем активации tanh в вашем генераторе. Чтобы понять, почему вы получаете это распределение, мне нужно увидеть ваш исходный набор данных x_train или его описание. - person csteel; 30.03.2020
comment
Ах да, исходный набор данных содержит переменные, представляющие такие компоненты, как масса и импульс различных частиц при столкновении, и цель генератора - произвести больше событий этого типа. Эти переменные просто содержат необработанные значения для этих переменных, так что в этом случае что-то вроде функции линейной активации имело бы больший смысл. Исходный набор данных передается через стандартную функцию масштабирования sklearns, однако я знаю, что нормализовала набор данных. - person pythonthrowaway; 30.03.2020
comment
но, возможно, мне нужно заранее выполнить некоторую предварительную обработку, чтобы масштабировать все переменные от 1 до -1, если я хочу использовать функцию tanh - person pythonthrowaway; 30.03.2020