Почему моя GAN предоставляет один и тот же вывод каждый раз, когда я ее запускаю, и почему их разнообразие отсутствует?

#python #generative-adversarial-network

Вопрос:

Когда я запускаю приведенный ниже код, я получаю все те же изображения: выход gan

Я запустил 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)