Autokodare i TensorFlow med exempel

Vad รคr Autoencoder i Deep Learning?

An Autokodare รคr ett verktyg fรถr att lรคra sig datakodning effektivt pรฅ ett oรถvervakat sรคtt. Det รคr en typ av konstgjorda neurala nรคtverk som hjรคlper dig att lรคra dig representationen av datamรคngder fรถr dimensionsreduktion genom att trรคna det neurala nรคtverket att ignorera signalbruset. Det รคr ett utmรคrkt verktyg fรถr att รฅterskapa en ingรฅng.

Med enkla ord, maskinen tar, lรฅt oss sรคga en bild, och kan producera en nรคrbeslรคktad bild. Ingรฅngen i denna typ av neurala nรคtverk รคr omรคrkt, vilket betyder att nรคtverket kan lรคra sig utan รถvervakning. Nรคrmare bestรคmt รคr ingรฅngen kodad av nรคtverket fรถr att bara fokusera pรฅ den mest kritiska egenskapen. Detta รคr en av anledningarna till att autoencoder รคr populรคrt fรถr dimensionsreducering. Dessutom kan autoencoders anvรคndas fรถr att producera generativa inlรคrningsmodeller. Till exempel kan det neurala nรคtverket trรคnas med en uppsรคttning ansikten och kan sedan producera nya ansikten.

Hur fungerar TensorFlow Autoencoder?

Syftet med en autoencoder รคr att producera en approximation av ingรฅngen genom att bara fokusera pรฅ de vรคsentliga funktionerna. Du kanske tรคnker varfรถr inte bara lรคra dig hur man kopierar och klistrar in indata fรถr att producera utdata. Faktum รคr att en autoencoder รคr en uppsรคttning begrรคnsningar som tvingar nรคtverket att lรคra sig nya sรคtt att representera data, annorlunda รคn att bara kopiera utdata.

En typisk autokodare definieras med en ingรฅng, en intern representation och en utgรฅng (en approximation av ingรฅngen). Inlรคrningen sker i de lager som รคr knutna till den interna representationen. Faktum รคr att det finns tvรฅ huvudblock av lager som ser ut som ett traditionellt neuralt nรคtverk. Den lilla skillnaden รคr att lagret som innehรฅller utgรฅngen mรฅste vara lika med ingรฅngen. Pรฅ bilden nedan gรฅr den ursprungliga ingรฅngen in i det fรถrsta blocket som kallas kodare. Denna interna representation komprimerar (minskar) storleken pรฅ inmatningen. I det andra blocket sker rekonstruktionen av ingรฅngen. Detta รคr avkodningsfasen.

Fungerar av Autoencoder
Fungerar av Autoencoder

Fungerar av Autoencoder

Modellen kommer att uppdatera vikterna genom att minimera fรถrlustfunktionen. Modellen straffas om rekonstruktionsutgรฅngen skiljer sig frรฅn ingรฅngen.

Fรถrestรคll dig konkret en bild med en storlek pรฅ 50ร—50 (dvs. 250 pixlar) och ett neuralt nรคtverk med bara ett dolt lager bestรฅende av hundra neuroner. Inlรคrningen sker pรฅ en funktionskarta som รคr tvรฅ gรฅnger mindre รคn inmatningen. Det betyder att nรคtverket mรฅste hitta ett sรคtt att rekonstruera 250 pixlar med endast en vektor av neuroner lika med 100.

Exempel pรฅ staplad autokodare

I den hรคr sjรคlvstudien fรถr Autoencoder kommer du att lรคra dig hur du anvรคnder en staplad autoencoder. Arkitekturen liknar ett traditionellt neuralt nรคtverk. Inmatningen gรฅr till ett dolt lager fรถr att komprimeras eller minska dess storlek och nรฅr sedan rekonstruktionslagren. Mรฅlet รคr att producera en utgรฅende bild sรฅ nรคra originalet. Modellen mรฅste lรคra sig ett sรคtt att uppnรฅ sin uppgift under en uppsรคttning begrรคnsningar, det vill sรคga med en lรคgre dimension.

Nufรถrtiden, autoencoders in Deep Learning anvรคnds frรคmst fรถr att fรถrsvaga en bild. Fรถrestรคll dig en bild med repor; en mรคnniska kan fortfarande kรคnna igen innehรฅllet. Idรฉn med att denoising autoencoder รคr att lรคgga till brus till bilden fรถr att tvinga nรคtverket att lรคra sig mรถnstret bakom data.

Den andra anvรคndbara familjen av Autoencoder Deep Learning รคr variationsautokodare. Den hรคr typen av nรคtverk kan generera nya bilder. Fรถrestรคll dig att du trรคnar ett nรคtverk med bilden av en man; ett sรฅdant nรคtverk kan skapa nya ansikten.

