Autoenkoder u TensorFlowu s primjerom

Što je Autoenkoder u dubokom učenju?

An Autokoder je alat za učinkovito učenje kodiranja podataka na nenadgledan način. To je vrsta umjetne neuronske mreže koja vam pomaže da naučite reprezentaciju skupova podataka za smanjenje dimenzionalnosti treniranjem neuronske mreže da zanemari šum signala. To je izvrstan alat za ponovno stvaranje unosa.

Jednostavnim riječima, stroj uzima, recimo sliku, i može proizvesti sličnu sliku. Ulaz u ovu vrstu neuronske mreže nije označen, što znači da je mreža sposobna učiti bez nadzora. Točnije, ulaz je kodiran od strane mreže kako bi se usredotočio samo na najkritičniju značajku. Ovo je jedan od razloga zašto je autoenkoder popularan za smanjenje dimenzionalnosti. Osim toga, autoenkoderi se mogu koristiti za proizvodnju generativni modeli učenja. Na primjer, neuronska mreža se može trenirati sa skupom lica, a zatim može proizvesti nova lica.

Kako radi TensorFlow Autoenkoder?

Svrha autoenkodera je proizvesti aproksimaciju ulaza fokusirajući se samo na bitne značajke. Možda mislite zašto jednostavno ne naučite kako kopirati i zalijepiti ulaz da biste dobili izlaz. Zapravo, autokoder je skup ograničenja koja tjeraju mrežu da nauči nove načine predstavljanja podataka, različite od pukog kopiranja izlaza.

Tipični autokoder je definiran s ulazom, internim prikazom i izlazom (aproksimacija ulaza). Učenje se odvija u slojevima koji su povezani s unutarnjom reprezentacijom. Zapravo, postoje dva glavna bloka slojeva koji izgledaju kao tradicionalna neuronska mreža. Mala razlika je u tome što sloj koji sadrži izlaz mora biti jednak ulazu. Na slici ispod, izvorni unos ulazi u prvi blok koji se zove davač. Ovaj interni prikaz komprimira (smanjuje) veličinu ulaza. U drugom bloku dolazi do rekonstrukcije ulaza. Ovo je faza dekodiranja.

Rad Autoenkodera
Rad Autoenkodera

Rad Autoenkodera

Model će ažurirati težine minimiziranjem funkcije gubitka. Model se kažnjava ako se izlaz rekonstrukcije razlikuje od ulaza.

Konkretno, zamislite sliku veličine 50×50 (tj. 250 piksela) i neuronsku mrežu sa samo jednim skrivenim slojem sastavljenim od sto neurona. Učenje se vrši na mapi značajki koja je dva puta manja od ulaza. To znači da mreža mora pronaći način da rekonstruira 250 piksela sa samo vektorom neurona jednakim 100.

Primjer naslaganog autokodera

U ovom vodiču za autokoder naučit ćete kako koristiti složeni autokoder. Arhitektura je slična tradicionalnoj neuronskoj mreži. Ulaz ide u skriveni sloj kako bi se komprimirao ili smanjio njegovu veličinu, a zatim dolazi do slojeva rekonstrukcije. Cilj je proizvesti izlaznu sliku što sličniju izvorniku. Model mora naučiti način kako postići svoj zadatak pod skupom ograničenja, to jest s nižom dimenzijom.

Danas, Autoenkoderi in Duboko učenje uglavnom se koriste za uklanjanje šuma sa slike. Zamislite sliku s ogrebotinama; čovjek još uvijek može prepoznati sadržaj. Ideja denoising autoenkodera je dodati šum slici kako bi se mreža natjerala da nauči uzorak iza podataka.

Druga korisna obitelj Autoencoder Deep Learning je varijacijski autoenkoder. Ova vrsta mreže može generirati nove slike. Zamislite da obučete mrežu sa slikom čovjeka; takva mreža može proizvesti nova lica.

Kako izgraditi autoenkoder s TensorFlowom

U ovom ćete vodiču naučiti kako izraditi naslagani autokoder za rekonstrukciju slike.

