Un modello generativo è un modo potente di imparare qualsiasi tipo di distribuzione dei dati usando l’apprendimento non supervisionato e ha raggiunto un enorme successo in pochi anni. Tutti i tipi di modelli generativi mirano ad apprendere la vera distribuzione dei dati dell’insieme di allenamento in modo da generare nuovi punti dati con alcune variazioni. Ma non è sempre possibile imparare l’esatta distribuzione dei nostri dati sia implicitamente che esplicitamente e quindi cerchiamo di modellare una distribuzione che sia il più possibile simile alla vera distribuzione dei dati. Per questo, possiamo sfruttare la potenza delle reti neurali per imparare una funzione che possa approssimare la distribuzione del modello alla vera distribuzione.
Due degli approcci più comunemente usati ed efficienti sono i Variational Autoencoders (VAE) e le Generative Adversarial Networks (GAN). VAE mira a massimizzare il limite inferiore della log-likelihood dei dati e GAN mira a raggiungere un equilibrio tra generatore e discriminatore. In questo blogpost, spiegherò il funzionamento di VAE e GAN e l’intuizione dietro di loro.
Variational Autoencoder
Presumo che il lettore abbia già familiarità con il funzionamento di un vanilla autoencoder. Sappiamo che possiamo usare un autocodificatore per codificare un’immagine di input in una rappresentazione dimensionale molto più piccola che può memorizzare informazioni latenti sulla distribuzione dei dati di input. Ma in un autocodificatore vanilla, il vettore codificato può solo essere mappato all’input corrispondente usando un decodificatore. Non può certo essere usato per generare immagini simili con una certa variabilità.
Per ottenere questo, il modello ha bisogno di imparare la distribuzione di probabilità dei dati di allenamento. VAE è uno degli approcci più popolari per imparare la distribuzione di dati complicati come le immagini utilizzando reti neurali in modo non supervisionato. Si tratta di un modello grafico probabilistico radicato nell’inferenza bayesiana, cioè il modello mira ad apprendere la distribuzione di probabilità sottostante ai dati di allenamento in modo da poter facilmente campionare nuovi dati da quella distribuzione appresa. L’idea è quella di imparare una rappresentazione latente a bassa dimensione dei dati di allenamento chiamata variabili latenti (variabili che non sono direttamente osservate ma sono piuttosto dedotte attraverso un modello matematico) che si presume abbiano generato i nostri dati di allenamento effettivi. Queste variabili latenti possono conservare informazioni utili sul tipo di output che il modello deve generare. La distribuzione di probabilità delle variabili latenti z è indicata con P(z). Una distribuzione gaussiana è selezionata come priore per imparare la distribuzione P(z) in modo da campionare facilmente nuovi punti dati durante il tempo di inferenza.
Ora l’obiettivo primario è quello di modellare i dati con alcuni parametri che massimizzano la probabilità dei dati di allenamento X. In breve, stiamo assumendo che un vettore latente a bassa dimensione abbia generato i nostri dati x (x ∈ X) e possiamo mappare questo vettore latente ai dati x usando una funzione deterministica f(z;θ) parametrizzata da theta che dobbiamo valutare (vedi fig. 1). Sotto questo processo generativo, il nostro scopo è di massimizzare la probabilità di ogni dato in X che è dato come,
Pө(X) = ∫Pө(X, z)dz = ∫Pө(X|z)Pө(z)dz (1)
Qui, f(z;θ)è stata sostituita da una distribuzione Pө(X|z).
L’intuizione dietro questa stima di massima verosimiglianza è che se il modello può generare campioni di allenamento da queste variabili latenti allora può anche generare campioni simili con alcune variazioni. In altre parole, se campioniamo un gran numero di variabili latenti da P(z) e generiamo x da queste variabili, allora la x generata dovrebbe corrispondere alla distribuzione dei dati Pdata(x). Ora abbiamo due domande a cui dobbiamo rispondere. Come catturare la distribuzione delle variabili latenti e come integrare l’equazione 1 su tutte le dimensioni di z?
Ovviamente è un compito noioso specificare manualmente le informazioni rilevanti che vorremmo codificare nel vettore latente per generare l’immagine di uscita. Piuttosto ci affidiamo alle reti neurali per calcolare z solo con l’assunzione che questo vettore latente possa essere ben approssimato come una distribuzione normale in modo da campionare facilmente al momento dell’inferenza. Se abbiamo una distribuzione normale di z in uno spazio n dimensionale, allora è sempre possibile generare qualsiasi tipo di distribuzione usando una funzione sufficientemente complicata e l’inverso di questa funzione può essere usato per imparare le variabili latenti stesse.
Nell’equazione 1, l’integrazione viene effettuata su tutte le dimensioni di z ed è quindi intrattabile. Tuttavia, può essere calcolata usando metodi di integrazione Monte-Carlo che è qualcosa di non facile da implementare. Quindi seguiamo un altro approccio per massimizzare approssimativamente Pө(X) nell’equazione 1. L’idea di VAE è di dedurre P(z) usando P(z|X) che non conosciamo. Noi deduciamo P(z|X) usando un metodo chiamato inferenza variazionale che è fondamentalmente un problema di ottimizzazione nella statistica bayesiana. Prima modelliamo P(z|X) usando una distribuzione più semplice Q(z|X) che è facile da trovare e cerchiamo di minimizzare la differenza tra P(z|X) e Q(z|X) usando l’approccio della metrica KL-divergenza in modo che la nostra ipotesi sia vicina alla distribuzione vera. Questo è seguito da un sacco di equazioni matematiche che non spiegherò qui ma che potete trovare nel documento originale. Ma devo dire che queste equazioni non sono molto difficili da capire una volta che si ottiene l’intuizione dietro VAE.