Generatore di volti falsi utilizzando il modello DCGAN

Blog

Generatore di volti falsi utilizzando il modello DCGAN

Panoramica

Nel seguente articolo, definiremo e alleneremo a Deep Convolutional Generative Adversarial Network_(DCGAN)_ modello su un set di dati di volti. L'obiettivo principale del modello è ottenere una rete di generatori per generare nuove immagini di falsi volti umani che sembrino il più realistici possibile.



Per farlo, cercheremo prima di capire l'intuizione dietro il funzionamento di ** GAN **sabbia ** DCGAN **s e poi unisci questa conoscenza per costruire un Modello di generatore di volti falsi . Entro la fine di questo post, sarai in grado di generare i tuoi campioni falsi su qualsiasi dato set di dati, utilizzando i concetti di questo articolo.

introduzione

Il seguente articolo è diviso in due sezioni:



  • Teoria — Comprendere l'intuizione dietro il funzionamento di _GAN_s e _DCGAN_s.
  • Pratico — Implementazione di Fake Face Generator in Pytorch.

Questo articolo coprirebbe entrambe le sezioni. Allora iniziamo il viaggio....

Teoria

Intuizione dietro le reti generative avversarie (GAN)

Generatore di volti falsi utilizzando il modello DCGAN



  • Definizione

_GAN_s, in generale, può essere definito come un modello generativo che ci permette di generare un'intera immagine in parallelo. Insieme a molti altri tipi di modelli generativi, _GAN_s utilizza una funzione differenziabile rappresentata da una rete neurale come Rete di generatori .

  • Rete di generatori

La rete del generatore prende il rumore casuale come input, quindi esegue il rumore attraverso la funzione differenziabile_(rete neurale)_ per trasformare il rumore e rimodellarlo per avere una struttura riconoscibile simile alle immagini nel set di dati di addestramento. L'uscita del generatore è determinata dalla scelta del rumore casuale in ingresso. L'esecuzione di Generator Network su diversi rumori di input casuali produce diverse immagini di output realistiche.

L'obiettivo finale del Generatore è apprendere una distribuzione simile alla distribuzione del set di dati di addestramento per campionare immagini realistiche. Per poterlo fare, la rete di generatori deve essere formata. Il processo di formazione del GAN_s è molto diverso, rispetto ad altri modelli generativi (La maggior parte dei modelli generativi viene addestrata regolando i parametri per massimizzare la probabilità del generatore di generare campioni realistici. Ad es. Auto-encoder variazionali (VAE)). GAN_s, invece, utilizza una seconda rete per addestrare il Generatore, chiamata Rete di discriminatori .

  • Rete di discriminatori

Discriminator Network è una rete di classificazione di base che restituisce la probabilità che un'immagine sia reale. Quindi, durante il processo di formazione, la rete del discriminatore mostra immagini reali dal set di formazione per metà del tempo e immagini false da Generator per un'altra metà del tempo. L'obiettivo del discriminatore è assegnare una probabilità vicina a 1, per le immagini reali e una probabilità vicina a 0, per le immagini false.

D'altra parte, Generator tenta il contrario, il suo obiettivo è generare immagini false, per le quali Discriminator risulterebbe in una probabilità vicina a 1_ (considerandole immagini reali dal training set)_. Man mano che la formazione prosegue, il discriminatore diventerà più bravo a classificare le immagini reali e false. Quindi, per ingannare il discriminatore, Generator sarà costretto a migliorare per produrre campioni più realistici. Quindi possiamo dire che:

I GAN possono essere considerati come un gioco non cooperativo a due giocatori (Generatore e Discriminatore), in cui ogni giocatore desidera ridurre al minimo la sua funzione di costo.

Differenza tra GAN e DCGAN

_DCGAN_s sono molto simili a _GAN_s ma si concentrano specificamente sull'utilizzo di reti convoluzionali profonde al posto delle reti completamente connesse utilizzate in Vanilla _GAN_s.

Le reti convoluzionali aiutano a trovare una correlazione profonda all'interno di un'immagine, ovvero cercano una correlazione spaziale. Ciò significa che DCGAN sarebbe un'opzione migliore per i dati immagine/video, mentre _GAN_s può essere considerato come un'idea generale su cui _DCGAN_s e molte altre architetture (CGAN, CycleGAN, StarGAN e molti altri) sono stati sviluppati.

angularjs nodo js esempio

