Cos'è un Autoencoder?
Un Autoencoder è uno strumento per apprendere la codifica dei dati in modo efficiente e senza supervisione. È un tipo di rete neurale artificiale che consente di apprendere la rappresentazione di set di dati per la riduzione della dimensionalità addestrando la rete neurale a ignorare il rumore del segnale. È un ottimo strumento per ricreare un input.
In parole semplici, la macchina prende, diciamo, un'immagine e può produrre un'immagine strettamente correlata. L'input in questo tipo di rete neurale non è etichettato, il che significa che la rete è in grado di apprendere senza supervisione. Più precisamente, l'input è codificato dalla rete per concentrarsi solo sulla caratteristica più critica. Questo è uno dei motivi per cui l'autoencoder è popolare per la riduzione della dimensionalità. Inoltre, gli autoencoder possono essere utilizzati per produrre modelli di apprendimento generativo . Ad esempio, la rete neurale può essere addestrata con una serie di volti e quindi può produrre nuovi volti.
In questo tutorial di TensorFlow Autoencoder imparerai:
- Cos'è un Autoencoder?
- Come funziona Autoencoder?
- Esempio di codificatore automatico impilato
- Crea un Autoencoder con TensorFlow
- Pre-elaborazione delle immagini
- Imposta stima set di dati
- Costruisci la rete
Come funziona Autoencoder?
Lo scopo di un autoencoder è quello di produrre un'approssimazione dell'input concentrandosi solo sulle caratteristiche essenziali. Potresti pensare perché non imparare semplicemente a copiare e incollare l'input per produrre l'output. In effetti, un autoencoder è un insieme di vincoli che costringono la rete ad apprendere nuovi modi per rappresentare i dati, diversi dalla semplice copia dell'output.
Un tipico autoencoder è definito con un input, una rappresentazione interna e un output (un'approssimazione dell'input). L'apprendimento avviene negli strati attaccati alla rappresentazione interna. In effetti, ci sono due blocchi principali di livelli che assomigliano a una rete neurale tradizionale. La leggera differenza è che il livello contenente l'output deve essere uguale all'input. Nella figura sotto, l'ingresso originale va nel primo blocco chiamato encoder . Questa rappresentazione interna comprime (riduce) la dimensione dell'input. Nel secondo blocco avviene la ricostruzione dell'ingresso. Questa è la fase di decodifica.

Funzionamento di Autoencoder
Il modello aggiornerà i pesi riducendo al minimo la funzione di perdita. Il modello è penalizzato se l'output della ricostruzione è diverso dall'input.
In concreto, immagina un'immagine con una dimensione di 50x50 (cioè 250 pixel) e una rete neurale con un solo strato nascosto composto da cento neuroni. L'apprendimento viene eseguito su una mappa delle caratteristiche che è due volte più piccola dell'input. Significa che la rete deve trovare un modo per ricostruire 250 pixel con un solo vettore di neuroni uguale a 100.
Esempio di codificatore automatico impilato
In questo tutorial sull'Autoencoder, imparerai come utilizzare un autoencoder in pila. L'architettura è simile a una rete neurale tradizionale. L'input va a un livello nascosto per essere compresso, o ridurne le dimensioni, e quindi raggiunge i livelli di ricostruzione. L'obiettivo è produrre un'immagine in uscita il più vicino possibile all'originale. Il modello deve imparare un modo per svolgere il suo compito sotto una serie di vincoli, cioè con una dimensione inferiore.
Al giorno d'oggi, gli Autoencoder in Deep Learning vengono utilizzati principalmente per il denoising di un'immagine. Immagina un'immagine con graffi; un essere umano è ancora in grado di riconoscere il contenuto. L'idea del denoising dell'autoencoder è di aggiungere rumore all'immagine per forzare la rete ad apprendere lo schema dietro i dati.
L'altra famiglia utile di Autoencoder Deep Learning è l'autoencoder variazionale. Questo tipo di rete può generare nuove immagini. Immagina di addestrare una rete con l'immagine di un uomo; una rete del genere può produrre volti nuovi.
Crea un Autoencoder con TensorFlow
In questo tutorial imparerai come costruire un autoencoder in pila per ricostruire un'immagine.
Utilizzerai il set di dati CIFAR-10 che contiene 60000 immagini a colori 32x32. Il set di dati Autoencoder è già suddiviso tra 50000 immagini per l'addestramento e 10000 per il test. Ci sono fino a dieci classi:
- Aereo
- Automobile
- Uccello
- Gatto
- Cervo
- Cane
- Rana
- Cavallo
- Nave
- Camion
È necessario scaricare le immagini in questo URL https://www.cs.toronto.edu/~kriz/cifar.html e decomprimerlo. La cartella per-10-batches-py contiene cinque batch di dati con 10000 immagini ciascuno in ordine casuale.
Prima di costruire e addestrare il tuo modello, devi applicare un po 'di elaborazione dei dati. Procedi come segue:
- Importa i dati
- Converti i dati in formato bianco e nero
- Aggiungi tutti i batch
- Costruisci il set di dati di addestramento
- Costruisci un visualizzatore di immagini
Pre-elaborazione delle immagini
Passaggio 1) Importa i dati.
Secondo il sito web ufficiale, puoi caricare i dati con il seguente codice. Il codice Autoencoder caricherà i dati in un dizionario con i dati e l' etichetta . Nota che il codice è una funzione.
import numpy as npimport tensorflow as tfimport pickledef unpickle(file):import picklewith open(file, 'rb') as fo:dict = pickle.load(fo, encoding='latin1')return dict
Passaggio 2) Converti i dati in formato bianco e nero
Per semplicità, convertirai i dati in una scala di grigi. Cioè, con una sola dimensione contro tre per l'immagine a colori. La maggior parte della rete neurale funziona solo con un input di dimensione.
def grayscale(im):return im.reshape(im.shape[0], 3, 32, 32).mean(1).reshape(im.shape[0], -1)
Passaggio 3) Aggiungi tutti i batch
Ora che entrambe le funzioni sono state create e il set di dati caricato, è possibile scrivere un ciclo per aggiungere i dati in memoria. Se controlli attentamente, il file di decompressione con i dati si chiama data_batch_ con un numero da 1 a 5. Puoi scorrere i file e aggiungerlo ai dati.
Al termine di questo passaggio, converti i dati sui colori in un formato in scala di grigi. Come puoi vedere, la forma dei dati è 50000 e 1024. I 32 * 32 pixel sono ora appiattiti al 2014.
# Load the data into memorydata, labels = [], []## Loop over the bfor i in range(1, 6):filename = './cifar-10-batches-py/data_batch_' + str(i)open_data = unpickle(filename)if len(data)> 0:data = np.vstack((data, open_data['data']))labels = np.hstack((labels, open_data['labels']))else:data = open_data['data']labels = open_data['labels']data = grayscale(data)x = np.matrix(data)y = np.array(labels)print(x.shape)(50000, 1024)
Nota: cambia "./cifar-10-batches-py/data_batch_" nella posizione effettiva del tuo file. Ad esempio per la macchina Windows, il percorso potrebbe essere filename = 'E: \ cifar-10-batches-py \ data_batch_' + str (i)
Passaggio 4) Costruisci il set di dati di addestramento
Per rendere l'allenamento più veloce e più facile, addestrerai un modello solo sulle immagini del cavallo. I cavalli sono la settima classe nei dati dell'etichetta. Come menzionato nella documentazione del set di dati CIFAR-10, ogni classe contiene 5000 immagini. È possibile stampare la forma dei dati per confermare che ci sono 5.000 immagini con 1024 colonne come mostrato nel passaggio di esempio di TensorFlow Autoencoder di seguito.
horse_i = np.where(y == 7)[0]horse_x = x[horse_i]print(np.shape(horse_x))(5000, 1024)
Passaggio 5) Costruisci un visualizzatore di immagini
Infine, costruisci una funzione per tracciare le immagini. Questa funzione sarà necessaria per stampare l'immagine ricostruita dall'autoencoder.
Un modo semplice per stampare le immagini è usare l'oggetto imshow dalla libreria matplotlib. Si noti che è necessario convertire la forma dei dati da 1024 a 32 * 32 (ovvero il formato di un'immagine).
# To plot pretty figures%matplotlib inlineimport matplotlibimport matplotlib.pyplot as pltdef plot_image(image, shape=[32, 32], cmap = "Greys_r"):plt.imshow(image.reshape(shape), cmap=cmap,interpolation="nearest")plt.axis("off")
La funzione accetta 3 argomenti:
- Immagine: l'ingresso
- Forma: elenco, la dimensione dell'immagine
- Cmap: scegli la mappa dei colori. Per impostazione predefinita, grigio
Puoi provare a tracciare la prima immagine nel set di dati. Dovresti vedere un uomo a cavallo.
plot_image(horse_x[1], shape=[32, 32], cmap = "Greys_r")
Imposta stima set di dati
Bene, ora che il set di dati è pronto per l'uso, puoi iniziare a utilizzare Tensorflow. Prima di costruire il modello, usiamo lo stimatore Dataset di Tensorflow per alimentare la rete.
Costruirai un set di dati con lo stimatore TensorFlow. Per rinfrescarti la mente, devi usare:
- from_tensor_slices
- ripetere
- lotto
Il codice completo per creare il set di dati è:
dataset = tf.data.Dataset.from_tensor_slices(x).repeat().batch(batch_size)
Tieni presente che x è un segnaposto con la seguente forma:
- [Nessuno, n_inputs]: impostare su Nessuno perché il numero di feed di immagini alla rete è uguale alla dimensione del batch.
per i dettagli, fare riferimento al tutorial sulla regressione lineare.
Dopodiché, devi creare l'iteratore. Senza questa riga di codice, nessun dato passerà attraverso la pipeline.
iter = dataset.make_initializable_iterator() # create the iteratorfeatures = iter.get_next()
Ora che la pipeline è pronta, puoi controllare se la prima immagine è la stessa di prima (cioè, un uomo a cavallo).
Si imposta la dimensione del batch su 1 perché si desidera alimentare il set di dati solo con un'immagine. Puoi vedere la dimensione dei dati con print (sess.run (features) .shape). È uguale a (1, 1024). 1 significa che solo un'immagine con 1024 è alimentata ciascuna. Se la dimensione del batch è impostata su due, due immagini passeranno attraverso la pipeline. (Non modificare la dimensione del batch. Altrimenti, verrà generato un errore. Solo un'immagine alla volta può andare alla funzione plot_image ().
## Parametersn_inputs = 32 * 32BATCH_SIZE = 1batch_size = tf.placeholder(tf.int64)# using a placeholderx = tf.placeholder(tf.float32, shape=[None,n_inputs])## Datasetdataset = tf.data.Dataset.from_tensor_slices(x).repeat().batch(batch_size)iter = dataset.make_initializable_iterator() # create the iteratorfeatures = iter.get_next()## Print the imagewith tf.Session() as sess:# feed the placeholder with datasess.run(iter.initializer, feed_dict={x: horse_x,batch_size: BATCH_SIZE})print(sess.run(features).shape)plot_image(sess.run(features), shape=[32, 32], cmap = "Greys_r")(1, 1024)
Costruisci la rete
È ora di costruire la rete. Addestrerai un autoencoder in pila, ovvero una rete con più livelli nascosti.
La tua rete avrà uno strato di input con 1024 punti, cioè 32x32, la forma dell'immagine.
Il blocco codificatore avrà uno strato nascosto superiore con 300 neuroni, uno strato centrale con 150 neuroni. Il blocco decoder è simmetrico all'encoder. Puoi visualizzare la rete nell'immagine sottostante. Tieni presente che puoi modificare i valori dei livelli nascosti e centrali.

Costruire la rete per Autoencoder
La creazione di un autoencoder è molto simile a qualsiasi altro modello di deep learning.
Costruirai il modello seguendo questi passaggi:
- Definisci i parametri
- Definisci i livelli
- Definisci l'architettura
- Definisci l'ottimizzazione
- Esegui il modello
- Valuta il modello
Nella sezione precedente si è appreso come creare una pipeline per alimentare il modello, quindi non è necessario creare nuovamente il set di dati. Costruirai un autoencoder con quattro livelli. Usi l'inizializzazione di Xavier. Questa è una tecnica per impostare i pesi iniziali uguali alla varianza sia dell'input che dell'output. Infine, si utilizza la funzione di attivazione elu. Regolarizzi la funzione di perdita con il regolarizzatore L2.
Passaggio 1) Definire i parametri
Il primo passo implica definire il numero di neuroni in ogni strato, il tasso di apprendimento e l'iperparametro del regolarizzatore.
Prima di ciò, importi parzialmente la funzione. È un metodo migliore per definire i parametri degli strati densi. Il codice seguente definisce i valori dell'architettura dell'autoencoder. Come elencato prima, l'autoencoder ha due livelli, con 300 neuroni nei primi livelli e 150 nei secondi. I loro valori sono memorizzati in n_hidden_1 e n_hidden_2.
È necessario definire la velocità di apprendimento e l'iperparametro L2. I valori vengono memorizzati in learning_rate e l2_reg
from functools import partial## Encodern_hidden_1 = 300n_hidden_2 = 150 # codings## Decodern_hidden_3 = n_hidden_1n_outputs = n_inputslearning_rate = 0.01l2_reg = 0.0001
La tecnica di inizializzazione di Xavier viene chiamata con l'oggetto xavier_initializer dallo stimatore contrib. Nello stesso stimatore, puoi aggiungere il regolarizzatore con l2_regularizer
## Define the Xavier initializationxav_init = tf.contrib.layers.xavier_initializer()## Define the L2 regularizerl2_regularizer = tf.contrib.layers.l2_regularizer(l2_reg)
Passaggio 2) Definisci i livelli
Tutti i parametri degli strati densi sono stati impostati; puoi impacchettare tutto nella variabile dense_layer usando l'oggetto partial. dense_layer che utilizza l'attivazione ELU, l'inizializzazione Xavier e la regolarizzazione L2.
## Create the dense layerdense_layer = partial(tf.layers.dense,activation=tf.nn.elu,kernel_initializer=xav_init,kernel_regularizer=l2_regularizer)
Passaggio 3) Definisci l'architettura
Se guardi l'immagine dell'architettura, noti che la rete impila tre livelli con un livello di output. Nel codice seguente, connetti i livelli appropriati. Ad esempio, il primo livello calcola il prodotto scalare tra le caratteristiche della matrice di input e le matrici contenenti i 300 pesi. Dopo aver calcolato il prodotto scalare, l'output passa alla funzione di attivazione Elu. L'output diventa l'input del livello successivo, ecco perché lo usi per calcolare hidden_2 e così via. Le moltiplicazioni delle matrici sono le stesse per ogni strato perché si utilizza la stessa funzione di attivazione. Notare che l'ultimo livello, uscite, non applica una funzione di attivazione. Ha senso perché questo è l'input ricostruito
## Make the mat mulhidden_1 = dense_layer(features, n_hidden_1)hidden_2 = dense_layer(hidden_1, n_hidden_2)hidden_3 = dense_layer(hidden_2, n_hidden_3)outputs = dense_layer(hidden_3, n_outputs, activation=None)
Passaggio 4) Definisci l'ottimizzazione
L'ultimo passaggio è costruire l'ottimizzatore. Si utilizza l'errore quadratico medio come funzione di perdita. Se ricordi il tutorial sulla regressione lineare, sai che l'MSE viene calcolato con la differenza tra l'output previsto e l'etichetta reale. Qui, l'etichetta è la caratteristica perché il modello cerca di ricostruire l'input. Pertanto, si desidera la media della somma della differenza del quadrato tra l'output e l'input previsti. Con TensorFlow, puoi codificare la funzione di perdita come segue:
loss = tf.reduce_mean(tf.square(outputs - features))
Quindi, è necessario ottimizzare la funzione di perdita. Utilizzi Adam Optimizer per calcolare i gradienti. La funzione obiettivo è ridurre al minimo la perdita.
## Optimizeloss = tf.reduce_mean(tf.square(outputs - features))optimizer = tf.train.AdamOptimizer(learning_rate)train = optimizer.minimize(loss)
Un'altra impostazione prima di addestrare il modello. Si desidera utilizzare una dimensione batch di 150, ovvero alimentare la pipeline con 150 immagini per ogni iterazione. È necessario calcolare manualmente il numero di iterazioni. Questo è banale da fare:
Se vuoi passare 150 immagini ogni volta e sai che ci sono 5000 immagini nel set di dati, il numero di iterazioni è uguale a. In python puoi eseguire i seguenti codici e assicurarti che l'output sia 33:
BATCH_SIZE = 150### Number of batches : length dataset / batch sizen_batches = horse_x.shape[0] // BATCH_SIZEprint(n_batches)33
Passaggio 5) Esegui il modello
Ultimo ma non meno importante, allena il modello. Stai addestrando il modello con 100 epoche. Cioè, il modello vedrà 100 volte le immagini a pesi ottimizzati.
Hai già familiarità con i codici per addestrare un modello in Tensorflow. La leggera differenza consiste nel reindirizzare i dati prima di eseguire l'addestramento. In questo modo, il modello si allena più velocemente.
Sei interessato a stampare la perdita dopo dieci epoche per vedere se il modello sta imparando qualcosa (cioè, la perdita sta diminuendo). La formazione richiede da 2 a 5 minuti, a seconda dell'hardware della macchina.
## Set paramsn_epochs = 100## Call Saver to save the model and re-use it later during evaluationsaver = tf.train.Saver()with tf.Session() as sess:sess.run(tf.global_variables_initializer())# initialise iterator with train datasess.run(iter.initializer, feed_dict={x: horse_x,batch_size: BATCH_SIZE})print('Training… ')print(sess.run(features).shape)for epoch in range(n_epochs):for iteration in range(n_batches):sess.run(train)if epoch % 10 == 0:loss_train = loss.eval() # not shownprint("\r{}".format(epoch), "Train MSE:", loss_train)#saver.save(sess, "./my_model_all_layers.ckpt")save_path = saver.save(sess, "./model.ckpt")print("Model saved in path: %s" % save_path)Training… (150, 1024)0 Train MSE: 2934.45510 Train MSE: 1672.67620 Train MSE: 1514.70930 Train MSE: 1404.311840 Train MSE: 1425.05850 Train MSE: 1479.063160 Train MSE: 1609.525970 Train MSE: 1482.322380 Train MSE: 1445.703590 Train MSE: 1453.8597Model saved in path: ./model.ckpt
Passaggio 6) Valuta il modello
Ora che hai addestrato il tuo modello, è il momento di valutarlo. Devi importare il test sert dal file / cifar-10-batches-py /.
test_data = unpickle('./cifar-10-batches-py/test_batch')test_x = grayscale(test_data['data'])#test_labels = np.array(test_data['labels'])
NOTA: per una macchina Windows, il codice diventa test_data = unpickle (r "E: \ cifar-10-batches-py \ test_batch")
Puoi provare a stampare le immagini 13, che è un cavallo
plot_image(test_x[13], shape=[32, 32], cmap = "Greys_r")
Per valutare il modello, utilizzerai il valore in pixel di questa immagine e vedrai se il codificatore è in grado di ricostruire la stessa immagine dopo aver ridotto 1024 pixel. Si noti che si definisce una funzione per valutare il modello su immagini diverse. Il modello dovrebbe funzionare meglio solo sui cavalli.
La funzione accetta due argomenti:
- df: importa i dati del test
- numero_immagine: indica quale immagine importare
La funzione è divisa in tre parti:
- Rimodella l'immagine alla dimensione corretta, ad esempio 1, 1024
- Alimenta il modello con l'immagine invisibile, codifica / decodifica l'immagine
- Stampa l'immagine reale e ricostruita
def reconstruct_image(df, image_number = 1):## Part 1: Reshape the image to the correct dimension i.e 1, 1024x_test = df[image_number]x_test_1 = x_test.reshape((1, 32*32))## Part 2: Feed the model with the unseen image, encode/decode the imagewith tf.Session() as sess:sess.run(tf.global_variables_initializer())sess.run(iter.initializer, feed_dict={x: x_test_1,batch_size: 1})## Part 3: Print the real and reconstructed image# Restore variables from disk.saver.restore(sess, "./model.ckpt")print("Model restored.")# Reconstruct imageoutputs_val = outputs.eval()print(outputs_val.shape)fig = plt.figure()# Plot realax1 = fig.add_subplot(121)plot_image(x_test_1, shape=[32, 32], cmap = "Greys_r")# Plot estimatedax2 = fig.add_subplot(122)plot_image(outputs_val, shape=[32, 32], cmap = "Greys_r")plt.tight_layout()fig = plt.gcf()
Ora che la funzione di valutazione è definita, puoi dare un'occhiata all'immagine numero tredici ricostruita
reconstruct_image(df =test_x, image_number = 13)
INFO:tensorflow:Restoring parameters from ./model.ckptModel restored.(1, 1024)
Sommario
Lo scopo principale di un autoencoder è comprimere i dati di input e quindi decomprimerli in un output che assomigli molto ai dati originali.
L'architettura di un autoencoder simmetrico con uno strato pivot denominato layer centrale.
Puoi creare l'autoencoder usando:
- Parziale: per creare gli strati densi con l'impostazione tipica:
-
tf.layers.dense,activation=tf.nn.elu,kernel_initializer=xav_init,kernel_regularizer=l2_regularizer
- dense_layer (): per fare la moltiplicazione della matrice
puoi definire la funzione di perdita e l'ottimizzazione con:
loss = tf.reduce_mean(tf.square(outputs - features))optimizer = tf.train.AdamOptimizer(learning_rate)train = optimizer.minimize(loss)
Ultima esecuzione di una sessione per addestrare il modello.