Autoencoder in TensorFlow met voorbeeld

Wat is Autoencoder in Deep Learning?

An Auto-encoder is een hulpmiddel om gegevenscodering efficiënt en zonder toezicht te leren. Het is een soort kunstmatig neuraal netwerk dat u helpt de representatie van datasets te leren voor dimensionaliteitsreductie door het neurale netwerk te trainen om de signaalruis te negeren. Het is een geweldig hulpmiddel voor het opnieuw creëren van een invoer.

In eenvoudige bewoordingen: de machine neemt, laten we zeggen, een afbeelding en kan een nauw verwante afbeelding produceren. De input in dit soort neurale netwerken is ongelabeld, wat betekent dat het netwerk zonder toezicht kan leren. Om precies te zijn: de invoer wordt door het netwerk gecodeerd om zich alleen op de meest kritische functie te concentreren. Dit is een van de redenen waarom autoencoder populair is voor dimensionaliteitsreductie. Bovendien kunnen autoencoders worden gebruikt om te produceren generatieve leermodellen. Het neurale netwerk kan bijvoorbeeld worden getraind met een reeks gezichten en vervolgens nieuwe gezichten produceren.

Hoe werkt TensorFlow Autoencoder?

Het doel van een autoencoder is om een ​​benadering van de invoer te produceren door zich alleen op de essentiële kenmerken te concentreren. Je denkt misschien waarom je niet alleen leert hoe je de invoer kunt kopiëren en plakken om de uitvoer te produceren. In feite is een autoencoder een reeks beperkingen die het netwerk dwingen nieuwe manieren te leren om de gegevens weer te geven, anders dan alleen het kopiëren van de uitvoer.

Een typische autoencoder wordt gedefinieerd met een invoer, een interne representatie en een uitvoer (een benadering van de invoer). Het leren vindt plaats in de lagen die aan de interne representatie zijn verbonden. In feite zijn er twee hoofdblokken met lagen die op een traditioneel neuraal netwerk lijken. Het kleine verschil is dat de laag die de uitvoer bevat gelijk moet zijn aan de invoer. In de onderstaande afbeelding gaat de originele invoer naar het eerste blok dat de encoder. Deze interne representatie comprimeert (verkleint) de omvang van de invoer. In het tweede blok vindt de reconstructie van de invoer plaats. Dit is de decodeerfase.

Werking van Autoencoder
Werking van Autoencoder

Werking van Autoencoder

Het model zal de gewichten bijwerken door de verliesfunctie te minimaliseren. Het model wordt bestraft als de reconstructie-output verschilt van de input.

Stel je concreet een afbeelding voor met een formaat van 50×50 (dwz 250 pixels) en een neuraal netwerk met slechts één verborgen laag bestaande uit honderd neuronen. Het leren gebeurt op een feature map die twee keer kleiner is dan de invoer. Het betekent dat het netwerk een manier moet vinden om 250 pixels te reconstrueren met slechts een vector van neuronen gelijk aan 100.

Gestapeld Autoencoder-voorbeeld

In deze Autoencoder-zelfstudie leert u hoe u een gestapelde autoencoder gebruikt. De architectuur is vergelijkbaar met een traditioneel neuraal netwerk. De invoer gaat naar een verborgen laag om te worden gecomprimeerd of de grootte ervan te verkleinen en bereikt vervolgens de reconstructielagen. Het doel is om een ​​uitvoerafbeelding te produceren die zo dicht mogelijk bij het origineel ligt. Het model moet een manier leren om zijn taak te bereiken onder een reeks beperkingen, dat wil zeggen met een lagere dimensie.

Tegenwoordig zijn er auto-encoders in Diepe leren worden voornamelijk gebruikt om ruis in een afbeelding te verwijderen. Stel je een afbeelding voor met krassen; een mens kan de inhoud nog steeds herkennen. Het idee van het ontruisen van autoencoder is om ruis aan het beeld toe te voegen om het netwerk te dwingen het patroon achter de gegevens te leren kennen.

De andere nuttige familie van Autoencoder Deep Learning is de variabele autoencoder. Dit type netwerk kan nieuwe beelden genereren. Stel je voor dat je een netwerk traint met het beeld van een man; zo'n netwerk kan nieuwe gezichten opleveren.

Hoe u een auto-encoder bouwt met TensorFlow

In deze zelfstudie leert u hoe u een gestapelde autoencoder bouwt om een ​​afbeelding te reconstrueren.