In questo articolo, lavoriamo principalmente sui dati di immagine, questo significa che DCGAN sarebbe un'opzione migliore rispetto a Vanilla GAN. Quindi d'ora in poi ci concentreremo principalmente sui DCGAN.

Alcuni suggerimenti per la formazione di DCGAN

Tutti i consigli di allenamento possono essere applicati anche a Vanilla GAN_s_ pure_._

visual studio 2019 profiler
  • Assicurati che sia Discriminator che Generator abbiano almeno un livello nascosto. Questo assicura che entrambi i modelli abbiano un Proprietà di approssimazione universale .

Proprietà di approssimazione universale afferma che una rete feed-forward con un singolo strato nascosto contenente un numero finito di unità nascoste può approssimare qualsiasi distribuzione di probabilità, dato un numero sufficiente di unità nascoste.

  • Per le unità nascoste, potrebbero funzionare molte funzioni di attivazione, ma le Leaky ReLU sono le più popolari. Le ReLU con perdite assicurano che il gradiente scorra attraverso l'intera architettura. Questo è molto importante per _DCGAN_s perché l'unico modo in cui il generatore può apprendere è ricevere un gradiente dal discriminatore.
  • Una delle funzioni di attivazione più popolari per l'output della rete di generatori è la funzione di attivazione iperbolica tangente_ (basata su_ Tecniche di formazione migliorate per i GAN carta) .
  • Poiché il discriminatore è un classificatore binario, utilizzeremo la funzione di attivazione sigmoide per ottenere la probabilità finale.

Finora abbiamo parlato dell'intuizione lavorativa e di alcuni suggerimenti e trucchi per allenare _GAN_s/_DCGAN_s. Ma ancora, molte domande rimangono senza risposta. Alcuni di loro sono:

Quale ottimizzatore scegliere? Come viene definita la funzione di costo? Quanto tempo deve essere formata una rete? e molti altri, che sarebbero coperti nel Pratico sezione.

Pratico

La parte di implementazione è suddivisa in una serie di attività da caricamento dei dati per definire e addestrare reti avversarie . Alla fine di questa sezione, sarai in grado di visualizzare i risultati del tuo generatore addestrato per vedere come si comporta; i tuoi campioni generati dovrebbero assomigliare abbastanza a facce realistiche con piccole quantità di rumore.
Generatore di volti falsi utilizzando il modello DCGAN

(1) Ottieni i dati

Utilizzerai il CelebFaces Attributi Dataset (CelebA) per addestrare le tue reti avversarie. Questi dati sono un set di dati più complesso rispetto al MNIST. Quindi, abbiamo bisogno di definire una rete più profonda_(DCGAN)_ per generare buoni risultati. Ti suggerirei di utilizzare una GPU per scopi di formazione.

(2) Preparazione dei dati

Poiché l'obiettivo principale di questo articolo è costruire un DCGAN modello, quindi invece di eseguire noi stessi la preelaborazione, utilizzeremo un set di dati pre-elaborato. Puoi scaricare il sottoinsieme più piccolo del CelebA set di dati da qui . E se sei interessato a eseguire la pre-elaborazione, procedi come segue:

  • Ritaglia le immagini per rimuovere la parte che non include il viso.
  • Ridimensionarli in 64x64x3 NumPy immagini.

Ora creeremo un Caricatore dati per accedere alle immagini in batch.

def get_dataloader(batch_size, image_size, data_dir='train/'): ''' Batch the neural network data using DataLoader :param batch_size: The size of each batch; the number of images in a batch :param img_size: The square size of the image data (x, y) :param data_dir: Directory where image data is located :return: DataLoader with batched data ''' transform = transforms.Compose([transforms.Resize(image_size),transforms.CenterCrop(image_size),transforms.ToTensor()]) dataset = datasets.ImageFolder(data_dir,transform = transform) dataloader = torch.utils.data.DataLoader(dataset = dataset,batch_size = batch_size,shuffle = True) return dataloader# Define function hyperparameters batch_size = 256 img_size = 32# Call your function and get a dataloader celeba_train_loader = get_dataloader(batch_size, img_size)

Caricatore dati iperparametri:

  • Puoi decidere su qualsiasi ragionevole dimensione del lotto parametro.
  • Tuttavia, il tuo dimensione dell'immagine deve essere 32. Ridimensionare i dati a una dimensione più piccola renderà l'allenamento più veloce, pur continuando a creare immagini convincenti dei volti.

Successivamente, scriveremo del codice per ottenere una rappresentazione visiva del set di dati.

