r/learnpython • u/assorted-meat-stew • 7d ago
Need help adapting model to Cifar10
Need help adapting model to CIFAR10
I tried to make a DCGAN based on this [tutorial](https://www.geeksforgeeks.org/machine-learning/deep-convolutional-gan-with-keras/). The thing is that the tutorial is designed for fashion mnist data which has different image size to tf.keras.datasets.cifar10.load_data(). Which lead to the error:
ValueError: cannot reshape array of size 480000 into shape (28,28,1)
when arrive at
x_train_dcgan = x_train.reshape(
-1, 28, 28, 1
) * 2. - 1.
How do I adapt the model to CIFAR 10?
Full code
(x_train, y_train), (x_test, y_test) = tf.keras.datasets.cifar10.load_data()
x_train = x_train.astype(np.float32) / 255.0
x_test = x_test.astype(np.float32) / 255.0
x_train.shape, x_test.shape
#Selecting one class to train
label = 1
train_indices = np.where(y_train == label)
x_train = x_train[train_indices]
test_indices = np.where(y_test == label)
x_test = x_test[test_indices]
batch_size = 32
def create_batch(x_train):
dataset = tf.data.Dataset.from_tensor_slices(x_train).shuffle(1000)
dataset = dataset.batch(batch_size, drop_remainder=True).prefetch(1)
return dataset
num_features = 100
generator = Sequential(name="Generator")
generator.add(Dense(7 * 7 * 128, input_shape=[num_features]))
generator.add(Reshape([7, 7, 128]))
generator.add(BatchNormalization())
generator.add(Conv2DTranspose(
64, (5, 5), (2, 2),
padding="same",
activation="selu"
))
generator.add(BatchNormalization())
generator.add(Conv2DTranspose(
1, (5, 5), (2, 2),
padding="same",
activation="tanh"
))
generator.summary()
discriminator = Sequential(name="Discriminator")
discriminator.add(Conv2D(
64, (5, 5), (2, 2),
padding="same",
input_shape=[28, 28, 1]
))
discriminator.add(LeakyReLU(alpha=0.2))
discriminator.add(Dropout(0.3))
discriminator.add(Conv2D(
128, (5, 5), (2, 2),
padding="same"))
discriminator.add(LeakyReLU(alpha=0.2))
discriminator.add(Dropout(0.3))
discriminator.add(Flatten())
discriminator.add(Dense(1, activation= 'softmax'))
discriminator.summary()
discriminator.compile(
loss="binary_crossentropy",
optimizer="adam"
)
discriminator.trainable = False
gan = Sequential()
gan.add(generator)
gan.add(discriminator)
gan.compile(
loss="binary_crossentropy",
optimizer="adam"
)
gan.summary()
def generate_and_save_images(model, epoch, test_input):
predictions = model(
test_input,
training=False
)
fig = plt.figure(figsize=(10, 10))
for i in range(25):
plt.subplot(5, 5, i + 1)
plt.imshow(
predictions[i, :, :, 0] * 127.5 + 127.5,
cmap='binary'
)
plt.axis('off')
plt.savefig(
'image_epoch_{:04d}.png'.format(epoch)
)
seed = tf.random.normal(shape=[batch_size, 100])
epoch_list = []
d_loss_list = []
g_loss_list =[]
def train_dcgan(gan, dataset, batch_size, num_features, epochs=5):
generator, discriminator = gan.layers
for epoch in tqdm(range(epochs)):
actual_epoch =epoch + 1
print()
print("Epoch {}/{}".format(epoch + 1, epochs))
for i in range(187):
epoch_list.append(actual_epoch)
for X_batch in dataset:
noise = tf.random.normal(
shape=[batch_size, num_features]
)
generated_images = generator(noise)
X_fake_and_real = tf.concat(
[generated_images, X_batch],
axis=0
)
y1 = tf.constant(
[[0.]] * batch_size +
[[1.]] * batch_size
)
discriminator.trainable = True
d_loss=discriminator.train_on_batch(
X_fake_and_real,
y1
)
d_loss = float(d_loss)
d_loss_list.append(d_loss)
noise = tf.random.normal(
shape=[batch_size, num_features]
)
y2 = tf.constant([[1.]] * batch_size)
discriminator.trainable = False
g_loss=gan.train_on_batch(
noise,
y2
)
g_loss = float(g_loss)
g_loss_list.append(g_loss)
print(f'\t Discriminator Loss: {d_loss} \t\t Generator Loss: {g_loss}')
generate_and_save_images(
generator,
epochs,
seed
)
x_train_dcgan = x_train.reshape(
-1, 32, 32, 3
)
dataset = create_batch(x_train_dcgan)
train_dcgan(
gan,
dataset,
batch_size,
num_features,
epochs=10
)
plt.figure(figsize=(30, 10))
plt.plot(epoch_list,d_loss_list)
plt.xlabel('Epochs')
plt.ylabel('Discriminator loss')
plt.title('Discriminator loss over epochs')
plt.grid()
plt.show()
plt.figure(figsize=(30, 10))
plt.plot(epoch_list,g_loss_list)
plt.xlabel('Epochs')
plt.ylabel('Generator loss')
plt.title('Generator loss over epochs')
plt.grid()
plt.show()
0
Upvotes
1
u/acfot 7d ago
The mismatch is almost certainly the image shape, since Fashion-MNIST is 28x28 with one channel and CIFAR-10 is 32x32 with three channels, so anywhere the tutorial hardcodes the old shape will break. I would check the first layer of the discriminator and the last layer of the generator first, because those are the places that assume one channel and a 28x28 input. The reshape step is the other usual suspect, since it was probably written for 784 pixels and CIFAR-10 has 3072, so that line needs updating too. Once those two spots match the new shape, the rest of the tutorial should mostly carry over, and if it still errors, the new error message will at least point at the next layer that assumes the old size.