Koristit ćete Skup podataka CIFAR-10 koji sadrži 60000 slika u boji 32×32. Skup podataka Autoencodera već je podijeljen na 50000 10000 slika za obuku i XNUMX XNUMX za testiranje. Postoji do deset klasa:

  • Zrakoplov
  • Automobil
  • Ptica
  • Mačka
  • Jelen
  • Pas
  • Žaba
  • Konj
  • Brod
  • Kamion

Morate preuzeti slike na ovom URL-u https://www.cs.toronto.edu/~kriz/cifar.html i raspakirati ih. Mapa for-10-batches-py sadrži pet serija podataka s po 10000 XNUMX slika u svakoj nasumičnim redoslijedom.

Prije nego što izgradite i obučite svoj model, morate primijeniti određenu obradu podataka. Postupit ćete na sljedeći način:

  1. Uvezite podatke
  2. Pretvorite podatke u crno-bijeli format
  3. Dodajte sve serije
  4. Konstruirajte skup podataka za obuku
  5. Konstruirajte vizualizator slike

Predobrada slike

Korak 1) Uvezite podatke

Prema službenoj web stranici, podatke možete učitati pomoću sljedećeg koda. Autoencoder kod će učitati podatke u rječnik s datum i oznaka. Imajte na umu da je kod funkcija.

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

Korak 2) Pretvorite podatke u crno-bijeli format

Radi jednostavnosti, podatke ćete pretvoriti u sive tonove. To jest, sa samo jednom dimenzijom u odnosu na tri za sliku boja. Većina neuronskih mreža radi samo s jednom dimenzijom ulaza.

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

Korak 3) Dodajte sve serije

Sada kada su obje funkcije stvorene i skup podataka učitan, možete napisati petlju za dodavanje podataka u memoriju. Ako pažljivo provjerite, raspakirana datoteka s podacima naziva se data_batch_ s brojem od 1 do 5. Možete prelaziti preko datoteka i dodati ih podacima.

Kada je ovaj korak gotov, podatke o bojama pretvarate u format sivih tonova. Kao što možete vidjeti, oblik podataka je 50000 i 1024. 32*32 piksela sada su izravnani na 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)

Napomena: promijenite './cifar-10-batches-py/data_batch_' na stvarnu lokaciju vaše datoteke. Na primjer za Windows stroj, put može biti naziv datoteke = 'E:\cifar-10-batches-py\data_batch_' + str(i)

Korak 4) Konstruirajte skup podataka za obuku

Kako bi trening bio brži i lakši, model ćete trenirati samo na slikama konja. Konji su sedma klasa u podacima na etiketi. Kao što je navedeno u dokumentaciji skupa podataka CIFAR-10, svaka klasa sadrži 5000 slika. Možete ispisati oblik podataka kako biste potvrdili da postoji 5.000 slika sa 1024 stupca kao što je prikazano u nastavku TensorFlow Korak primjera autokodera.

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

Korak 5) Konstruirajte vizualizator slike

Konačno, konstruirate funkciju za iscrtavanje slika. Ova će vam funkcija trebati za ispis rekonstruirane slike iz autokodera.

Jednostavan način ispisa slika je korištenje objekta imshow iz biblioteke matplotlib. Imajte na umu da trebate pretvoriti oblik podataka iz 1024 u 32*32 (tj. format slike).

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

Funkcija prima 3 argumenta:

  • Slika: ulaz
  • Oblikujte: popis, dimenzija slike
  • Cmap: odaberite kartu boja. Prema zadanim postavkama, siva

Možete pokušati iscrtati prvu sliku u skupu podataka. Trebali biste vidjeti čovjeka na konju.

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

Konstruirajte vizualizator slike

Postavite procjenitelj skupa podataka

U redu, sada kada je skup podataka spreman za upotrebu, možete početi koristiti Tensorflow. Prije izgradnje modela, upotrijebimo Dataset estimator Tensorflowa za napajanje mreže.

Izgradit ćete skup podataka s TensorFlow estimatorom. Da biste osvježili svoj um, trebate koristiti:

  • iz_odsječaka_tenzora
  • ponoviti
  • serija

Potpuni kod za izradu skupa podataka je:

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