Je gebruikt de CIFAR-10-gegevensset die 60000 32×32 kleurenafbeeldingen bevat. De Autoencoder-dataset is al verdeeld over 50000 afbeeldingen voor training en 10000 voor testen. Er zijn maximaal tien klassen:

  • Vliegtuig
  • Automobile
  • Vogel
  • Kat
  • Hert
  • Hond
  • Kikker
  • Paard
  • Verzenden
  • Vrachtwagen

U moet de afbeeldingen in deze URL https://www.cs.toronto.edu/~kriz/cifar.html downloaden en uitpakken. De map for-10-batches-py bevat vijf batches met gegevens met elk 10000 afbeeldingen in willekeurige volgorde.

Voordat u uw model bouwt en traint, moet u enige gegevensverwerking toepassen. U gaat als volgt te werk:

  1. Importeer de gegevens
  2. Converteer de gegevens naar zwart-witformaat
  3. Voeg alle batches toe
  4. Construeer de trainingsgegevensset
  5. Bouw een beeldvisualizer

Voorbewerking van afbeeldingen

Stap 1) Importeer de gegevens

Volgens de officiële website kunt u de gegevens uploaden met de volgende code. De Autoencoder-code laadt de gegevens in een woordenboek met de gegevens en label. Merk op dat de code een functie is.

import numpy as np
import tensorflow as tf
import pickle
def unpickle(file):
    import pickle
    with open(file, 'rb') as fo:
        dict = pickle.load(fo, encoding='latin1')
    return dict

Stap 2) Converteer de gegevens naar zwart-witformaat

Voor de eenvoud converteert u de gegevens naar grijswaarden. Dat wil zeggen, met slechts één dimensie tegen drie voor het kleurenbeeld. Het grootste deel van het neurale netwerk werkt alleen met invoer uit één dimensie.

def grayscale(im):
    return im.reshape(im.shape[0], 3, 32, 32).mean(1).reshape(im.shape[0], -1)

Stap 3) Voeg alle batches toe

Nu beide functies zijn gemaakt en de dataset is geladen, kunt u een lus schrijven om de gegevens in het geheugen toe te voegen. Als je het zorgvuldig controleert, heet het uitgepakte bestand met de gegevens data_batch_ met een nummer van 1 tot 5. Je kunt de bestanden doorlopen en aan de gegevens toevoegen.

Wanneer deze stap is voltooid, converteert u de kleurgegevens naar een grijswaardenindeling. Zoals u kunt zien, is de vorm van de gegevens 50000 en 1024. De 32*32 pixels zijn nu afgevlakt naar 2014.

# Load the data into memory
data, labels = [], []
## Loop over the b
for 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)

Opmerking: Wijzig './cifar-10-batches-py/data_batch_' naar de daadwerkelijke locatie van uw bestand. Bijvoorbeeld voor Windows machine, kan het pad de bestandsnaam = 'E:\cifar-10-batches-py\data_batch_' + str(i) zijn

Stap 4) Construeer de trainingsgegevensset

Om de training sneller en gemakkelijker te maken, train je een model alleen op de paardenafbeeldingen. De paarden zijn de zevende klasse in de labelgegevens. Zoals vermeld in de documentatie van de CIFAR-10-dataset, bevat elke klasse 5000 afbeeldingen. U kunt de vorm van de gegevens afdrukken om te bevestigen dat er 5.000 afbeeldingen met 1024 kolommen zijn, zoals hieronder weergegeven TensorFlow Voorbeeldstap Autoencoder.

horse_i = np.where(y == 7)[0]
horse_x = x[horse_i]
print(np.shape(horse_x)) 
(5000, 1024)

Stap 5) Bouw een beeldvisualizer

Ten slotte construeert u een functie om de afbeeldingen te plotten. U hebt deze functie nodig om het gereconstrueerde beeld vanuit de autoencoder af te drukken.

Een gemakkelijke manier om afbeeldingen af ​​te drukken is door het object imshow uit de matplotlib-bibliotheek te gebruiken. Houd er rekening mee dat u de vorm van de gegevens moet converteren van 1024 naar 32*32 (dwz het formaat van een afbeelding).

# To plot pretty figures
%matplotlib inline
import matplotlib
import matplotlib.pyplot as plt
def plot_image(image, shape=[32, 32], cmap = "Greys_r"):
    plt.imshow(image.reshape(shape), cmap=cmap,interpolation="nearest")
    plt.axis("off")   

