ГАН сходится всего за несколько эпох
Я реализовал родовую состязательную сеть в Керасе. Размер моих тренировочных данных составляет около 16 000, где каждое изображение имеет размер 32*32. Все мои тренировочные изображения являются версиями изображений с измененным размером из набора данных imagenet в отношении задачи обнаружения объекта. Я подавал матрицу изображений прямо в сеть, не делая центральную обрезку. Я использовал AdamOptimizer с частотой обучения 1e-4 и бета1, равной 0,5, и я также установил коэффициент отсева на 0,1. Сначала я обучил дискриминатор на 3000 реальных изображениях и 3000 поддельных изображениях, и он достиг точности 93%. Затем я подготовился к 500 эпохам с размером пакета 32. Однако моя модель, казалось, сходилась всего за несколько эпох (<10), и изображения, которые она генерировала, были безобразными.
Случайные образцы, сгенерированные генератором
Мне было интересно, является ли мой тренировочный набор данных слишком маленьким (по сравнению с данными в документе DCGAN, которых более 300 000) или конфигурация моей модели неверна. Более того, я должен тренировать SGD на D для k итераций (где k мало, возможно, 1), а затем тренироваться с SGD на G для одной итерации, как это было предложено Яном Гудфеллоу в первоначальной статье?(Я только что попытался обучить их один за раз)
Ниже приведена конфигурация генератора.
g_input = Input(shape=[100])
H = Dense(1024*4*4, init='glorot_normal')(g_input)
H = BatchNormalization(mode=2)(H)
H = Activation('relu')(H)
H = Reshape( [4, 4,1024] )(H)
H = UpSampling2D(size=( 2, 2))(H)
H = Convolution2D(512, 3, 3, border_mode='same', init='glorot_uniform')(H)
H = BatchNormalization(mode=2)(H)
H = Activation('relu')(H)
H = UpSampling2D(size=( 2, 2))(H)
H = Convolution2D(256, 3, 3, border_mode='same', init='glorot_uniform')(H)
H = BatchNormalization(mode=2)(H)
H = Activation('relu')(H)
H = UpSampling2D(size=( 2, 2))(H)
H = Convolution2D(3, 3, 3, border_mode='same', init='glorot_uniform')(H)
g_V = Activation('tanh')(H)
generator = Model(g_input,g_V)
generator.compile(loss='binary_crossentropy', optimizer=opt)
generator.summary()
Ниже приведена конфигурация дискриминатора:
d_input = Input(shape=shp)
H = Convolution2D(64, 5, 5, subsample=(2, 2), border_mode = 'same', init='glorot_normal')(d_input)
H = LeakyReLU(0.2)(H)
#H = Dropout(dropout_rate)(H)
H = Convolution2D(128, 5, 5, subsample=(2, 2), border_mode = 'same', init='glorot_normal')(H)
H = BatchNormalization(mode=2)(H)
H = LeakyReLU(0.2)(H)
#H = Dropout(dropout_rate)(H)
H = Flatten()(H)
H = Dense(256, init='glorot_normal')(H)
H = LeakyReLU(0.2)(H)
d_V = Dense(2,activation='softmax')(H)
discriminator = Model(d_input,d_V)
discriminator.compile(loss='categorical_crossentropy', optimizer=dopt)
discriminator.summary()
Ниже приведена конфигурация GAN в целом:
gan_input = Input(shape=[100])
H = generator(gan_input)
gan_V = discriminator(H)
GAN = Model(gan_input, gan_V)
GAN.compile(loss='categorical_crossentropy', optimizer=opt)
GAN.summary()
2 ответа
я думаю проблема с
loss
функция Попробуйте
loss='categorical_crossentropy',
Я подозреваю, что ваш генератор можно тренировать, пока вы тренируете ган. Вы можете проверить, используя generator.layers[-1].get_weights()
чтобы увидеть, изменились ли параметры в процессе обучения Ган.
Вы должны заморозить дискриминатор, прежде чем собирать его в gan:
generator.trainnable = False
gan_input = Input(shape=[100])
H = generator(gan_input)
gan_V = discriminator(H)
GAN = Model(gan_input, gan_V)
GAN.compile(loss='categorical_crossentropy', optimizer=opt)
GAN.summary()
см. это обсуждение: https://github.com/fchollet/keras/issues/4674