I want to build a DC-GAN algorithm from scratch in Tensorflow 2.4.0. I am using my own dataset, which I can load into my DC-GAN model. Now I want to train my model and the training is working but the output is not right. I was working with the official tensorflow tutorial for DCGANs (https://www.tensorflow.org/tutorials/generative/dcgan) . In my training set are images of a robot but the generator generates grey Images. I have trained my model for over 500 epochs, but the grey images are getting white. I dont understand why the generator does not generate manipulated images of the robot, the content of the training data is fine and the algorithm is based from the tensorflow tutorial.
My Code is here:
import tensorflow as tf
from tensorflow.keras import layers
from dataHandler.dataLoader.loadData1 import load_dataset #function to load dataset
from dataHandler.preProcessData.configuratorPath import * #path of the files
BUFFER_SIZE = 60000
BATCH_SIZE = 256
train_dataset=load_dataset(tfRecordPath,classesPath,size=64)
train_dataset=train_dataset.shuffle(BUFFER_SIZE)
train_dataset=train_dataset.batch(BATCH_SIZE)
EPOCHS = 50
noise_dim = 100
num_examples_to_generate = 16
seed = tf.random.normal([num_examples_to_generate, noise_dim])
def make_generator_model():
# In Keras, you assemble layers to build models. A model is (usually) a graph of layers. The most common type of model is a stack of layers
model = tf.keras.Sequential()
"""
Add a densely-connected layer to the model
the model will take as input arrays of shape (*, 100).
And and output arrays of shape (*, 7*7*256)
after the first layer, you don't need to specify the size of the input anymore
Afterwards, we do automatic shape inference
"""
model.add(layers.Dense(4 * 4 * 1024, use_bias=False, input_shape=(100,)))
"""
You can think about batch normalization as doing preprocessing at every layer of the network.
Accelerating Deep Network Training by Reducing Internal Covariate Shift
"""
model.add(layers.BatchNormalization())
"""
ReLU is linear (identity) for all positive values, and zero for all negative values.
Leaky ReLU has a small slope for negative values, instead of altogether zero. For example, leaky ReLU may have y = 0.01x when x < 0
"""
model.add(layers.LeakyReLU())
# reshape the output from something flattened to something with a shape of (7,7,256)
model.add(layers.Reshape((4, 4, 1024)))
assert model.output_shape == (None, 4, 4, 1024) # Note: None is the batch size
"""
The generator uses a transposed convolutional layer (Upsampling) layers to produce an image from seed (random noise).
128 is the dimensionality of the output space
(5,5) specifies the height and width of the 2D convolution window
strides = (1,1) specifies the strides of the convolution along the height and width
"""
model.add(layers.Conv2DTranspose(512, (5, 5), strides=(2, 2), padding="same", use_bias=False))
assert model.output_shape == (None, 8, 8, 512)
model.add(layers.BatchNormalization())
model.add(layers.LeakyReLU())
# Another transposed convolutional layer (upsampling)
model.add(layers.Conv2DTranspose(256, (5, 5), strides=(2, 2), padding="same", use_bias=False))
assert model.output_shape == (None, 16, 16, 256)
model.add(layers.BatchNormalization())
model.add(layers.LeakyReLU())
# Another transposed convolutional layer (upsampling)
model.add(layers.Conv2DTranspose(128, (5, 5), strides=(2, 2), padding="same", use_bias=False))
assert model.output_shape == (None, 32, 32, 128)
model.add(layers.BatchNormalization())
model.add(layers.LeakyReLU())
# Final output layer also a convolutional layer (upsampling), sigmoid goes from 0 to 1
model.add(layers.Conv2DTranspose(3, (5, 5), strides=(2, 2), padding="same", use_bias=False, activation="sigmoid"))
# assert model.output_shape == (None, 64, 64, 3)
assert model.output_shape == (None, 64, 64, 3)
return model
noise = tf.random.normal([1, 100])
generator = make_generator_model()
def make_discriminator_model():
model = tf.keras.Sequential()
#model.add(layers.Conv2D(64, (5, 5), strides=(2, 2), padding='same',
#input_shape=[64, 64, 3]))
model.add(layers.Conv2D(64, (5, 5), strides=(2, 2), padding='same',
input_shape=[64, 64, 3]))
model.add(layers.LeakyReLU())
model.add(layers.Dropout(
0.3)) # Dropout consists in randomly setting a fraction rate of input units to 0 at each update during training time, which helps prevent overfitting.
model.add(layers.Conv2D(128, (5, 5), strides=(2, 2), padding='same'))
model.add(layers.LeakyReLU())
model.add(layers.Dropout(0.3))
"""
Flattens the input. Does not affect the batch size.
If inputs are shaped (batch,) without a channel dimension, then flattening adds an extra channel dimension and output shapes are (batch, 1).
"""
model.add(layers.Flatten())
model.add(layers.Dense(1))
return model
cross_entropy = tf.keras.losses.BinaryCrossentropy(from_logits=True)
def discriminator_loss(real_output, fake_output):
real_loss = cross_entropy(tf.ones_like(real_output), real_output)
fake_loss = cross_entropy(tf.zeros_like(fake_output), fake_output)
total_loss = real_loss + fake_loss
return total_loss
def generator_loss(fake_output):
return cross_entropy(tf.ones_like(fake_output), fake_output)
generator_optimizer = tf.keras.optimizers.Adam(1e-4)
discriminator_optimizer = tf.keras.optimizers.Adam(1e-4)
discriminator=make_discriminator_model()
# Notice the use of `tf.function`
# This annotation causes the function to be "compiled".
@tf.function
def train_step(images):
noise = tf.random.normal([BATCH_SIZE, noise_dim])
with tf.GradientTape() as gen_tape, tf.GradientTape() as disc_tape:
generated_images = generator(noise, training=True)
real_output = discriminator(images, training=True)
fake_output = discriminator(generated_images, training=True)
gen_loss = generator_loss(fake_output)
disc_loss = discriminator_loss(real_output, fake_output)
gradients_of_generator = gen_tape.gradient(gen_loss, generator.trainable_variables)
gradients_of_discriminator = disc_tape.gradient(disc_loss, discriminator.trainable_variables)
generator_optimizer.apply_gradients(zip(gradients_of_generator, generator.trainable_variables))
discriminator_optimizer.apply_gradients(zip(gradients_of_discriminator, discriminator.trainable_variables))
def train(dataset, epochs):
for epoch in range(1, epochs):
for image_batch in dataset:
train_step(image_batch)
train(train_dataset, EPOCHS)
question from:
https://stackoverflow.com/questions/65917142/dc-gan-generates-wrong-images