admin管理员组文章数量:1026373
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)))
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)))
本文标签: pythonProblems with setting gradients of GAN in kerasStack Overflow
版权声明:本文标题:python - Problems with setting gradients of GAN in keras - Stack Overflow 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://it.en369.cn/questions/1745642585a2160836.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论