#python #generative-adversarial-network
Вопрос:
Когда я запускаю приведенный ниже код, я получаю все те же изображения:
Я запустил GAN еще пару раз, и все они выдают одно и то же изображение, показанное выше. Я не знаю, связано ли это как-то с шумом или с тем, как я сохраняю изображения, но я не могу этого понять. Конечный продукт выглядит хорошо, но я просто хочу, чтобы при каждом запуске GAN была вариация, а не просто одна и та же картинка.
Я не уверен, почему это происходит, и буду признателен за любую помощь.
random_dim = 100 PREVIEW_ROWS = 3 PREVIEW_COLS = 3 PREVIEW_MARGIN = 4 IMAGE_SIZE = 128 WIDTH = 128 HEIGHT = 128 CHANNELS = 3 def save_images(cnt, noise, generator): image_array = np.full((PREVIEW_MARGIN (PREVIEW_ROWS * (IMAGE_SIZE PREVIEW_MARGIN)), PREVIEW_MARGIN (PREVIEW_COLS * (IMAGE_SIZE PREVIEW_MARGIN)), 3), 255, dtype=np.uint8) generated_images = generator.predict(noise) generated_images = 0.5 * generated_images 0.5 image_count = 0 for row in range(PREVIEW_ROWS): for col in range(PREVIEW_COLS): r = row * (IMAGE_SIZE PREVIEW_MARGIN) PREVIEW_MARGIN c = col * (IMAGE_SIZE PREVIEW_MARGIN) PREVIEW_MARGIN image_array[r:r IMAGE_SIZE, c:c IMAGE_SIZE] = generated_images[image_count] * 255 image_count = 1 output_path = 'output' if not os.path.exists(output_path): os.makedirs(output_path) filename = os.path.join(output_path, f"trained-{cnt}.png") im = Image.fromarray(image_array) im.save(filename) def get_optimizer(): return Adam(lr=0.0002, beta_1=0.5) def get_generator(): gen_input = Input(shape=random_dim) generator = Sequential() generator.add(Dense(128 * 16 * 16, input_dim=random_dim)) generator.add(LeakyReLU()) generator.add(Reshape((16, 16, 128))) generator.add(Conv2D(256, 5, padding='same')) generator.add(LeakyReLU()) generator.add(Conv2DTranspose(256, 4, strides=2, padding='same')) generator.add(LeakyReLU()) generator.add(Conv2DTranspose(256, 4, strides=2, padding='same')) generator.add(LeakyReLU()) generator.add(Conv2DTranspose(256, 4, strides=2, padding="same")) generator.add(LeakyReLU()) generator.add(Conv2D(512, 5, padding='same')) generator.add(LeakyReLU()) generator.add(Conv2D(512, 5, padding='same')) generator.add(LeakyReLU()) generator.add(Conv2D(3, 7, activation='tanh', padding="same")) input = Input(shape=(random_dim,)) generated_image = generator(input) generator.summary() return Model(input, generated_image) def get_discriminator(): disc_input = Input(shape=(128, 128, 3)) discriminator = Sequential() discriminator.add(Conv2D(256, 3, input_shape=(128, 128, 3))) discriminator.add(LeakyReLU()) discriminator.add(Conv2D(256, 4, strides=2)) discriminator.add(LeakyReLU()) discriminator.add(Conv2D(256, 4, strides=2)) discriminator.add(LeakyReLU()) discriminator.add(Conv2D(256, 4, strides=2)) discriminator.add(LeakyReLU()) discriminator.add(Conv2D(256, 4, strides=2)) discriminator.add(LeakyReLU()) discriminator.add(Flatten()) discriminator.add(Dropout(0.4)) discriminator.add(Dense(1, activation='sigmoid')) discriminator = Model(disc_input, discriminator(disc_input)) optimizer = RMSprop( lr = .0001, clipvalue = 1.0, decay = 1e-8 ) discriminator.compile(loss='binary_crossentropy', optimizer=optimizer) discriminator.summary() return discriminator def get_gan_network(discriminator, random_dim, generator, optimizer): # We initially set trainable to False since we only want to train either the # generator or discriminator at a time discriminator.trainable = False # gan input (noise) will be 100-dimensional vectors gan_input = Input(shape=(random_dim,)) # the output of the generator (an image) x = generator(gan_input) # get the output of the discriminator (probability if the image is real or not) gan_output = discriminator(x) gan = Model(inputs=gan_input, outputs=gan_output) gan.compile(loss='binary_crossentropy', optimizer=optimizer) return gan X_train = training_data fixed_noise = np.random.normal(0, 1, (PREVIEW_ROWS * PREVIEW_COLS, 100)) def train(epochs=1, batchSize=128): batchCount = X_train.shape[0] / batchSize print(X_train.shape[0]) print('Epochs:', epochs) print('Batch size:', batchSize) print('Batches per epoch:', batchCount) adam = get_optimizer() generator = get_generator() discriminator = get_discriminator() discriminator.trainable = False gan = get_gan_network(discriminator, random_dim, generator, adam) y_real = np.ones((batchSize, 1)) y_fake = np.zeros((batchSize, 1)) d_losses = [] a_losses = [] real_scores = [] fake_scores = [] start = 0 for step in tdqm(range(1000)): start_time = time.time() latent_vectors = np.random.randn(batchSize, random_dim) generated = generator.predict(latent_vectors) real = training_data[start:start batchSize] combined_images = np.concatenate([generated, real]) labels = np.concatenate([np.ones((batchSize, 1)), np.zeros((batchSize, 1))]) labels = .05 * np.random.random(labels.shape) d_loss = discriminator.train_on_batch(combined_images, labels) d_losses.append(d_loss) latent_vectors = np.random.randn(batchSize, random_dim) misleading_targets = np.zeros((batchSize, 1)) a_loss = gan.train_on_batch(latent_vectors, misleading_targets) a_losses.append(a_loss) #if step == 1 or step % 20 == 0: if step % 50 == 49: save_images(step, fixed_noise, generator) if __name__ == '__main__': train(1000, 16)