-->

Intelligenza Artificiale

A un certo punto non fu più la biologia a dominare il destino dell'uomo, ma il prodotto del suo cervello: la cultura.
Cosicché: "Le uniche leggi della materia sono quelle che la nostra mente deve architettare e le uniche leggi della mente sono architettate per essa dalla materia".
JAMES CLERK MAXWELL

Reti GAN Codice


Codice di una rete Generative Adversarial Networks (GAN), con il data set Fashion MNSIT.
Tutti i passi principali, commentati

Generare Immagini con GAN

Creare e addestrare una rete Generative Adversarial Network (GAN) utilizzando il dataset Fashion MNIST, seguiremo i seguenti passaggi:
  • Caricamento del dataset Fashion MNIST.

  • Preprocessing e normalizzazione dei dati.

  • Definizione del generatore con una rete Conv2D e funzione tanh.

  • Definizione del discriminatore con una rete Conv2D e funzione sigmoid.

  • Addestramento del generatore e del discriminatore con Cross Entropy.

  • Visualizzazione delle immagini generate con matplotlib

Caricamento del dataset Fashion MNIST



(train_images, train_labels), (_, _) = tf.keras.datasets.fashion_mnist.load_data()

Qui stiamo caricando il dataset Fashion MNIST usando `tf.keras.datasets.fashion_mnist.load_data()`. Questo dataset contiene immagini in scala di grigi di articoli di abbigliamento.

Preprocessing e normalizzazione dei dati


train_images = train_images.reshape(train_images.shape[0], 28, 28, 1).astype('float32')
train_images = (train_images - 127.5) / 127.5  # Normalizzazione a [-1, 1]

* `train_images.reshape(train_images.shape[0], 28, 28, 1).astype('float32')`: Riorganizza le immagini in un formato adatto per la rete convoluzionale, cambiando la dimensione a `(28, 28, 1)` e convertendo i valori in `float32`.
* `(train_images - 127.5) / 127.5`: Normalizza i valori dei pixel da [0, 255] a [-1, 1], che è l'intervallo richiesto dalla funzione di attivazione `tanh` nel generatore.

Creazione del dataset tf.data



BUFFER_SIZE = 60000
BATCH_SIZE = 256
train_dataset = tf.data.Dataset.from_tensor_slices(train_images).shuffle(BUFFER_SIZE).batch(BATCH_SIZE)


* `BUFFER_SIZE`: Numero di immagini nel dataset per lo shuffle.
* `BATCH_SIZE`: Numero di immagini da passare alla rete in un batch.
* `tf.data.Dataset.from_tensor_slices(train_images).shuffle(BUFFER_SIZE).batch(BATCH_SIZE)`: Crea un dataset TensorFlow, applica lo shuffle e lo divide in batch.

Definizione del generatore


def make_generator_model():
    model = tf.keras.Sequential()
    model.add(layers.Dense(7*7*256, use_bias=False, input_shape=(100,)))
    model.add(layers.BatchNormalization())
    model.add(layers.ReLU())
    model.add(layers.Reshape((7, 7, 256)))
    model.add(layers.Conv2DTranspose(128, (5, 5), strides=(1, 1), padding='same', use_bias=False))
    model.add(layers.BatchNormalization())
    model.add(layers.ReLU())
    model.add(layers.Conv2DTranspose(64, (5, 5), strides=(2, 2), padding='same', use_bias=False))
    model.add(layers.BatchNormalization())
    model.add(layers.ReLU())
    model.add(layers.Conv2DTranspose(1, (5, 5), strides=(2, 2), padding='same', use_bias=False, activation='tanh'))
    return model

Il generatore prende un input di rumore casuale e genera immagini realistiche:
* `Dense(7*7*256, use_bias=False, input_shape=(100,))`: Densa, senza bias, trasforma il vettore di rumore in una mappa di caratteristiche di dimensioni `7*7*256`.
* `BatchNormalization()`: Normalizza le uscite del layer precedente.
* `ReLU()`: Funzione di attivazione ReLU. * `Reshape((7, 7, 256))`: Cambia la dimensione a `7x7x256`.
* `Conv2DTranspose(...)`: Strato di convoluzione trasposta per aumentare la risoluzione dell'immagine.
* `tanh`: Funzione di attivazione che produce valori nell'intervallo [-1, 1].