def imshow(img): npimg = img.numpy() plt.imshow(np.transpose(npimg, (1, 2, 0)))# obtain one batch of training images dataiter = iter(celeba_train_loader) images, _ = dataiter.next() # _ for no labels# plot the images in the batch, along with the corresponding labels fig = plt.figure(figsize=(20, 4)) plot_size=20 for idx in np.arange(plot_size): ax = fig.add_subplot(2, plot_size/2, idx+1, xticks=[], yticks=[]) imshow(images[idx])

Tieni presente di convertire il tensore immagini in a NumPy digita e trasponi le dimensioni per visualizzare correttamente un'immagine basata sul codice sopra_(In Dataloader abbiamo trasformato le immagini in Tensor)_. Esegui questo pezzo di codice per ottenere una visualizzazione del set di dati.

Generatore di volti falsi utilizzando il modello DCGAN

Ora, prima di iniziare con la sezione successiva_(Definizione del modello),_ scriveremo una funzione per ridimensionare i dati dell'immagine in un intervallo di pixel da -1 a 1 che utilizzeremo durante l'addestramento. La ragione per farlo è che l'output di un generatore attivato tanh conterrà valori di pixel in un intervallo da -1 a 1, e quindi, dobbiamo ridimensionare le nostre immagini di addestramento in un intervallo da -1 a 1_ (in questo momento, loro sono nell'intervallo 0–1)_.

def scale(x, feature_range=(-1, 1)): ''' Scale takes in an image x and returns that image, scaled with a feature_range of pixel values from -1 to 1. This function assumes that the input x is already scaled from 0-1.''' # assume x is scaled to (0, 1) # scale to feature_range and return scaled x min, max = feature_range x = x*(max-min) + min return x

(3) Definizione del modello

A GAN è composto da due reti antagoniste, un discriminatore e un generatore. Quindi, in questa sezione, definiremo le architetture per entrambi.

Discriminatore

Questo è un classificatore convoluzionale, solo senza MaxpPooling strati. Ecco il codice per la rete dei discriminatori.

def conv(input_c,output,kernel_size,stride = 2,padding = 1, batch_norm = True): layers =[] con = nn.Conv2d(input_c,output,kernel_size,stride,padding,bias = False) layers.append(con) if batch_norm: layers.append(nn.BatchNorm2d(output)) return nn.Sequential(*layers)class Discriminator(nn.Module):def __init__(self, conv_dim): ''' Initialize the Discriminator Module :param conv_dim: The depth of the first convolutional layer ''' #complete init functionsuper(Discriminator, self).__init__() self.conv_dim = conv_dim self.layer_1 = conv(3,conv_dim,4,batch_norm = False) #16 self.layer_2 = conv(conv_dim,conv_dim*2,4) #8 self.layer_3 = conv(conv_dim*2,conv_dim*4,4) #4 self.fc = nn.Linear(conv_dim*4*4*4,1)def forward(self, x): ''' Forward propagation of the neural network :param x: The input to the neural network :return: Discriminator logits; the output of the neural network ''' # define feedforward behavior x = F.leaky_relu(self.layer_1(x)) x = F.leaky_relu(self.layer_2(x)) x = F.leaky_relu(self.layer_3(x)) x = x.view(-1,self.conv_dim*4*4*4) x = self.fc(x) return x

Spiegazione

  • L'architettura seguente è costituita da tre livelli convoluzionali e un livello finale completamente connesso, che genera un singolo logit. Questo logit definisce se l'immagine è reale o meno.
  • Ogni strato di convoluzione, eccetto il primo, è seguito da a Normalizzazione batch (definita nella funzione di supporto conv) .
  • Per le unità nascoste, abbiamo usato il che perde ReLU funzione di attivazione come discusso nel teoria sezione.
  • Dopo ogni strato di convoluzione, l'altezza e la larghezza diventano la metà. Ad esempio, dopo la prima convoluzione le immagini 32X32 verranno ridimensionate in 16X16 e così via.

La dimensione di output può essere calcolata utilizzando la seguente formula:
Generatore di volti falsi utilizzando il modello DCGAN

dove O è l'altezza/lunghezza dell'output, IN è l'altezza/lunghezza di input, A è la dimensione del filtro, P è l'imbottitura, e S è il passo.

  • Il numero di mappe delle caratteristiche dopo ogni convoluzione si basa sul parametro conv_dim(Nella mia implementazione conv_dim = 64) .

