DCGAN производит шум, но не имеет ожидаемой структуры, может ли кто-нибудь помочь мне получить надлежащие результаты от DCGAN?

#python #deep-learning #generative-adversarial-network

Вопрос:

Может ли кто-нибудь помочь мне получить правильные результаты/изображения с моего DCGAN ?

Я получаю разные цветные (шумовые) изображения от одной итерации к другой, но нигде не приближаюсь к тому, что я должен получить. Я кормлю человеческие лица/Кошек/Собак этикетками, чтобы обучить мой генератор и дискриминатор, и я должен получить результат, который выглядит
либо как Кошка, либо Собака, либо как человеческое лицо.

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

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

 def generator(latent_dim, n_classes):
    
    initializer = tf.random_normal_initializer(0., 0.021)
    in_label = Input(shape=(1,))
    li = Embedding(n_classes, 25)(in_label)
    n_nodes = 64 * 64
    
    li = Dense(n_nodes)(li)
    
    li = Reshape((64, 64, 1))(li)
    
    
    in_lat = Input(shape=(latent_dim,))
    n_nodes = 128 * 64 * 64
    
    gen = Dense(n_nodes)(in_lat)
    
    gen = LeakyReLU(alpha=0.2)(gen)
    gen = BatchNormalization(axis=-1)(gen)
    gen = Reshape((64, 64, 128))(gen)

    merge = Concatenate()([gen, li])
    gen = Conv2DTranspose(128, (4,4), strides=(2,2), padding='same',kernel_initializer=initializer,use_bias=False)(merge)
    gen = LeakyReLU(alpha=0.2)(gen)
    gen = BatchNormalization(axis=-1)(gen)
    

    gen = Conv2DTranspose(128, (4,4), strides=(2,2), padding='same',kernel_initializer=initializer,use_bias=False)(gen)
    gen = LeakyReLU(alpha=0.2)(gen)
    gen = BatchNormalization(axis=-1)(gen)

    
    out_layer = Conv2D(3, (7,7), activation='tanh', padding='same',kernel_initializer=initializer,use_bias=False)(gen)
    model = Model([in_lat, in_label], out_layer, name="generator")
    
    opt = Adam(lr=0.0002, beta_1=0.5)
    model.compile(optimizer=opt,loss='binary_crossentropy', metrics='accuracy')
    
    return model



def define_discriminator(n_classes,in_shape=(256,256,3)):
    
    initializer = tf.random_normal_initializer(0., 0.021)
    in_label = Input(shape=(1,))
    li = Embedding(n_classes, 25)(in_label)     
    n_nodes = in_shape[0] * in_shape[1]
    
    li = Dense(n_nodes)(li)

    li = Reshape((in_shape[0], in_shape[1],1))(li)
    
    in_image = Input(shape=in_shape)
    merge = Concatenate()([in_image, li])
    
    fe = Conv2D(128, (3,3), strides=(2,2), padding='same',kernel_initializer=initializer,use_bias=False)(merge)
    fe = LeakyReLU(alpha=0.2)(fe)
    fe = BatchNormalization(axis=-1)(fe)

    fe = Conv2D(128, (3,3), strides=(2,2), padding='same',kernel_initializer=initializer,use_bias=False)(fe)
    fe = LeakyReLU(alpha=0.2)(fe)
    fe = BatchNormalization(axis=-1)(fe)
    
    
    fe = Flatten()(fe)
    fe = Dropout(0.4)(fe)

    out_layer = Dense(1, activation='sigmoid')(fe)
    model = Model([in_image, in_label], out_layer, name="discriminator")

    opt = Adam(lr=0.0002, beta_1=0.5)
    model.compile(optimizer=opt, loss='binary_crossentropy', metrics=['accuracy'])
    
    return model



def define_gan(g_model, d_model):
    
    g_model.trainable = True
    d_model.trainable = False
    
    gen_noise, gen_label = g_model.input
    gen_output = g_model.output
    
    gan_output = d_model([gen_output, gen_label])
    model = Model([gen_noise, gen_label], gan_output, name="gan")
    opt = Adam(lr=0.0002, beta_1=0.5)
    model.compile(optimizer=opt,  loss='binary_crossentropy', metrics='accuracy')
    return model
 

Ниже приведены результаты/изображения для различных итераций. 16 квадратов-это 16
различных скрытых векторов.

Результаты эпохи 700

Результаты эпохи 701

Результаты эпохи 704

Результаты эпохи 708

Комментарии:

1. Попробуйте удалить точность из компиляции. Это пример DCGAN для кераса, использующего грани, keras.io/examples/generative/dcgan_overriding_train_step .

2. Спасибо, что ответили… Я постараюсь, как вы сказали.

Ответ №1:

Не видя никакого кода, трудно строить догадки, но вы можете проверить это репо для справки.

Обратите внимание на это примечание:

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

  1. Используйте графический процессор. Если у вас его нет, используйте Colab, как было предложено выше. Находясь в Colab, вы можете выбрать «Изменить тип среды выполнения» в пункте «Среда выполнения» в строке меню и выбрать «GPU» в качестве аппаратного ускорителя. Этот аппаратный ускоритель обучает GAN на порядки быстрее, чем опции «Нет» или «TPU», и дискриминатор (мы понятия не имеем, почему!) будет обучаться должным образом.
  2. Измените оптимизатор дискриминатора. Как отмечается в комментарии на этапе компиляции дискриминатора в этой записной книжке, переключение с оптимизатора RMSProp по умолчанию на другой (например, Adam или AdaDelta) позволяет дискриминатору эффективно учиться, и поэтому GAN генерирует эскизы. Независимо от того, используете ли вы только процессор, графический процессор или ТПУ, это решение эффективно. (Тем не менее, обучение GAN с помощью графического процессора по-прежнему намного быстрее, чем только с процессором или TPU.)

Вы также можете ознакомиться с этим обсуждением: https://github.com/the-deep-learners/deep-learning-illustrated/issues/2

Комментарии:

1. Привет, тромги, спасибо, что ответил… проблема не в дискриминаторе, а в генераторе. Дискриминатор идеально классифицирует поддельные и реальные изображения, и я уже использую оптимизатор adam, как вы видите в моем коде. В любом случае, как вы предложили, я попробую использовать другой оптимизатор для дискриминатора, возможно, SGD, не для повышения его производительности, а для того, чтобы дать генератору немного места для обучения. Спасибо.