Definizione del discriminatore



def make_discriminator_model():
    model = tf.keras.Sequential()
    model.add(layers.Conv2D(64, (5, 5), strides=(2, 2), padding='same', input_shape=[28, 28, 1]))
    model.add(layers.LeakyReLU())
    model.add(layers.Dropout(0.3))
    model.add(layers.Conv2D(128, (5, 5), strides=(2, 2), padding='same'))
    model.add(layers.LeakyReLU())
    model.add(layers.Dropout(0.3))
    model.add(layers.Flatten())
    model.add(layers.Dense(1, activation='sigmoid'))
    return model


Il discriminatore classifica le immagini come reali o generate:
* `Conv2D(64, (5, 5), strides=(2, 2), padding='same', input_shape=[28, 28, 1])`: Strato convoluzionale per estrarre caratteristiche.
* `LeakyReLU()`: Funzione di attivazione LeakyReLU.
* `Dropout(0.3)`: Applicazione del dropout per ridurre l'overfitting.
* `Dense(1, activation='sigmoid')`: Strato denso con attivazione sigmoid per produrre una probabilità.

Funzioni di perdita



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

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):


* `BinaryCrossentropy(from_logits=False)`: Funzione di perdita per la classificazione binaria.
* `discriminator_loss`: Somma della perdita sui dati reali e falsi.
* `generator_loss`: Misura la capacità del generatore di ingannare il discriminatore.

Ottimizzatori


generator_optimizer = tf.keras.optimizers.Adam(1e-4)
discriminator_optimizer = tf.keras.optimizers.Adam(1e-4)


Usiamo Adam come ottimizzatore per entrambi i modelli con un learning rate di 0.0001.

Creazione dei modelli e checkpoint


generator = make_generator_model()
discriminator = make_discriminator_model()

checkpoint_dir = './training_checkpoints'
checkpoint_prefix = os.path.join(checkpoint_dir, "ckpt")
checkpoint = tf.train.Checkpoint(generator_optimizer=generator_optimizer,
                                 discriminator_optimizer=discriminator_optimizer,
                                 generator=generator,
                                 discriminator=discriminator)


* `make_generator_model()` e `make_discriminator_model()`: Inizializza i modelli.
* `tf.train.Checkpoint`: Per salvare i modelli e gli ottimizzatori durante l'addestramento.

Training



EPOCHS = 50
noise_dim = 100
num_examples_to_generate = 16
seed = tf.random.normal([num_examples_to_generate, noise_dim])

@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(epochs):
        for image_batch in dataset:
            train_step(image_batch)

        generate_and_save_images(generator, epoch + 1, seed)

        if (epoch + 1) % 15 == 0:
            checkpoint.save(file_prefix = checkpoint_prefix)

        print ('Epoca {} terminata'.format(epoch + 1))

    generate_and_save_images(generator, epochs, seed)


* `EPOCHS = 50`: Numero di epoche di addestramento.
* `noise_dim = 100`: Dimensione del vettore di rumore per il generatore.
* `num_examples_to_generate = 16`: Numero di immagini generate per la visualizzazione.
* `seed`: Vettore di rumore per la visualizzazione delle immagini generate durante l'addestramento.
* `train_step`: Funzione di addestramento per un singolo batch di immagini.
* `train`: Funzione principale di addestramento che esegue `train_step` su ogni batch per ogni epoca.

Generazione e salvataggio delle immagini



def generate_and_save_images(model, epoch, test_input):
    predictions = model(test_input, training=False)

    fig = plt.figure(figsize=(4,4))

    for i in range(predictions.shape[0]):
        plt.subplot(4, 4, i+1)
        plt.imshow(predictions[i, :, :, 0] * 127.5 + 127.5, cmap='gray')
        plt.axis('off')

    plt.savefig('image_at_epoch_{:04d}.png'.format(epoch))
    plt.show()

# Inizia l'addestramento
train(train_dataset, EPOCHS)


Accedi alla Area Riservata per scaricare il codice


download

Se vuoi Saperne di piu’

Accedi all'area Riservata

Scarica il codice dell'articolo