DCGAN: дискриминатор становится слишком сильным слишком быстро, чтобы генератор мог учиться

Я пытаюсь использовать эту версию кода DCGAN (реализованную в Tensorflow) с некоторыми из моих данных. Я сталкиваюсь с проблемой того, что дискриминатор слишком быстро становится слишком сильным, чтобы генератор мог чему-то научиться.

Теперь есть несколько приемов, обычно рекомендуемых для решения этой проблемы с GAN:

  • пакетная нормализация (уже есть в коде DCGAN)

  • дать старт генератор.

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

Добавление большего числа итераций генератора в этом случае помогает только замедляя неизбежное - дискриминатор становится слишком сильным и подавляет обучение генератора.

Следовательно, я хотел бы попросить совета о том, есть ли другой способ, который мог бы помочь проблеме слишком сильного дискриминатора?

3 ответа

Решение

Подводя итог этой теме - общий совет будет:

  • попробуйте поиграть с параметрами модели (например, с темпами обучения)
  • попробуйте добавить больше разнообразия к входным данным
  • Попробуйте настроить архитектуру сетей генератора и дискриминатора.

Однако в моем случае проблема заключалась в масштабировании данных: я изменил формат входных данных с исходного.jpg на.npy и потерял масштабирование по пути. Обратите внимание, что этот код потока DCGAN изменяет масштаб входных данных до диапазона [-1,1], и модель настроена для работы с этим диапазоном.

Я думаю, что есть несколько способов уменьшить дискриминатор:

  1. Попробуйте leaky_relu и dropout в функции дискриминатора:

    def leaky_relu(x, alpha, name="leaky_relu"): return tf.maximum(x, alpha * x , name=name)

Вот полное определение:

def discriminator(images, reuse=False):

# Implement a seperate leaky_relu function
def leaky_relu(x, alpha, name="leaky_relu"):
    return tf.maximum(x, alpha * x , name=name)

# Leaky parameter Alpha 
alpha = 0.2

# Add batch normalization, kernel initializer, the LeakyRelu activation function, ect. to the layers accordingly
with tf.variable_scope('discriminator', reuse=reuse):
    # 1st conv with Xavier weight initialization to break symmetry, and in turn, help converge faster and prevent local minima.
    images = tf.layers.conv2d(images, 64, 5, strides=2, padding="same", kernel_initializer=tf.contrib.layers.xavier_initializer())
    # batch normalization
    bn = tf.layers.batch_normalization(images, training=True)
    # Leaky relu activation function
    relu = leaky_relu(bn, alpha, name="leaky_relu")
    # Dropout "rate=0.1" would drop out 10% of input units, oppsite with keep_prob
    drop = tf.layers.dropout(relu, rate=0.2)

    # 2nd conv with Xavier weight initialization, 128 filters.
    images = tf.layers.conv2d(drop, 128, 5, strides=2, padding="same", kernel_initializer=tf.contrib.layers.xavier_initializer())
    bn = tf.layers.batch_normalization(images, training=True)
    relu = leaky_relu(bn, alpha, name="leaky_relu")
    drop = tf.layers.dropout(relu, rate=0.2)

    # 3rd conv with Xavier weight initialization, 256 filters, strides=1 without reshape
    images = tf.layers.conv2d(drop, 256, 5, strides=1, padding="same", kernel_initializer=tf.contrib.layers.xavier_initializer())
    #print(images)
    bn = tf.layers.batch_normalization(images, training=True)
    relu = leaky_relu(bn, alpha, name="leaky_relu")
    drop = tf.layers.dropout(relu, rate=0.2)


    flatten = tf.reshape(drop, (-1, 7 * 7 * 128))
    logits = tf.layers.dense(flatten, 1)
    ouput = tf.sigmoid(logits)  

    return ouput, logits
  1. Добавьте сглаживание меток в потерю дискриминатора, чтобы предотвратить его усиление. Увеличьте значение сглаживания в соответствии с производительностью d_loss.

    d_loss_real = tf.reduce_mean( tf.nn.sigmoid_cross_entropy_with_logits(logits=d_logits_real, labels=tf.ones_like(d_model_real)*(1.0 - smooth)))

Когда я попробовал реализовать их для генерации данных mnist, в конце я получил очень большие потери. Но, глядя на выходные данные, они все равно выглядели как числа (если вы немного щурились). В зависимости от вашей проблемной области, иногда выходной сигнал генератора "достаточно хорош", несмотря на то, что он не прошел тест дискриминатора.

Другие вопросы по тегам