In questa definizione del modello, non abbiamo applicato il Sigmoide funzione di attivazione sul logit di uscita finale. Ciò è dovuto alla scelta della nostra funzione di perdita. Qui invece di usare il normale BCE (perdita di entropia incrociata binaria), useremo BCEWithLogitLoss, che è considerato come una versione numericamente stabile di BCE . BCEWithLogitLoss è definito in modo tale da applicare prima la funzione di attivazione Sigmoid sul logit e quindi calcolare la perdita, a differenza di BCE . Puoi leggere di più su queste funzioni di perdita qui .

Generatore

Il generatore dovrebbe sovracampionare un input e generare una nuova immagine della stessa dimensione dei nostri dati di training 32X32X3. Per farlo utilizzeremo i livelli convoluzionali di trasposizione. Ecco il codice per la rete del generatore.

def deconv(input_c,output,kernel_size,stride = 2, padding =1, batch_norm = True): layers = [] decon = nn.ConvTranspose2d(input_c,output,kernel_size,stride,padding,bias = False) layers.append(decon) if batch_norm: layers.append(nn.BatchNorm2d(output)) return nn.Sequential(*layers)class Generator(nn.Module): def __init__(self, z_size, conv_dim): ''' Initialize the Generator Module :param z_size: The length of the input latent vector, z :param conv_dim: The depth of the inputs to the *last* transpose convolutional layer ''' super(Generator, self).__init__() # complete init function self.conv_dim = conv_dim self.fc = nn.Linear(z_size,conv_dim*8*2*2) self.layer_1 = deconv(conv_dim*8,conv_dim*4,4) #4 self.layer_2 = deconv(conv_dim*4,conv_dim*2,4) #8 self.layer_3 = deconv(conv_dim*2,conv_dim,4) #16 self.layer_4 = deconv(conv_dim,3,4,batch_norm = False) #32 def forward(self, x): ''' Forward propagation of the neural network :param x: The input to the neural network :return: A 32x32x3 Tensor image as output ''' # define feedforward behavior x = self.fc(x) x = x.view(-1,self.conv_dim*8,2,2) #(batch_size,depth,width,height) x = F.relu(self.layer_1(x)) x = F.relu(self.layer_2(x)) x = F.relu(self.layer_3(x)) x = torch.tanh(self.layer_4(x)) return x

Spiegazione

  • L'architettura seguente è costituita da un livello completamente connesso seguito da quattro livelli di convoluzione trasposta. Questa architettura è definita in modo tale che l'output dopo il quarto livello di convoluzione di trasposizione risulti in un'immagine di dimensione 32X32X3_(dimensione di un'immagine dal set di dati di addestramento)._
  • Gli ingressi al generatore sono vettori di una certa lunghezza z_size(z_size è il vettore del rumore) .
  • Ciascun livello di convoluzione di trasposizione, eccetto l'ultimo, è seguito da a Normalizzazione batch (definita nella funzione di supporto deconv) .
  • Per le unità nascoste, abbiamo usato il riprendere funzione di attivazione.
  • Dopo ogni livello di convoluzione trasposta, l'altezza e la larghezza diventano doppie. Ad esempio, dopo la prima convoluzione di trasposizione le immagini 2X2 verranno ridimensionate in 4X4 e così via.

Può essere calcolato utilizzando la seguente formula:

perché la mia banca rifiuta il pagamento in contanti dell'app?

_# Padding==Same: H = H1 * stride_

_# Padding==Valid H = (H1-1) * stride + HF_

dove H = dimensione dell'uscita, H1 = dimensione dell'ingresso, HF = dimensione del filtro.

  • Il numero di mappe delle caratteristiche dopo ogni convoluzione di trasposizione si basa sul parametro conv_dim(Nella mia implementazione conv_dim = 64) .

(4) Inizializza i pesi delle tue reti

Per aiutare i modelli a convergere, ho inizializzato i pesi degli strati convoluzionali e lineari nel modello in base al originale DCGAN carta , che dice: Tutti i pesi sono inizializzati da una distribuzione Normale centrata sullo zero con una deviazione standard di 0,02.

def weights_init_normal(m): ''' Applies initial weights to certain layers in a model . The weights are taken from a normal distribution with mean = 0, std dev = 0.02. :param m: A module or layer in a network ''' # classname will be something like: # `Conv`, `BatchNorm2d`, `Linear`, etc. classname = m.__class__.__name__ if hasattr(m,'weight') and (classname.find('Conv') != -1 or classname.find('Linear') != -1): m.weight.data.normal_(0.0,0.02) if hasattr(m,'bias') and m.bias is not None: m.bias.data.zero_()
  • Ciò inizializzerebbe i pesi su una distribuzione normale, centrata intorno a 0, con una deviazione standard di 0,02.
  • I termini di bias, se esistono, possono essere lasciati soli o impostati su 0.