De functie heeft 3 argumenten nodig:

  • Beeld: de invoer
  • Vorm: lijst, de afmeting van de afbeelding
  • cmap: kies de kleurenkaart. Standaard grijs

U kunt proberen de eerste afbeelding in de gegevensset te plotten. Je zou een man op een paard moeten zien.

plot_image(horse_x[1], shape=[32, 32], cmap = "Greys_r")

Bouw een beeldvisualisator

Gegevenssetschatter instellen

Oké, nu de dataset klaar is voor gebruik, kun je Tensorflow gaan gebruiken. Voordat we het model bouwen, gebruiken we de Dataset-schatter van Tensorflow om het netwerk te voeden.

Je bouwt een dataset met de TensorFlow-schatter. Om je geest op te frissen, moet je het volgende gebruiken:

  • van_tensor_slices
  • herhaling
  • partij

De volledige code om de dataset te bouwen is:

dataset = tf.data.Dataset.from_tensor_slices(x).repeat().batch(batch_size)

Merk op dat x een tijdelijke aanduiding is met de volgende vorm:

  • [None,n_inputs]: Stel in op Geen omdat het aantal beeldfeeds naar het netwerk gelijk is aan de batchgrootte.

voor meer informatie, zie de tutorial op lineaire regressie.

Daarna moet u de iterator maken. Zonder deze regel code gaan er geen gegevens door de pijplijn.

iter = dataset.make_initializable_iterator() # create the iteratorfeatures = iter.get_next()

Nu de pijplijn gereed is, kunt u controleren of de eerste afbeelding hetzelfde is als voorheen (dwz een man op een paard).

U stelt de batchgrootte in op 1 omdat u de dataset alleen met één afbeelding wilt voeden. U kunt de dimensie van de gegevens zien met print(sess.run(features).shape). Deze is gelijk aan (1, 1024). 1 betekent dat er slechts één afbeelding met 1024 per afbeelding wordt gevoed. Als de batchgrootte is ingesteld op twee, gaan er twee afbeeldingen door de pijplijn. (Wijzig de batchgrootte niet. Anders wordt er een fout gegenereerd. Er kan slechts één afbeelding tegelijk naar de functie plot_image() gaan.)

## Parameters
n_inputs = 32 * 32
BATCH_SIZE = 1
batch_size = tf.placeholder(tf.int64)

# using a placeholder
x = tf.placeholder(tf.float32, shape=[None,n_inputs])
## Dataset
dataset = tf.data.Dataset.from_tensor_slices(x).repeat().batch(batch_size)
iter = dataset.make_initializable_iterator() # create the iterator
features = iter.get_next()

## Print the image
with tf.Session() as sess:
    # feed the placeholder with data
    sess.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)

Gegevenssetschatter instellen

Bouw het netwerk

Het is tijd om het netwerk aan te leggen. Je traint een gestapelde autoencoder, dat wil zeggen een netwerk met meerdere verborgen lagen.

Uw netwerk heeft één invoerlaag met 1024 punten, dat wil zeggen 32×32, de vorm van de afbeelding.

Het encoderblok zal één verborgen bovenste laag hebben met 300 neuronen, een centrale laag met 150 neuronen. Het decoderblok is symmetrisch ten opzichte van de encoder. U kunt het netwerk visualiseren in de onderstaande afbeelding. Merk op dat u de waarden van verborgen en centrale lagen kunt wijzigen.

Bouw het netwerk
Het bouwen van een netwerk voor Autoencoder

Het bouwen van een autoencoder lijkt sterk op elk ander deep learning-model.

U bouwt het model volgens de volgende stappen:

  1. Definieer de parameters
  2. Definieer de lagen
  3. Definieer de architectuur
  4. Definieer de optimalisatie
  5. Voer het model uit
  6. Evalueer het model

In de vorige sectie hebt u geleerd hoe u een pijplijn kunt maken om het model te voeden, zodat u de gegevensset niet opnieuw hoeft te maken. Je gaat een autoencoder bouwen met vier lagen. U gebruikt de Xavier-initialisatie. Dit is een techniek om de initiële gewichten gelijk te stellen aan de variantie van zowel de invoer als de uitvoer. Tenslotte maak je gebruik van de elu-activeringsfunctie. Je regulariseert de verliesfunctie met L2 regularizer.

Stap 1) Definieer de parameters

De eerste stap impliceert het definiëren van het aantal neuronen in elke laag, de leersnelheid en de hyperparameter van de regularizer.