Imajte na umu da je x rezervirano mjesto sljedećeg oblika:

  • [None,n_inputs]: Postavite na None jer je broj feedova slika u mrežu jednak veličini serije.

za pojedinosti pogledajte vodič na Linearna regresija.

Nakon toga morate kreirati iterator. Bez ovog retka koda nikakvi podaci neće proći kroz cjevovod.

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

Sada kada je cjevovod spreman, možete provjeriti je li prva slika ista kao prije (tj. čovjek na konju).

Postavili ste veličinu serije na 1 jer skupu podataka želite dodati samo jednu sliku. Možete vidjeti dimenziju podataka pomoću print(sess.run(features).shape). Jednako je (1, 1024). 1 znači da se svaka slika šalje samo po jednom slikom s 1024. Ako je veličina serije postavljena na dvije, tada će dvije slike proći kroz cjevovod. (Nemojte mijenjati veličinu serije. U suprotnom će se javiti pogreška. Samo jedna po jedna slika može ići u funkciju 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)

Postavite procjenitelj skupa podataka

Izgradite mrežu

Vrijeme je za izgradnju mreže. Trenirati ćete složeni autokoder, odnosno mrežu s više skrivenih slojeva.

Vaša mreža će imati jedan ulazni sloj sa 1024 točke, tj. 32×32, oblik slike.

Blok kodera će imati jedan gornji skriveni sloj sa 300 neurona, središnji sloj sa 150 neurona. Blok dekodera je simetričan u odnosu na koder. Mrežu možete vizualizirati na slici ispod. Imajte na umu da možete promijeniti vrijednosti skrivenih i središnjih slojeva.

Izgradite mrežu
Izgradnja mreže za Autoencoder

Izrada autoenkodera vrlo je slična bilo kojem drugom modelu dubokog učenja.

Model ćete izraditi slijedeći ove korake:

  1. Definirajte parametre
  2. Definirajte slojeve
  3. Definirajte arhitekturu
  4. Definirajte optimizaciju
  5. Pokrenite model
  6. Ocijenite model

U prethodnom ste odjeljku naučili kako stvoriti cjevovod za napajanje modela, tako da nema potrebe ponovno stvarati skup podataka. Konstruirat ćete autokoder s četiri sloja. Koristite Xavier inicijalizaciju. Ovo je tehnika za postavljanje početnih težina jednakih varijanci ulaza i izlaza. Konačno, koristite funkciju elu aktivacije. Funkciju gubitka regulirate L2 regulatorom.

Korak 1) Definirajte parametre

Prvi korak podrazumijeva definiranje broja neurona u svakom sloju, stopu učenja i hiperparametar regularizatora.

Prije toga djelomično uvozite funkciju. To je bolja metoda za definiranje parametara gustih slojeva. Kod u nastavku definira vrijednosti arhitekture autoenkodera. Kao što je prije navedeno, autokoder ima dva sloja, s 300 neurona u prvim slojevima i 150 u drugim slojevima. Njihove vrijednosti pohranjene su u n_hidden_1 i n_hidden_2.

Morate definirati brzinu učenja i hiperparametar L2. Vrijednosti su pohranjene u learning_rate i 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

Tehnika inicijalizacije Xavier poziva se s objektom xavier_initializer iz doprinosa estimatora. U istom estimatoru možete dodati regularizator s 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)

Korak 2) Definirajte slojeve

Postavljeni su svi parametri gustih slojeva; sve možete upakirati u varijablu dense_layer korištenjem parcijala objekta. dense_layer koji koristi ELU aktivaciju, Xavier inicijalizaciju i L2 regulaciju.

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

Korak 3) Definirajte arhitekturu

Ako pogledate sliku arhitekture, primijetit ćete da mreža slaže tri sloja s izlaznim slojem. U donjem kodu povezujete odgovarajuće slojeve. Na primjer, prvi sloj izračunava točkasti umnožak između značajki ulaznih matrica i matrica koje sadrže 300 težina. Nakon što se izračuna točkasti umnožak, izlaz ide u Elu aktivacijsku funkciju. Izlaz postaje ulaz sljedećeg sloja, zato ga koristite za izračunavanje hidden_2 i tako dalje. Množenje matrica je isto za svaki sloj jer koristite istu aktivacijsku funkciju. Imajte na umu da posljednji sloj, izlazi, ne primjenjuje funkciju aktivacije. Ima smisla jer je ovo rekonstruirani unos

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