(5) Costruisci una rete completa

Definisci gli iperparametri dei tuoi modelli e istanzia il discriminatore e il generatore dalle classi definite nel Definizione del modello sezione. Ecco il codice per quello.

dove acquistare lto network
def build_network(d_conv_dim, g_conv_dim, z_size): # define discriminator and generator D = Discriminator(d_conv_dim) G = Generator(z_size=z_size, conv_dim=g_conv_dim)# initialize model weights D.apply(weights_init_normal) G.apply(weights_init_normal)print(D) print() print(G) return D, G # Define model hyperparams d_conv_dim = 64 g_conv_dim = 64 z_size = 100D, G = build_network(d_conv_dim, g_conv_dim, z_size)

Quando esegui il codice sopra, ottieni il seguente output. Descrive inoltre l'architettura del modello per i modelli Discriminator e Generator.
Generatore di volti falsi utilizzando il modello DCGAN

(6) Processo di formazione

Il processo di addestramento comprende la definizione delle funzioni di perdita, la selezione dell'ottimizzatore e infine l'addestramento del modello.

Discriminatore e perdita del generatore

Perdita discriminatore

  • Per il discriminatore, la perdita totale è la somma di (d_real_loss + d_fake_loss) , dove d_real_loss è la perdita ottenuta sulle immagini dai dati di addestramento e d_fake_loss è la perdita ottenuta sulle immagini generate da Generator Network. Per-eg

z — Vettore del rumore

i — Immagine dal training set

G(z) — Immagine generata

D(G(z)) — Output discriminatore su un'immagine generata

D(i) — Output del discriminatore su un'immagine del set di dati di addestramento

Perdita = perdita_reale(D(i)) + perdita_falsa(D(G(z)))

  • Ricorda che vogliamo che il discriminatore emetta 1 per immagini reali e 0 per immagini false, quindi dobbiamo impostare le perdite per riflettere questo_(Tieni a mente questa riga mentre leggi il codice qui sotto)_.

Perdita del generatore

  • La perdita del generatore sarà simile solo con le etichette capovolte. L'obiettivo del generatore è far credere al discriminatore che le sue immagini generate siano vero . Per-eg

z — Vettore del rumore

G(z) — Immagine generata

D(G(z)) — Output discriminatore su un'immagine generata

Perdita = perdita_reale(D(G(z)))

Ecco il codice per real_loss e fake_loss

def real_loss(D_out): '''Calculates how close discriminator outputs are to being real. param, D_out: discriminator logits return: real loss''' batch_size = D_out.size(0) labels = torch.ones(batch_size) if train_on_gpu: labels = labels.cuda() criterion = nn.BCEWithLogitsLoss() loss = criterion(D_out.squeeze(),labels) return lossdef fake_loss(D_out): '''Calculates how close discriminator outputs are to being fake. param, D_out: discriminator logits return: fake loss''' batch_size = D_out.size(0) labels = torch.zeros(batch_size) if train_on_gpu: labels = labels.cuda() criterion = nn.BCEWithLogitsLoss() loss = criterion(D_out.squeeze(),labels) return loss

Ottimizzatori

Per _GAN_s definiamo due ottimizzatori, uno per il Generatore e l'altro per il Discriminatore. L'idea è di eseguirli contemporaneamente per continuare a migliorare entrambe le reti. In questa implementazione, ho usato Adamo ottimizzatore in entrambi i casi. Per saperne di più sui diversi ottimizzatori, fare riferimento a questo collegamento .

# Create optimizers for the discriminator D and generator G d_optimizer = optim.Adam(D.parameters(),lr = .0002, betas = [0.5,0.999]) g_optimizer = optim.Adam(G.parameters(),lr = .0002, betas = [0.5,0.999])

Tasso di apprendimento (lr) e beta i valori sono basati sull'originale Carta DCGAN .

Addestramento

L'addestramento comporterà l'alternanza tra l'addestramento del discriminatore e del generatore. Useremo il real_loss e fake_loss funzioni definite in precedenza, per aiutarci nel calcolo delle perdite del discriminatore e del generatore.

futuro della rete asp
  • Dovresti addestrare il discriminatore alternando immagini vere e false
  • Quindi il generatore, che cerca di ingannare il discriminatore e dovrebbe avere una funzione di perdita opposta

Ecco il codice per l'allenamento.

def train(D, G, n_epochs, print_every=50): '''Trains adversarial networks for some number of epochs param, D: the discriminator network param, G: the generator network param, n_epochs: number of epochs to train for param, print_every: when to print and record the models' losses return: D and G losses''' # move models to GPU if train_on_gpu: D.cuda() G.cuda()# keep track of loss and generated, 'fake' samples samples = [] losses = []# Get some fixed data for sampling. These are images that are held # constant throughout training, and allow us to inspect the model's performance sample_size=16 fixed_z = np.random.uniform(-1, 1, size=(sample_size, z_size)) fixed_z = torch.from_numpy(fixed_z).float() # move z to GPU if available if train_on_gpu: fixed_z = fixed_z.cuda()# epoch training loop for epoch in range(n_epochs):# batch training loop for batch_i, (real_images, _) in enumerate(celeba_train_loader):batch_size = real_images.size(0) real_images = scale(real_images) if train_on_gpu: real_images = real_images.cuda() # 1. Train the discriminator on real and fake ima.ges d_optimizer.zero_grad() d_out_real = D(real_images) z = np.random.uniform(-1,1,size = (batch_size,z_size)) z = torch.from_numpy(z).float() if train_on_gpu: z = z.cuda() d_loss = real_loss(d_out_real) + fake_loss(D(G(z))) d_loss.backward() d_optimizer.step() # 2. Train the generator with an adversarial loss G.train() g_optimizer.zero_grad() z = np.random.uniform(-1,1,size = (batch_size,z_size)) z = torch.from_numpy(z).float() if train_on_gpu: z = z.cuda() g_loss = real_loss(D(G(z))) g_loss.backward() g_optimizer.step() # Print some loss stats if batch_i % print_every == 0: # append discriminator loss and generator loss losses.append((d_loss.item(), g_loss.item())) # print discriminator and generator loss print('Epoch [{:5d}/{:5d}] | d_loss: {:6.4f} | g_loss: {:6.4f}'.format( epoch+1, n_epochs, d_loss.item(), g_loss.item()))## AFTER EACH EPOCH## # this code assumes your generator is named G, feel free to change the name # generate and save sample, fake images G.eval() # for generating samples samples_z = G(fixed_z) samples.append(samples_z) G.train() # back to training mode# Save training generator samples with open('train_samples.pkl', 'wb') as f: pkl.dump(samples, f) # finally return losses return losses # set number of epochs n_epochs = 40# call training function losses = train(D, G, n_epochs=n_epochs)

L'addestramento viene eseguito per oltre 40 epoche utilizzando una GPU, ecco perché ho dovuto spostare i miei modelli e gli input dalla CPU alla GPU.

(6)Risultati

  • Quello che segue è il grafico delle perdite di allenamento per il Generatore e il Discriminatore registrate dopo ogni epoca.
    Generatore di volti falsi utilizzando il modello DCGAN
    L'elevata fluttuazione nella perdita di allenamento del generatore è dovuta al fatto che l'input alla rete del generatore è un batch di vettori di rumore casuali (ciascuno di z_size) , ciascuna campionata da una distribuzione uniforme di (-1,1) per generare nuove immagini per ogni epoca.

Nel grafico del discriminatore, possiamo osservare un aumento della perdita di allenamento (circa 50 sull'asse x) seguito da una diminuzione graduale fino alla fine, questo perché il Generatore ha iniziato a generare un'immagine realistica che ha ingannato il Discriminatore, portando ad un aumento dell'errore. Ma lentamente, man mano che l'addestramento progredisce, Discriminator migliora nel classificare le immagini false e reali, portando a una graduale diminuzione dell'errore di addestramento.

  • Campioni generati dopo 40 epoche .
    Generatore di volti falsi utilizzando il modello DCGAN

Il nostro modello è stato in grado di generare nuove immagini di falsi volti umani che sembrano il più realistici possibile. Possiamo anche osservare che tutte le immagini hanno una tonalità più chiara, anche le facce marroni sono un po' più chiare. Questo perché il CelebA il set di dati è distorto; si compone di volti di celebrità che sono per lo più bianchi. Detto questo, DCGAN genera con successo immagini quasi reali dal semplice rumore.

Generatore di volti falsi utilizzando il modello DCGAN

#machine-learning #ai #data-science #deep-learning