Daarvoor importeert u de functie gedeeltelijk. Het is een betere methode om de parameters van de dichte lagen te definiëren. De onderstaande code definieert de waarden van de autoencoderarchitectuur. Zoals eerder vermeld, heeft de autoencoder twee lagen, met 300 neuronen in de eerste lagen en 150 in de tweede lagen. Hun waarden worden opgeslagen in n_hidden_1 en n_hidden_2.

U moet de leersnelheid en de L2-hyperparameter definiëren. De waarden worden opgeslagen in learning_rate en l2_reg

from functools import partial

## Encoder
n_hidden_1 = 300
n_hidden_2 = 150  # codings

## Decoder
n_hidden_3 = n_hidden_1
n_outputs = n_inputs

learning_rate = 0.01
l2_reg = 0.0001

De Xavier-initialisatietechniek wordt aangeroepen met het object xavier_initializer uit de schattercontrib. In dezelfde schatter kunt u de regularizer toevoegen met l2_regularizer

## Define the Xavier initialization
xav_init =  tf.contrib.layers.xavier_initializer()
## Define the L2 regularizer
l2_regularizer = tf.contrib.layers.l2_regularizer(l2_reg)

Stap 2) Definieer de lagen

Alle parameters van de dichte lagen zijn ingesteld; je kunt alles in de variabele density_layer inpakken door het object gedeeltelijk te gebruiken. density_layer die gebruik maakt van de ELU-activering, Xavier-initialisatie en L2-regularisatie.

## Create the dense layer
dense_layer = partial(tf.layers.dense,
                         activation=tf.nn.elu,
                         kernel_initializer=xav_init,
                         kernel_regularizer=l2_regularizer)

Stap 3) Definieer de architectuur

Als u naar de afbeelding van de architectuur kijkt, ziet u dat het netwerk drie lagen stapelt met een uitvoerlaag. In de onderstaande code verbindt u de juiste lagen. De eerste laag berekent bijvoorbeeld het dot-product tussen de invoermatrices en de matrices met de 300 gewichten. Nadat het dot-product is berekend, gaat de uitvoer naar de Elu-activeringsfunctie. De uitvoer wordt de invoer van de volgende laag, daarom gebruikt u deze om hidden_2 te berekenen, enzovoort. De matricesvermenigvuldiging is voor elke laag hetzelfde, omdat u dezelfde activeringsfunctie gebruikt. Merk op dat de laatste laag, uitvoer, geen activeringsfunctie toepast. Het is logisch, omdat dit de gereconstrueerde invoer is

## Make the mat mul
hidden_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)

Stap 4) Definieer de optimalisatie

De laatste stap is het bouwen van de optimizer. U gebruikt de Mean Square Error als verliesfunctie. Als u zich de tutorial over lineaire regressie herinnert, weet u dat de MSE wordt berekend op basis van het verschil tussen de voorspelde output en het echte label. Hier is het label het kenmerk omdat het model de invoer probeert te reconstrueren. Daarom wilt u het gemiddelde van de som van het verschil in het kwadraat tussen de voorspelde uitvoer en invoer. Met TensorFlow kunt u de verliesfunctie als volgt coderen:

loss = tf.reduce_mean(tf.square(outputs - features))

Vervolgens moet u de verliesfunctie optimaliseren. U gebruikt Adam Optimizer om de gradiënten te berekenen. De objectieve functie is het minimaliseren van het verlies.

## Optimize
loss = tf.reduce_mean(tf.square(outputs - features))
optimizer = tf.train.AdamOptimizer(learning_rate)
train  = optimizer.minimize(loss)

Nog één instelling voordat u het model traint. U wilt een batchgrootte van 150 gebruiken, dat wil zeggen dat u de pijplijn elke iteratie met 150 afbeeldingen voedt. U moet het aantal iteraties handmatig berekenen. Dit is triviaal om te doen:

Als u elke keer 150 afbeeldingen wilt doorgeven en u weet dat er 5000 afbeeldingen in de dataset zitten, is het aantal iteraties gelijk aan . In Python kunt u de volgende codes uitvoeren en ervoor zorgen dat de uitvoer 33 is:

BATCH_SIZE = 150
### Number of batches :  length dataset / batch size
n_batches = horse_x.shape[0] // BATCH_SIZE
print(n_batches)
33

Stap 5) Voer het model uit

Tenslotte, maar daarom niet minder belangrijk, train het model. Je traint het model met 100 tijdperken. Dat wil zeggen dat het model 100 keer de afbeeldingen zal zien met geoptimaliseerde gewichten.

Je bent al bekend met de codes om een ​​model te trainen in Tensorflow. Het kleine verschil is dat de gegevens worden doorgesluisd voordat de training wordt uitgevoerd. Op deze manier traint het model sneller.

U bent geïnteresseerd in het afdrukken van het verlies na tien tijdperken om te zien of het model iets leert (dat wil zeggen: het verlies neemt af). De training duurt 2 tot 5 minuten, afhankelijk van de hardware van uw machine.

## Set params
n_epochs = 100

## Call Saver to save the model and re-use it later during evaluation
saver = tf.train.Saver()

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    # initialise iterator with train data
    sess.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 shown
            print("\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.455
10 Train MSE: 1672.676
20 Train MSE: 1514.709
30 Train MSE: 1404.3118
40 Train MSE: 1425.058
50 Train MSE: 1479.0631
60 Train MSE: 1609.5259
70 Train MSE: 1482.3223
80 Train MSE: 1445.7035
90 Train MSE: 1453.8597
Model saved in path: ./model.ckpt

Stap 6) Evalueer het model

Nu u uw model hebt getraind, is het tijd om het te evalueren. U moet de testserie importeren uit het bestand /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'])

NOTITIE: Voor een Windows machine, de code wordt test_data = unpickle(r”E:\cifar-10-batches-py\test_batch”)

Je kunt proberen de afbeelding 13, dat is een paard, af te drukken

plot_image(test_x[13], shape=[32, 32], cmap = "Greys_r")

Evalueer het model

Om het model te evalueren, gebruikt u de pixelwaarde van deze afbeelding en kijkt u of de encoder dezelfde afbeelding kan reconstrueren na het verkleinen van 1024 pixels. Houd er rekening mee dat u een functie definieert om het model op verschillende afbeeldingen te evalueren. Het model zou alleen beter moeten werken bij paarden.

De functie heeft twee argumenten nodig:

  • df: Importeer de testgegevens
  • afbeelding_nummer: geef aan welke afbeelding u wilt importeren

De functie is verdeeld in drie delen:

  1. Geef de afbeelding een nieuwe vorm naar de juiste afmeting, bijvoorbeeld 1, 1024
  2. Voed het model met de onzichtbare afbeelding, codeer/decodeer de afbeelding
  3. Druk de echte en gereconstrueerde afbeelding af
def reconstruct_image(df, image_number = 1):
    ## Part 1: Reshape the image to the correct dimension i.e 1, 1024
    x_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 image
    with 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 image
        outputs_val = outputs.eval()
        print(outputs_val.shape)
        fig = plt.figure()
      # Plot real
        ax1 = fig.add_subplot(121)
        plot_image(x_test_1, shape=[32, 32], cmap = "Greys_r")
      # Plot estimated
        ax2 = fig.add_subplot(122)
        plot_image(outputs_val, shape=[32, 32], cmap = "Greys_r")
        plt.tight_layout()
        fig = plt.gcf()

Nu de evaluatiefunctie is gedefinieerd, kunt u de gereconstrueerde afbeelding nummer dertien bekijken

reconstruct_image(df =test_x, image_number = 13)
INFO:tensorflow:Restoring parameters from ./model.ckpt
Model restored.
(1, 1024)

Evalueer het model

Samenvatting

  • Het primaire doel van een autoencoder is om de invoergegevens te comprimeren en deze vervolgens te decomprimeren tot een uitvoer die sterk op de originele gegevens lijkt.
  • De architectuur van een autoencoder is symmetrisch met een pivotlaag, de zogenaamde centrale laag.
  • U kunt de autoencoder maken met behulp van:
  • Partieel: om de dichte lagen te creëren met de typische instelling:

      	tf.layers.dense,                         
      	activation=tf.nn.elu,                         
      	kernel_initializer=xav_init,                         
      	kernel_regularizer=l2_regularizer

    dichte_laag(): om de matrixvermenigvuldiging te maken

  • U kunt de verliesfunctie en optimalisatie definiëren met:
  • loss = tf.reduce_mean(tf.square(outputs - features))
    optimizer = tf.train.AdamOptimizer(learning_rate)
    train  = optimizer.minimize(loss)
    
  • Voer als laatste een sessie uit om het model te trainen.

Dagelijkse Guru99 Nieuwsbrief

Begin uw dag met het laatste en belangrijkste AI-nieuws, direct bezorgd.