Hur man bygger en autokodare med TensorFlow

I den hรคr handledningen kommer du att lรคra dig hur du bygger en staplad autokodare fรถr att rekonstruera en bild.

Du kommer att anvรคnda CIFAR-10 dataset som innehรฅller 60000 32ร—32 fรคrgbilder. Autoencoder-dataset รคr redan uppdelat mellan 50000 10000 bilder fรถr trรคning och XNUMX XNUMX fรถr testning. Det finns upp till tio klasser:

  • Flygplan
  • Automobile
  • Fรฅgel
  • Cat
  • Deer
  • Dog
  • groda
  • Hรคst
  • Ship
  • Lastbil

Du mรฅste ladda ner bilderna i denna URL https://www.cs.toronto.edu/~kriz/cifar.html och packa upp den. Mappen fรถr-10-batches-py innehรฅller fem partier data med 10000 XNUMX bilder vardera i en slumpmรคssig ordning.

Innan du bygger och trรคnar din modell mรฅste du tillรคmpa viss databehandling. Du kommer att gรฅ tillvรคga enligt fรถljande:

  1. Importera data
  2. Konvertera data till svartvitt format
  3. Lรคgg till alla satser
  4. Konstruera trรคningsdatauppsรคttningen
  5. Konstruera en bildvisualiserare

Bildfรถrbehandling

Steg 1) Importera data

Enligt den officiella webbplatsen kan du ladda upp data med fรถljande kod. Autoencoder-koden kommer att ladda data i en ordbok med datum och etikett. Observera att koden รคr 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

Steg 2) Konvertera data till svartvitt format

Fรถr enkelhetens skull kommer du att konvertera data till en grรฅskala. Det vill sรคga med endast en dimension mot tre fรถr fรคrgbild. Det mesta av det neurala nรคtverket fungerar bara med endimensionell input.

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

Steg 3) Lรคgg till alla satser

Nu nรคr bรฅda funktionerna har skapats och datauppsรคttningen laddats kan du skriva en loop fรถr att lรคgga till data i minnet. Om du kontrollerar noggrant, heter unzip-filen med data data_batch_ med ett nummer frรฅn 1 till 5. Du kan loopa รถver filerna och lรคgga till dem i data.

Nรคr detta steg รคr klart konverterar du fรคrgdata till ett grรฅskaleformat. Som du kan se รคr formen pรฅ data 50000 och 1024. De 32*32 pixlarna รคr nu plattade till 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)

Obs: ร„ndra './cifar-10-batches-py/data_batch_' till den faktiska platsen fรถr din fil. Till exempel fรถr Windows maskin, sรถkvรคgen kan vara filnamn = 'E:\cifar-10-batches-py\data_batch_' + str(i)

Steg 4) Konstruera trรคningsdatauppsรคttningen

Fรถr att gรถra trรคningen snabbare och enklare kommer du att trรคna en modell endast pรฅ hรคstbilderna. Hรคstarna รคr den sjunde klassen i etikettdata. Som nรคmnts i dokumentationen fรถr CIFAR-10-datauppsรคttningen innehรฅller varje klass 5000 bilder. Du kan skriva ut formen pรฅ data fรถr att bekrรคfta att det finns 5.000 1024 bilder med XNUMX XNUMX kolumner som visas i nedan TensorFlow Exempelsteg fรถr autoencoder.

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

Steg 5) Konstruera en bildvisualiserare

Slutligen konstruerar du en funktion fรถr att plotta bilderna. Du behรถver denna funktion fรถr att skriva ut den rekonstruerade bilden frรฅn autoencodern.

Ett enkelt sรคtt att skriva ut bilder รคr att anvรคnda objektet imshow frรฅn matplotlib-biblioteket. Observera att du mรฅste konvertera formen pรฅ data frรฅn 1024 till 32*32 (dvs formatet pรฅ en bild).

# 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 tar 3 argument:

  • Bild: ingรฅngen
  • Forma: lista, bildens dimension
  • cmap:vรคlj fรคrgkartan. Som standard, grรฅ

Du kan fรถrsรถka plotta den fรถrsta bilden i datamรคngden. Du borde se en man pรฅ en hรคst.

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

Konstruera en bildvisualiserare

Stรคll in Dataset Estimator

Okej, nu nรคr datasetet รคr klart att anvรคnda kan du bรถrja anvรคnda Tensorflow. Innan vi bygger modellen, lรฅt oss anvรคnda Dataset-estimatorn fรถr Tensorflow fรถr att mata nรคtverket.

Du kommer att bygga en datamรคngd med TensorFlow estimator. Fรถr att frรคscha upp ditt sinne mรฅste du anvรคnda:

  • from_tensor_slices
  • upprepa
  • sats

