Construire un DCGAN sur Fashion MNIST
Un DCGAN (Deep Convolutional Generative Adversarial Network) est une variante des GAN qui utilise des réseaux de neurones convolutionnels pour générer des images. Dans cet exemple, nous allons construire un DCGAN qui génère des images à partir du jeu de données Fashion MNIST.
Étapes pour construire un DCGAN
- Préparer les données
- Définir le modèle du générateur
- Définir le modèle du discriminateur
- Construire le modèle DCGAN
- Entraîner le DCGAN
- Visualiser les résultats
1. Préparer les Données
Nous allons charger et prétraiter le jeu de données Fashion MNIST.
import numpy as npimport matplotlib.pyplot as pltfrom tensorflow.keras.datasets import fashion_mnist
# Charger le jeu de données(X_train, _), (_, _) = fashion_mnist.load_data()X_train = X_train / 255.0 # Normaliser les images entre 0 et 1X_train = np.expand_dims(X_train, axis=-1) # Ajouter une dimension pour les canaux
2. Définir le Modèle du Générateur
Le générateur transforme un vecteur de bruit aléatoire en une image.
from tensorflow.keras.models import Sequentialfrom tensorflow.keras.layers import Dense, Reshape, Conv2DTranspose, BatchNormalization, LeakyReLU
def build_generator(latent_dim): model = Sequential() model.add(Dense(256 * 7 * 7, activation='relu', input_dim=latent_dim)) model.add(Reshape((7, 7, 256))) model.add(BatchNormalization(momentum=0.8))
model.add(Conv2DTranspose(128, kernel_size=3, strides=2, padding='same')) model.add(BatchNormalization(momentum=0.8)) model.add(LeakyReLU(alpha=0.2))
model.add(Conv2DTranspose(64, kernel_size=3, strides=2, padding='same')) model.add(BatchNormalization(momentum=0.8)) model.add(LeakyReLU(alpha=0.2))
model.add(Conv2DTranspose(1, kernel_size=3, padding='same', activation='tanh'))
return model
latent_dim = 100 # Dimension du bruitgenerator = build_generator(latent_dim)
3. Définir le Modèle du Discriminateur
Le discriminateur détermine si une image est réelle ou générée.
from tensorflow.keras.layers import Conv2D, Flatten
def build_discriminator(img_shape): model = Sequential() model.add(Conv2D(64, kernel_size=3, strides=2, input_shape=img_shape, padding='same')) model.add(LeakyReLU(alpha=0.2))
model.add(Conv2D(128, kernel_size=3, strides=2, padding='same')) model.add(LeakyReLU(alpha=0.2))
model.add(Flatten()) model.add(Dense(1, activation='sigmoid')) # Classification binaire return model
img_shape = (28, 28, 1)discriminator = build_discriminator(img_shape)
# Compiler le discriminateurdiscriminator.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
4. Construire le Modèle DCGAN
Le modèle DCGAN combine le générateur et le discriminateur.
from tensorflow.keras.models import Modelfrom tensorflow.keras.layers import Input
discriminator.trainable = False # Le discriminateur ne sera pas entraîné lors de l'entraînement du DCGANdcgan_input = Input(shape=(latent_dim,))generated_image = generator(dcgan_input)dcgan_output = discriminator(generated_image)dcgan = Model(dcgan_input, dcgan_output)
# Compiler le DCGANdcgan.compile(loss='binary_crossentropy', optimizer='adam')
5. Entraîner le DCGAN
Nous allons entraîner le DCGAN en alternant entre l’entraînement du générateur et celui du discriminateur.
def train_dcgan(dcgan, generator, discriminator, epochs, batch_size): for epoch in range(epochs): # --------------------- # Entraîner le Discriminateur # --------------------- # Sélectionner un échantillon aléatoire d'images réelles idx = np.random.randint(0, X_train.shape[0], batch_size) real_images = X_train[idx]
# Générer des échantillons de bruit aléatoire noise = np.random.normal(0, 1, (batch_size, latent_dim)) fake_images = generator.predict(noise)
# Créer les étiquettes pour les images réelles et générées real_labels = np.ones((batch_size, 1)) # Étiquettes réelles fake_labels = np.zeros((batch_size, 1)) # Étiquettes générées
# Entraîner le discriminateur d_loss_real = discriminator.train_on_batch(real_images, real_labels) d_loss_fake = discriminator.train_on_batch(fake_images, fake_labels) d_loss = 0.5 * np.add(d_loss_real, d_loss_fake)
# --------------------- # Entraîner le Générateur # --------------------- noise = np.random.normal(0, 1, (batch_size, latent_dim)) # Bruit pour le générateur valid_labels = np.ones((batch_size, 1)) # On veut que le générateur produise des images "réelles"
# Entraîner le générateur g_loss = dcgan.train_on_batch(noise, valid_labels)
# Afficher les pertes print(f"{epoch}/{epochs} [D loss: {d_loss[0]:.4f}, acc.: {100*d_loss[1]:.2f}%] [G loss: {g_loss:.4f}]")
# Paramètres d'entraînementepochs = 10000batch_size = 64
# Entraîner le DCGANtrain_dcgan(dcgan, generator, discriminator, epochs, batch_size)
6. Visualiser les Résultats
Nous allons visualiser les images générées après l’entraînement.
def plot_generated_images(generator, epoch, latent_dim): noise = np.random.normal(0, 1, (16, latent_dim)) generated_images = generator.predict(noise) generated_images = generated_images.reshape(16, 28, 28)
plt.figure(figsize=(10, 10)) for i in range(generated_images.shape[0]): plt.subplot(4, 4, i + 1) plt.imshow(generated_images[i], interpolation='nearest', cmap='gray') plt.axis('off') plt.tight_layout() plt.savefig(f"dcgan_generated_epoch_{epoch}.png") plt.show()
# Exemple d'affichage des résultatsplot_generated_images(generator, 10000, latent_dim)
Conclusion
Vous avez maintenant construit un DCGAN capable de générer des images du jeu de données Fashion MNIST. Les GAN peuvent être améliorés et ajustés pour générer des images de meilleure qualité en expérimentant avec les architectures et les hyperparamètres. N’hésitez pas à explorer et à personnaliser votre modèle !