最新消息:Welcome to the puzzle paradise for programmers! Here, a well-designed puzzle awaits you. From code logic puzzles to algorithmic challenges, each level is closely centered on the programmer's expertise and skills. Whether you're a novice programmer or an experienced tech guru, you'll find your own challenges on this site. In the process of solving puzzles, you can not only exercise your thinking skills, but also deepen your understanding and application of programming knowledge. Come to start this puzzle journey full of wisdom and challenges, with many programmers to compete with each other and show your programming wisdom! Translated with DeepL.com (free version)

python - Problems with setting gradients of GAN in keras - Stack Overflow

matteradmin5PV0评论

Having some experience in developing neural networks in Keras, I decided to write a non-standard GAN, which you can't really call as such. The point is that the discriminator is a ready-made neural network that perfectly predicts the quality of a face image, and I wanted my network to increase the resolution of 48 by 48 images by 4 times (made them 96 by 96). My regular GAN with a trainable discriminator simply interpolated the image to a larger space with a loss of quality, as if you simply enlarged the image on a computer. It is not so important for me that the image is a complete copy, so the idea with a ready-made discriminator seemed good to me.

Here is the code of train step function:

@tf.function
def train_step(images_x, images_y):

  with tf.GradientTape() as gen_tape:
    generated_images = generator(images_x, training=True).numpy()

    #Integrating ready-made network, which returns numpy array with shape (batch_size, 1) and contains scalars representing the number in range of 0-1
    fake_output = K.constant(face_detector.estimate(generated_images)) #K = tensorflow backend

    gen_loss = generator_loss(fake_output)

  gradients_of_generator = gen_tape.gradient(gen_loss, generator.trainable_variables)

  generator_optimizer.apply_gradients(zip(gradients_of_generator, generator.trainable_variables))

  return gen_loss

common train function:

def train(dataset_x, dataset_y, epochs):
  history = []
  MAX_PRINT_LABEL = 10
  th = BUFFER_SIZE // (BATCH_SIZE * MAX_PRINT_LABEL)

  for epoch in range(1, epochs + 1):
    print(f'{epoch}/{EPOCHS}: ', end='')

    start = time.time()
    n = 0

    gen_loss_epoch = 0
    l = len(dataset_x)
    for o in range(l):
      tf.config.run_functions_eagerly(True) #I'm suspecting the issue is related to this, but i can't do it without running eagerly (train_step doesn't work)
      gen_loss = train_step(dataset_x[o], dataset_y[o]) 
      tf.config.run_functions_eagerly(False)
      print(gen_loss, disc_loss)
      gen_loss_epoch += K.mean(gen_loss)
      if (n % th == 0): print('=', end='')
      n += 1
    generator.save("generator.h5")


    history += [gen_loss_epoch / n]
    

  return history

generator structure and other

cross_entropy = tf.keras.losses.BinaryCrossentropy(from_logits=True)

hidden_dim = 2


def dropout_and_batch():
  return Dropout(0.3)(BatchNormalization())

img_height = 96
img_width = 96
img_channels = 3  
latent_dim = 2  
input_img = Input(shape=(48, 48, 3))
x = Conv2D(32, 3, padding='same', activation='relu')(input_img)
x = Conv2D(32, 3, padding='same', activation='relu')(x)
x = Conv2D(32, 3, padding='same', activation='relu')(x)

x = Flatten()(input_img)
z_mean = Dense(latent_dim)(x)
z_log_var = Dense(latent_dim)(x)
@keras.saving.register_keras_serializable()
def sampling(args):
    z_mean, z_log_var = args
    epsilon = tf.random.normal([batch_size, latent_dim], 0, 1, tf.float32)
    return z_mean + tf.exp(0.5 * z_log_var) * epsilon 
z = Lambda(sampling, output_shape=(latent_dim,))([z_mean, 
 z_log_var])


decoder_input = Input(shape=(latent_dim,))
x = Dense(img_width*img_height*3, activation='relu')(decoder_input)
x = Reshape((img_width, img_height, 3))(x)
x = Conv2D(32, 3, padding='same', activation='relu')(x)
x = Conv2D(32, 3, padding='same', activation='relu')(x)
decoded = Conv2D(3, 3, padding='same', activation='sigmoid')(x)

encoder = Model(input_img, [z_mean, z_log_var, z])
decoder = Model(decoder_input, decoded)

generator = Model(input_img, decoder(encoder(input_img)[2]))

custom loss function:

def generator_loss(fake_output):
  loss = cross_entropy(tf.ones_like(fake_output), fake_output)
  return loss

loading dataset:

for path in glob("faces/*.jpg"):
  img = Image.open(path)
  y_train.append(np.asarray(img.resize((96, 96))))
  if y_train[-1].shape != (96, 96, 3):
    del y_train[-1]
    continue
  x_train.append(np.asarray(img.resize((48, 48))))
x_train = np.asarray(x_train)/255
y_train = np.asarray(y_train)/255

BUFFER_SIZE = x_train.shape[0]
BATCH_SIZE = 100

BUFFER_SIZE = BUFFER_SIZE // BATCH_SIZE * BATCH_SIZE
x_train = x_train[:BUFFER_SIZE]
y_train = y_train[:BUFFER_SIZE]
print(x_train.shape, y_train.shape)


train_dataset_x = list(tf.data.Dataset.from_tensor_slices(x_train).shuffle(BUFFER_SIZE).batch(BATCH_SIZE))
train_dataset_y = list(tf.data.Dataset.from_tensor_slices(y_train).shuffle(BUFFER_SIZE).batch(BATCH_SIZE))

I have had this error that I still can't solve on my own and with Gemini for a long time now: ValueError: No gradients provided for any variable (it points to a line generator_optimizer.apply_gradients(zip(gradients_of_generator, generator.trainable_variables)))

Post a comment

comment list (0)

  1. No comments so far