Den fullstรคndiga koden fรถr att bygga datamรคngden รคr:

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

Observera att x รคr en platshรฅllare med fรถljande form:

  • [None,n_inputs]: Stรคll in pรฅ None eftersom antalet bildmatningar till nรคtverket รคr lika med batchstorleken.

fรถr detaljer, se handledningen om linjรคr regression.

Efter det mรฅste du skapa iteratorn. Utan denna kodrad kommer ingen data att gรฅ genom pipelinen.

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

Nu nรคr pipelinen รคr klar kan du kontrollera om den fรถrsta bilden รคr densamma som tidigare (dvs en man pรฅ en hรคst).

Du stรคller in batchstorleken till 1 eftersom du bara vill mata datamรคngden med en bild. Du kan se dimensionen pรฅ datan med print(sess.run(features).shape). Det รคr lika med (1, 1024). 1 betyder att endast en bild med 1024 matas vardera. Om batchstorleken รคr instรคlld pรฅ tvรฅ, kommer tvรฅ bilder att gรฅ genom pipelinen. (ร„ndra inte batchstorleken. Annars kommer det att skapa ett fel. Endast en bild รฅt gรฅngen kan gรฅ till 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)

Stรคll in Dataset Estimator

Bygg nรคtverket

Det รคr dags att bygga nรคtverket. Du kommer att trรคna en staplad autokodare, det vill sรคga ett nรคtverk med flera dolda lager.

Ditt nรคtverk kommer att ha ett indatalager med 1024 punkter, dvs 32ร—32, bildens form.

Kodarblocket kommer att ha ett รถvre dolt lager med 300 neuroner, ett centralt lager med 150 neuroner. Avkodarblocket รคr symmetriskt till kodaren. Du kan visualisera nรคtverket pรฅ bilden nedan. Observera att du kan รคndra vรคrdena fรถr dolda och centrala lager.

Bygg nรคtverket
Bygga nรคtverket fรถr Autoencoder

Att bygga en autoencoder รคr mycket likt vilken annan modell fรถr djupinlรคrning som helst.

Du kommer att konstruera modellen enligt dessa steg:

  1. Definiera parametrarna
  2. Definiera lagren
  3. Definiera arkitekturen
  4. Definiera optimeringen
  5. Kรถr modellen
  6. Utvรคrdera modellen

I det fรถregรฅende avsnittet lรคrde du dig hur man skapar en pipeline fรถr att mata modellen, sรฅ det finns inget behov av att skapa datauppsรคttningen en gรฅng till. Du kommer att konstruera en autoencoder med fyra lager. Du anvรคnder Xavier-initieringen. Detta รคr en teknik fรถr att stรคlla in de initiala vikterna lika med variansen fรถr bรฅde ingรฅngen och utmatningen. Slutligen anvรคnder du elu-aktiveringsfunktionen. Du reglerar fรถrlustfunktionen med L2 regularizer.

Steg 1) Definiera parametrarna

Det fรถrsta steget innebรคr att definiera antalet neuroner i varje lager, inlรคrningshastigheten och hyperparametern fรถr regularizern.

Innan dess importerar du funktionen delvis. Det รคr en bรคttre metod att definiera parametrarna fรถr de tรคta lagren. Koden nedan definierar vรคrdena fรถr autoencoder-arkitekturen. Som nรคmnts tidigare har autokodaren tvรฅ lager, med 300 neuroner i det fรถrsta lagret och 150 i det andra lagret. Deras vรคrden lagras i n_hidden_1 och n_hidden_2.

Du mรฅste definiera inlรคrningshastigheten och hyperparametern L2. Vรคrdena lagras i learning_rate och 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-initieringstekniken anropas med objektet xavier_initializer frรฅn estimatorns bidrag. I samma estimator kan du lรคgga till regularizern 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)

Steg 2) Definiera lagren

Alla parametrar fรถr de tรคta lagren har stรคllts in; du kan packa allt i variabeln dense_layer genom att anvรคnda objektet partial. dense_layer som anvรคnder ELU-aktivering, Xavier-initiering och L2-regularisering.

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

Steg 3) Definiera arkitekturen

Om du tittar pรฅ bilden av arkitekturen, noterar du att nรคtverket staplar tre lager med ett utdatalager. I koden nedan kopplar du ihop lรคmpliga lager. Till exempel berรคknar det fรถrsta lagret punktprodukten mellan inmatningsmatrisegenskaperna och matriserna som innehรฅller de 300 vikterna. Efter att punktprodukten har berรคknats gรฅr utsignalen till Elu-aktiveringsfunktionen. Utdatan blir indata fรถr nรคsta lager, det รคr dรคrfรถr du anvรคnder den fรถr att berรคkna hidden_2 och sรฅ vidare. Matrismultiplikationen รคr densamma fรถr varje lager eftersom du anvรคnder samma aktiveringsfunktion. Observera att det sista lagret, utgรฅngar, inte tillรคmpar en aktiveringsfunktion. Det รคr vettigt eftersom detta รคr den rekonstruerade ingรฅngen