Korak 4) Definirajte optimizaciju

Zadnji korak je konstruirati optimizator. Koristite srednju kvadratnu pogrešku kao funkciju gubitka. Ako se prisjetite vodiča o linearnoj regresiji, znate da se MSE izračunava s razlikom između predviđenog izlaza i stvarne oznake. Ovdje je oznaka značajka jer model pokušava rekonstruirati ulaz. Stoga želite srednju vrijednost zbroja razlike kvadrata između predviđenog izlaza i ulaza. S TensorFlowom možete kodirati funkciju gubitka na sljedeći način:

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

Zatim trebate optimizirati funkciju gubitka. Za izračunavanje gradijenata koristite Adamov optimizator. Ciljna funkcija je minimiziranje gubitka.

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

Još jedna postavka prije treninga modela. Želite upotrijebiti veličinu serije od 150, to jest, unijeti cjevovod sa 150 slika u svakoj iteraciji. Morate ručno izračunati broj ponavljanja. Ovo je trivijalno učiniti:

Ako želite proslijediti 150 slika svaki put i znate da postoji 5000 slika u skupu podataka, broj ponavljanja je jednak . U pythonu možete pokrenuti sljedeće kodove i osigurati da je izlaz 33:

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

Korak 5) Pokrenite model

Na kraju, ali ne manje važno, obučite model. Vi trenirate model sa 100 epoha. To jest, model će vidjeti 100 puta više slika za optimizirane težine.

Već ste upoznati s kodovima za obuku modela u Tensorflowu. Mala je razlika u usmjeravanju podataka prije pokretanja obuke. Na taj način model se brže trenira.

Zanima vas ispis gubitka nakon deset epoha da vidite uči li model nešto (tj. gubici se smanjuju). Obuka traje 2 do 5 minuta, ovisno o hardveru vašeg stroja.

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

Korak 6) Ocijenite model

Sada kada ste obučili svoj model, vrijeme je da ga ocijenite. Morate uvesti testni set iz datoteke /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'])

BILJEŠKA: Za Windows stroj, kod postaje test_data = unpickle(r”E:\cifar-10-batches-py\test_batch”)

Možete pokušati ispisati slike 13, što je konj

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

Ocijenite model

Za procjenu modela upotrijebit ćete vrijednost piksela ove slike i vidjeti može li koder rekonstruirati istu sliku nakon smanjivanja za 1024 piksela. Imajte na umu da definirate funkciju za procjenu modela na različitim slikama. Model bi trebao bolje funkcionirati samo na konjima.

Funkcija prima dva argumenta:

  • df: Uvezite testne podatke
  • broj_slike: označite koju sliku želite uvesti

Funkcija je podijeljena u tri dijela:

  1. Preoblikujte sliku na ispravnu dimenziju, tj. 1, 1024
  2. Nahranite model neviđenom slikom, kodirajte/dekodirajte sliku
  3. Ispišite stvarnu i rekonstruiranu sliku
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()

Sada kada je funkcija evaluacije definirana, možete pogledati rekonstruiranu sliku broj trinaest

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

Ocijenite model

Rezime

  • Primarna svrha autoenkodera je komprimirati ulazne podatke, a zatim ih dekomprimirati u izlaz koji je vrlo sličan izvornim podacima.
  • Arhitektura autoenkodera simetričnog sa zakretnim slojem koji se naziva središnji sloj.
  • Autokoder možete izraditi pomoću:
  • Djelomična: za stvaranje gustih slojeva s tipičnom postavkom:

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

    gusti_sloj(): za množenje matrice

  • Funkciju gubitka i optimizaciju možete definirati pomoću:
  • loss = tf.reduce_mean(tf.square(outputs - features))
    optimizer = tf.train.AdamOptimizer(learning_rate)
    train  = optimizer.minimize(loss)
    
  • Zadnje pokrenite sesiju za obuku modela.

Sažmite ovu objavu uz: