Autoencoder i TensorFlow med eksempel
Hvad er Autoencoder i Deep Learning?
An Autoencoder er et værktøj til at lære datakodning effektivt på en uovervåget måde. Det er en type kunstigt neuralt netværk, der hjælper dig med at lære repræsentationen af datasæt til dimensionsreduktion ved at træne det neurale netværk til at ignorere signalstøjen. Det er et fantastisk værktøj til at genskabe et input.
Med enkle ord tager maskinen, lad os sige et billede, og kan producere et nært beslægtet billede. Inputtet i denne type neurale netværk er umærket, hvilket betyder, at netværket er i stand til at lære uden overvågning. Mere præcist kodes inputtet af netværket for kun at fokusere på den mest kritiske funktion. Dette er en af grundene til, at autoencoder er populær til dimensionsreduktion. Desuden kan autoencodere bruges til at producere generative læringsmodeller. For eksempel kan det neurale netværk trænes med et sæt ansigter og kan derefter producere nye ansigter.
Hvordan virker TensorFlow Autoencoder?
Formålet med en autoencoder er at producere en tilnærmelse af inputtet ved kun at fokusere på de væsentlige funktioner. Du tænker måske, hvorfor ikke bare lære at kopiere og indsætte input for at producere output. Faktisk er en autoencoder et sæt begrænsninger, der tvinger netværket til at lære nye måder at repræsentere data på, anderledes end blot at kopiere outputtet.
En typisk autoencoder er defineret med et input, en intern repræsentation og et output (en tilnærmelse af input). Læringen sker i de lag, der er knyttet til den indre repræsentation. Faktisk er der to hovedblokke af lag, der ligner et traditionelt neuralt netværk. Den lille forskel er, at laget, der indeholder outputtet, skal være lig med inputtet. På billedet nedenfor går det originale input ind i den første blok kaldet encoder. Denne interne repræsentation komprimerer (reducerer) størrelsen af input. I den anden blok sker rekonstruktionen af inputtet. Dette er afkodningsfasen.
Modellen vil opdatere vægtene ved at minimere tabsfunktionen. Modellen straffes, hvis rekonstruktionsoutputtet er forskelligt fra inputtet.
Forestil dig konkret et billede med en størrelse på 50×50 (dvs. 250 pixels) og et neuralt netværk med kun ét skjult lag bestående af hundrede neuroner. Indlæringen foregår på et feature map, som er to gange mindre end inputtet. Det betyder, at netværket skal finde en måde at rekonstruere 250 pixels med kun en vektor af neuroner svarende til 100.
Eksempel på stablet autoencoder
I denne autoencoder-vejledning lærer du, hvordan du bruger en stablet autoencoder. Arkitekturen ligner et traditionelt neuralt netværk. Inputtet går til et skjult lag for at blive komprimeret eller reducere dets størrelse og når derefter rekonstruktionslagene. Målet er at producere et outputbillede så tæt på som originalen. Modellen skal lære en måde at udføre sin opgave på under et sæt af begrænsninger, det vil sige med en lavere dimension.
I dag er autoencoders i Deep Learning bruges hovedsageligt til at forringe et billede. Forestil dig et billede med ridser; et menneske er stadig i stand til at genkende indholdet. Ideen med at denoising autoencoder er at tilføje støj til billedet for at tvinge netværket til at lære mønsteret bag dataene.
Den anden nyttige familie af Autoencoder Deep Learning er variationsautoencoder. Denne type netværk kan generere nye billeder. Forestil dig, at du træner et netværk med billedet af en mand; et sådant netværk kan producere nye ansigter.
Sådan bygger du en autoencoder med TensorFlow
I denne vejledning lærer du, hvordan du bygger en stablet autoencoder for at rekonstruere et billede.
Du vil bruge CIFAR-10 datasæt som indeholder 60000 32×32 farvebilleder. Autoencoder-datasættet er allerede delt mellem 50000 billeder til træning og 10000 til test. Der er op til ti klasser:
- Fly
- Automobile
- Bird
- Cat
- Deer
- Dog
- Frog
- hest
- Forsendelse
- lastbil
Du skal downloade billederne i denne URL https://www.cs.toronto.edu/~kriz/cifar.html og udpakke den. Mappen for-10-batches-py indeholder fem batches af data med 10000 billeder hver i en tilfældig rækkefølge.
Før du bygger og træner din model, skal du anvende noget databehandling. Du vil fortsætte som følger:
- Importer dataene
- Konverter dataene til sort/hvid-format
- Tilføj alle batches
- Konstruer træningsdatasættet
- Konstruer en billedvisualisering
Billedforbehandling
Trin 1) Importer dataene
Ifølge den officielle hjemmeside kan du uploade dataene med følgende kode. Autoencoder-koden vil indlæse dataene i en ordbog med data og label. Bemærk, at koden er en funktion.
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
Trin 2) Konverter dataene til sort/hvid-format
For nemheds skyld konverterer du dataene til en gråtoneskala. Det vil sige med kun én dimension mod tre for farver billede. Det meste af det neurale netværk fungerer kun med én dimensionsinput.
def grayscale(im): return im.reshape(im.shape[0], 3, 32, 32).mean(1).reshape(im.shape[0], -1)
Trin 3) Tilføj alle batches
Nu hvor begge funktioner er oprettet og datasættet indlæst, kan du skrive en loop for at tilføje dataene i hukommelsen. Hvis du tjekker omhyggeligt, hedder unzip-filen med dataene data_batch_ med et tal fra 1 til 5. Du kan loope over filerne og tilføje dem til data.
Når dette trin er udført, konverterer du farvedataene til et gråskalaformat. Som du kan se, er formen af dataene 50000 og 1024. De 32*32 pixels er nu fladt til 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)
Bemærk: Skift './cifar-10-batches-py/data_batch_' til den faktiske placering af din fil. For eksempel for Windows maskine, stien kunne være filnavn = 'E:\cifar-10-batches-py\data_batch_' + str(i)
Trin 4) Konstruer træningsdatasættet
For at gøre træningen hurtigere og nemmere, træner du kun en model på hestebillederne. Hestene er den syvende klasse i mærkedataene. Som nævnt i dokumentationen til CIFAR-10-datasættet, indeholder hver klasse 5000 billeder. Du kan udskrive formen på dataene for at bekræfte, at der er 5.000 billeder med 1024 kolonner som vist i nedenstående TensorFlow Autoencoder eksempel trin.
horse_i = np.where(y == 7)[0] horse_x = x[horse_i] print(np.shape(horse_x)) (5000, 1024)
Trin 5) Konstruer en billedvisualisering
Til sidst konstruerer du en funktion til at plotte billederne. Du skal bruge denne funktion for at udskrive det rekonstruerede billede fra autoencoderen.
En nem måde at udskrive billeder på er at bruge objektet imshow fra matplotlib-biblioteket. Bemærk, at du skal konvertere formen på dataene fra 1024 til 32*32 (dvs. formatet af et billede).
# 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")
Funktionen tager 3 argumenter:
- Billede: indgangen
- Shape: liste, billedets dimension
- cmap: vælg farvekortet. Som standard, grå
Du kan prøve at plotte det første billede i datasættet. Du burde se en mand på en hest.
plot_image(horse_x[1], shape=[32, 32], cmap = "Greys_r")
Indstil Datasæt Estimator
Okay, nu hvor datasættet er klar til brug, kan du begynde at bruge Tensorflow. Før vi bygger modellen, lad os bruge Dataset-estimatoren af Tensorflow til at fodre netværket.
Du vil bygge et datasæt med TensorFlow-estimator. For at genopfriske dit sind skal du bruge:
- from_tensor_slices
- gentag
- parti
Den fulde kode til at bygge datasættet er:
dataset = tf.data.Dataset.from_tensor_slices(x).repeat().batch(batch_size)
Bemærk, at x er en pladsholder med følgende form:
- [None,n_inputs]: Indstil til None, fordi antallet af billedfeed til netværket er lig med batchstørrelsen.
for detaljer, se venligst selvstudiet om lineær regression.
Derefter skal du oprette iteratoren. Uden denne kodelinje vil ingen data gå gennem pipelinen.
iter = dataset.make_initializable_iterator() # create the iteratorfeatures = iter.get_next()
Nu hvor pipelinen er klar, kan du kontrollere, om det første billede er det samme som før (dvs. en mand på en hest).
Du indstiller batchstørrelsen til 1, fordi du kun ønsker at fodre datasættet med ét billede. Du kan se dimensionen af dataene med print(sess.run(features).shape). Det er lig med (1, 1024). 1 betyder, at kun ét billede med 1024 er feed hver. Hvis batchstørrelsen er indstillet til to, vil to billeder gå gennem pipelinen. (Lad være med at ændre batchstørrelsen. Ellers vil det give en fejl. Kun ét billede ad gangen kan gå til funktionen plot_image().
## 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)
Byg netværket
Det er tid til at opbygge netværket. Du træner en stablet autoencoder, det vil sige et netværk med flere skjulte lag.
Dit netværk vil have ét inputlag med 1024 punkter, dvs. 32×32, billedets form.
Indkoderblokken vil have et øverste skjult lag med 300 neuroner, et centralt lag med 150 neuroner. Dekoderblokken er symmetrisk med indkoderen. Du kan visualisere netværket på billedet nedenfor. Bemærk, at du kan ændre værdierne for skjulte og centrale lag.
At bygge en autoencoder ligner meget enhver anden deep learning-model.
Du vil konstruere modellen ved at følge disse trin:
- Definer parametrene
- Definer lagene
- Definer arkitekturen
- Definer optimeringen
- Kør modellen
- Vurder modellen
I det forrige afsnit lærte du, hvordan du opretter en pipeline til at fodre modellen, så der er ingen grund til at oprette datasættet igen. Du vil konstruere en autoencoder med fire lag. Du bruger Xavier-initialiseringen. Dette er en teknik til at indstille startvægtene lig med variansen af både input og output. Til sidst bruger du elu-aktiveringsfunktionen. Du regulariserer tabsfunktionen med L2 regularizer.
Trin 1) Definer parametrene
Det første trin indebærer at definere antallet af neuroner i hvert lag, indlæringshastigheden og hyperparameteren for regularizeren.
Inden da importerer du funktionen delvist. Det er en bedre metode til at definere parametrene for de tætte lag. Koden nedenfor definerer værdierne for autoencoder-arkitekturen. Som nævnt før har autoencoderen to lag med 300 neuroner i det første lag og 150 i det andet lag. Deres værdier er gemt i n_hidden_1 og n_hidden_2.
Du skal definere indlæringshastigheden og L2-hyperparameteren. Værdierne gemmes i learning_rate og 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
Xavier initialiseringsteknikken kaldes med objektet xavier_initializer fra estimatorbidraget. I samme estimator kan du tilføje regularizeren med 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)
Trin 2) Definer lagene
Alle parametrene for de tætte lag er blevet indstillet; du kan pakke alt i variablen dense_layer ved at bruge objektet partial. dense_layer, som bruger ELU-aktivering, Xavier-initialisering og L2-regularisering.
## Create the dense layer dense_layer = partial(tf.layers.dense, activation=tf.nn.elu, kernel_initializer=xav_init, kernel_regularizer=l2_regularizer)
Trin 3) Definer arkitekturen
Hvis du ser på billedet af arkitekturen, bemærker du, at netværket stabler tre lag med et outputlag. I koden nedenfor forbinder du de relevante lag. For eksempel beregner det første lag prikproduktet mellem input-matricens funktioner og de matricer, der indeholder de 300 vægte. Efter at prikproduktet er beregnet, går outputtet til Elu-aktiveringsfunktionen. Outputtet bliver input til det næste lag, det er derfor du bruger det til at beregne hidden_2 og så videre. Matrixmultiplikationen er den samme for hvert lag, fordi du bruger den samme aktiveringsfunktion. Bemærk, at det sidste lag, output, ikke anvender en aktiveringsfunktion. Det giver mening, fordi dette er det rekonstruerede input
## 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)
Trin 4) Definer optimeringen
Det sidste trin er at konstruere optimizeren. Du bruger Mean Square Error som en tabsfunktion. Hvis du husker tutorialen om lineær regression, ved du, at MSE beregnes med forskellen mellem det forudsagte output og den reelle etiket. Her er etiketten funktionen, fordi modellen forsøger at rekonstruere inputtet. Derfor vil du have middelværdien af summen af forskellen af kvadratet mellem forudsagt output og input. Med TensorFlow kan du kode tabsfunktionen som følger:
loss = tf.reduce_mean(tf.square(outputs - features))
Derefter skal du optimere tabsfunktionen. Du bruger Adam optimizer til at beregne gradienterne. Den objektive funktion er at minimere tabet.
## Optimize loss = tf.reduce_mean(tf.square(outputs - features)) optimizer = tf.train.AdamOptimizer(learning_rate) train = optimizer.minimize(loss)
Endnu en indstilling før træning af modellen. Du vil bruge en batchstørrelse på 150, det vil sige at fodre pipelinen med 150 billeder hver iteration. Du skal beregne antallet af iterationer manuelt. Dette er trivielt at gøre:
Hvis du vil sende 150 billeder hver gang, og du ved, at der er 5000 billeder i datasættet, er antallet af iterationer lig med . I python kan du køre følgende koder og sørge for, at outputtet er 33:
BATCH_SIZE = 150 ### Number of batches : length dataset / batch size n_batches = horse_x.shape[0] // BATCH_SIZE print(n_batches) 33
Trin 5) Kør modellen
Sidst, men ikke mindst, træne modellen. Du træner modellen med 100 epoker. Det vil sige, at modellen vil se 100 gange billederne til optimerede vægte.
Du er allerede bekendt med koderne til at træne en model i Tensorflow. Den lille forskel er at røre dataene, før du kører træningen. På den måde træner modellen hurtigere.
Du er interesseret i at udskrive tabet efter ti epoker for at se, om modellen lærer noget (dvs. tabet er faldende). Træningen tager 2 til 5 minutter, afhængigt af din maskinhardware.
## 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
Trin 6) Vurder modellen
Nu hvor du har trænet din model, er det tid til at evaluere den. Du skal importere test-serien fra filen /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'])
BEMÆRK: For en Windows maskine, bliver koden test_data = unpickle(r”E:\cifar-10-batches-py\test_batch”)
Du kan prøve at printe billederne 13, som er en hest
plot_image(test_x[13], shape=[32, 32], cmap = "Greys_r")
For at evaluere modellen skal du bruge pixelværdien af dette billede og se, om koderen kan rekonstruere det samme billede efter at have krympet 1024 pixels. Bemærk, at du definerer en funktion til at evaluere modellen på forskellige billeder. Modellen burde kun fungere bedre på heste.
Funktionen tager to argumenter:
- df: Importer testdataene
- billednummer: angiv hvilket billede der skal importeres
Funktionen er opdelt i tre dele:
- Omform billedet til den korrekte dimension, dvs. 1, 1024
- Fodre modellen med det usete billede, indkode/afkode billedet
- Udskriv det rigtige og rekonstruerede billede
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 hvor evalueringsfunktionen er defineret, kan du se det rekonstruerede billede nummer tretten
reconstruct_image(df =test_x, image_number = 13)
INFO:tensorflow:Restoring parameters from ./model.ckpt Model restored. (1, 1024)
Resumé
- Det primære formål med en autoencoder er at komprimere inputdataene og derefter komprimere dem til et output, der ligner de originale data.
- Arkitekturen af en autoencoder symmetrisk med et pivotlag kaldet det centrale lag.
- Du kan oprette autoencoderen ved at bruge:
Delvis: for at skabe de tætte lag med den typiske indstilling:
tf.layers.dense, activation=tf.nn.elu, kernel_initializer=xav_init, kernel_regularizer=l2_regularizer
tæt_lag(): at lave matrixmultiplikationen
loss = tf.reduce_mean(tf.square(outputs - features)) optimizer = tf.train.AdamOptimizer(learning_rate) train = optimizer.minimize(loss)