## 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)

Steg 4) Definiera optimeringen

Det sista steget รคr att konstruera optimeraren. Du anvรคnder Mean Square Error som en fรถrlustfunktion. Om du kommer ihรฅg handledningen om linjรคr regression, vet du att MSE berรคknas med skillnaden mellan den fรถrutspรฅdda utsignalen och den verkliga etiketten. Hรคr รคr etiketten funktionen eftersom modellen fรถrsรถker rekonstruera ingรฅngen. Dรคrfรถr vill du ha medelvรคrdet av summan av skillnaden i kvadraten mellan fรถrutsagd utdata och ingรฅng. Med TensorFlow kan du koda fรถrlustfunktionen enligt fรถljande:

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

Sedan mรฅste du optimera fรถrlustfunktionen. Du anvรคnder Adam optimizer fรถr att berรคkna gradienterna. Den objektiva funktionen รคr att minimera fรถrlusten.

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

Ytterligare en instรคllning innan du trรคnar modellen. Du vill anvรคnda en batchstorlek pรฅ 150, det vill sรคga mata pipelinen med 150 bilder varje iteration. Du mรฅste berรคkna antalet iterationer manuellt. Detta รคr trivialt att gรถra:

Om du vill skicka 150 bilder varje gรฅng och du vet att det finns 5000 bilder i datamรคngden รคr antalet iterationer lika med . I python kan du kรถra fรถljande koder och se till att utdata รคr 33:

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

Steg 5) Kรถr modellen

Sist men inte minst, trรคna modellen. Du trรคnar modellen med 100 epoker. Det vill sรคga, modellen kommer att se 100 gรฅnger bilderna till optimerade vikter.

Du รคr redan bekant med koderna fรถr att trรคna en modell i Tensorflow. Den lilla skillnaden รคr att rรถra data innan du kรถr trรคningen. Pรฅ sรฅ sรคtt trรคnar modellen snabbare.

Du รคr intresserad av att skriva ut fรถrlusten efter tio epoker fรถr att se om modellen lรคr sig nรฅgot (dvs. fรถrlusten minskar). Utbildningen tar 2 till 5 minuter, beroende pรฅ din maskinvara.

## 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

Steg 6) Utvรคrdera modellen

Nu nรคr du har trรคnat din modell รคr det dags att utvรคrdera den. Du mรฅste importera testserien frรฅn 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'])

ANMร„RKNINGAR: Fรถr en Windows maskin, koden blir test_data = unpickle(rโ€E:\cifar-10-batches-py\test_batchโ€)

Du kan prova att skriva ut bilderna 13, som รคr en hรคst

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

Utvรคrdera modellen

Fรถr att utvรคrdera modellen kommer du att anvรคnda pixelvรคrdet fรถr denna bild och se om kodaren kan rekonstruera samma bild efter att ha krympt 1024 pixlar. Observera att du definierar en funktion fรถr att utvรคrdera modellen pรฅ olika bilder. Modellen borde fungera bรคttre bara pรฅ hรคstar.

Funktionen tar tvรฅ argument:

  • df: Importera testdata
  • bildnummer: ange vilken bild som ska importeras

Funktionen รคr uppdelad i tre delar:

  1. Forma om bilden till rรคtt dimension, dvs 1, 1024
  2. Mata modellen med den osynliga bilden, koda/avkoda bilden
  3. Skriv ut den verkliga och rekonstruerade bilden
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 nรคr utvรคrderingsfunktionen รคr definierad kan du ta en titt pรฅ den rekonstruerade bilden nummer tretton

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

Utvรคrdera modellen

Sammanfattning

  • Det primรคra syftet med en autoencoder รคr att komprimera indata och sedan komprimera den till en utdata som liknar originaldata.
  • Arkitekturen fรถr en autoencoder symmetrisk med ett pivotlager som heter det centrala lagret.
  • Du kan skapa autokodaren med:
  • Partiell: fรถr att skapa de tรคta lagren med den typiska instรคllningen:

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

    dense_layer(): fรถr att gรถra matrismultiplikationen

  • Du kan definiera fรถrlustfunktionen och optimeringen med:
  • loss = tf.reduce_mean(tf.square(outputs - features))
    optimizer = tf.train.AdamOptimizer(learning_rate)
    train  = optimizer.minimize(loss)
    
  • Kรถr senast ett pass fรถr att trรคna modellen.

Sammanfatta detta inlรคgg med: