Autoencoder a TensorFlow-ban példával

Mi az Autoencoder a Deep Learningben?

An Autoencoder egy eszköz az adatok kódolásának hatékony, felügyelet nélküli tanulására. Ez egyfajta mesterséges neurális hálózat, amely segít megtanulni az adathalmazok ábrázolását a dimenziócsökkentéshez azáltal, hogy a neurális hálózatot arra tanítja, hogy figyelmen kívül hagyja a jelzajt. Ez egy nagyszerű eszköz a bemenet újra létrehozásához.

Egyszerűen fogalmazva: a gép, mondjuk, képet készít, és ezzel szorosan összefüggő képet tud készíteni. Az ilyen típusú neurális hálózat bemenete címkézetlen, vagyis a hálózat képes felügyelet nélkül tanulni. Pontosabban, a bemenetet a hálózat kódolja, hogy csak a legkritikusabb szolgáltatásra összpontosítson. Ez az egyik oka annak, hogy az autoencoder népszerű a méretcsökkentés terén. Emellett autoencoderek is használhatók a gyártáshoz generatív tanulási modellek. Például a neurális hálózatot betaníthatjuk egy sor arccal, majd új arcokat hozhatunk létre.

Hogyan működik a TensorFlow Autoencoder?

Az autoencoder célja, hogy csak a lényeges jellemzőkre összpontosítva közelítse meg a bemenetet. Gondolhatja, miért nem tanulja meg egyszerűen a bemenet másolását és beillesztését a kimenet előállításához. Valójában az automatikus kódoló olyan megszorítások összessége, amelyek arra kényszerítik a hálózatot, hogy új módszereket tanuljon meg az adatok megjelenítésére, eltérve a kimenet puszta másolásától.

Egy tipikus autoencoder egy bemenettel, egy belső reprezentációval és egy kimenettel (a bemenet közelítése) van meghatározva. A tanulás a belső reprezentációhoz kapcsolódó rétegekben történik. Valójában két fő rétegblokkja van, amelyek úgy néznek ki, mint egy hagyományos neurális hálózat. A kis különbség az, hogy a kimenetet tartalmazó rétegnek egyenlőnek kell lennie a bemenettel. Az alábbi képen az eredeti bemenet az első blokkba kerül, az úgynevezett jeladó. Ez a belső reprezentáció tömöríti (csökkenti) a bemenet méretét. A második blokkban a bemenet rekonstrukciója történik. Ez a dekódolási fázis.

Az Autoencoder működése
Az Autoencoder működése

Az Autoencoder működése

A modell a veszteségfüggvény minimalizálásával frissíti a súlyokat. A modellt büntetik, ha a rekonstrukció kimenete eltér a bemenettől.

Konkrétan képzeljünk el egy 50 × 50 (azaz 250 pixel) méretű képet és egy neurális hálózatot, amely mindössze egyetlen, száz neuronból álló rejtett réteget tartalmaz. A tanulás egy jellemzőtérképen történik, amely kétszer kisebb, mint a bemenet. Ez azt jelenti, hogy a hálózatnak meg kell találnia a módját, hogy 250 pixelt rekonstruáljon, csak 100-nak megfelelő neuronvektorral.

Halmozott automatikus kódoló példa

Ebben az Autoencoder oktatóanyagban megtudhatja, hogyan kell használni a halmozott automatikus kódolót. Az architektúra hasonló a hagyományos neurális hálózathoz. A bemenet egy rejtett rétegre megy, hogy tömörítse, vagy csökkentse a méretét, majd eléri a rekonstrukciós rétegeket. A cél az, hogy az eredetihez hasonló kimeneti képet készítsenek. A modellnek meg kell tanulnia egy módot arra, hogy bizonyos korlátok mellett, azaz alacsonyabb dimenzióval érje el feladatát.

Manapság az automatikus kódolók bekerülnek Deep Learning főként a kép zajtalanítására szolgálnak. Képzeljen el egy karcos képet; az ember még mindig képes felismerni a tartalmat. A zajmentesítő autoencoder ötlete az, hogy zajt adjon a képhez, hogy rákényszerítse a hálózatot, hogy megtanulja az adatok mögötti mintát.

Az Autoencoder Deep Learning másik hasznos családja a variational autoencoder. Az ilyen típusú hálózatok új képeket generálhatnak. Képzeld el, hogy egy hálózatot képezel ki egy férfi képével; egy ilyen hálózat új arcokat produkálhat.

Hogyan készítsünk automatikus kódolót a TensorFlow segítségével

Ebből az oktatóanyagból megtudhatja, hogyan kell felépíteni egy halmozott automatikus kódolót a kép rekonstruálásához.

Ön használni fogja a CIFAR-10 adatkészlet amely 60000 32×32 színes képet tartalmaz. Az Autoencoder adatkészlet már fel van osztva 50000 10000 képre a képzéshez és XNUMX XNUMX képre a teszteléshez. Legfeljebb tíz osztály van:

  • Repülőgép
  • Autó
  • Madár
  • Macska
  • Szarvas
  • Kutya
  • béka
  • Hajó
  • Kamion

Le kell töltenie a https://www.cs.toronto.edu/~kriz/cifar.html URL-címen található képeket, és ki kell csomagolnia. A for-10-batches-py mappa öt adatcsomagot tartalmaz, egyenként 10000 XNUMX képpel, véletlenszerű sorrendben.

Mielőtt megépítené és betanítaná a modellt, bizonyos adatfeldolgozást kell alkalmaznia. A következőképpen jár el:

  1. Importálja az adatokat
  2. Konvertálja az adatokat fekete-fehér formátumba
  3. Csatlakoztassa az összes tételt
  4. Készítse el a képzési adatkészletet
  5. Készítsen képvizualizálót

Kép előfeldolgozása

1. lépés) Importálja az adatokat

A hivatalos weboldal szerint az alábbi kóddal töltheti fel az adatokat. Az Autoencoder kód betölti az adatokat egy szótárba a dátum és a címke. Vegye figyelembe, hogy a kód egy függvény.

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

2. lépés) Alakítsa át az adatokat fekete-fehér formátumba

Az egyszerűség kedvéért az adatokat szürkeárnyalatossá alakítja. Vagyis csak egy dimenzióval a három színnel szemben. A neurális hálózatok nagy része csak egydimenziós bemenettel működik.

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

3. lépés) Csatlakoztassa az összes köteget

Most, hogy mindkét függvény létrejött, és az adatkészlet betöltődött, írhat egy hurkot, amellyel hozzáfűzheti az adatokat a memóriában. Ha figyelmesen ellenőrzi, az adatokat tartalmazó kicsomagolt fájl neve data_batch_ lesz, 1-től 5-ig terjedő számmal. A fájlok között hurkolhat, és adatokhoz fűzheti.

Amikor ez a lépés megtörtént, a színadatokat szürkeárnyalatos formátumba konvertálja. Amint látható, az adatok alakja 50000 és 1024. A 32*32 pixel most 2014-re van lapítva.

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

Megjegyzés: Módosítsa a './cifar-10-batches-py/data_batch_' fájlt a fájl tényleges helyére. Például azért Windows gépen, az elérési út a következő lehet: fájlnév = 'E:\cifar-10-batches-py\data_batch_' + str(i)

4. lépés) Készítse el a betanítási adatkészletet

Az edzés gyorsabbá és egyszerűbbé tétele érdekében modellt csak a lóképeken fog kiképezni. A lovak a hetedik osztályt képviselik a címkeadatokban. Ahogy a CIFAR-10 adatkészlet dokumentációjában említettük, minden osztály 5000 képet tartalmaz. Kinyomtathatja az adatok alakját, hogy megbizonyosodjon arról, hogy 5.000 kép van 1024 oszloppal, az alábbiak szerint TensorFlow Az automatikus kódoló példa lépése.

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

5. lépés) Készítsen képmegjelenítőt

Végül összeállít egy függvényt a képek ábrázolásához. Erre a funkcióra szüksége lesz a rekonstruált kép automatikus kódolóból történő kinyomtatásához.

A képek nyomtatásának egyszerű módja az imshow objektum használata a matplotlib könyvtárból. Vegye figyelembe, hogy az adatok alakját 1024-ről 32*32-re kell konvertálnia (azaz egy kép formátumára).

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

A függvénynek 3 argumentuma van:

  • Kép: a bemenet
  • Alak: lista, a kép mérete
  • Cmap:válassza ki a színtérképet. Alapértelmezés szerint szürke

Megpróbálhatja ábrázolni az adatkészlet első képét. Látnod kell egy embert lovon.

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

Készítsen képmegjelenítőt

Állítsa be az Adatkészlet-becslőt

Rendben, most, hogy az adatkészlet használatra kész, megkezdheti a Tensorflow használatát. A modell felépítése előtt használjuk a Tensorflow Dataset becslését a hálózat táplálására.

A TensorFlow becslővel egy adatkészletet fog készíteni. Az elméd felfrissítéséhez a következőket kell használni:

  • from_tensor_slices
  • ismétlés
  • batch

Az adatkészlet felépítéséhez szükséges teljes kód:

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

Vegye figyelembe, hogy x egy helyőrző a következő alakkal:

  • [Nincs,n_inputs]: Állítsa Nincs értékre, mert a hálózatba érkező képtovábbítások száma megegyezik a köteg méretével.

a részletekért tekintse meg a következő oktatóanyagot lineáris regresszió.

Ezt követően létre kell hoznia az iterátort. E kódsor nélkül semmilyen adat nem megy át a folyamaton.

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

Most, hogy a csővezeték készen áll, ellenőrizheti, hogy az első kép ugyanaz-e, mint korábban (azaz ember lovon).

A kötegméretet 1-re állítja, mert csak egy képpel szeretné betölteni az adatkészletet. Az adatok méretét a print(sess.run(features).shape) paranccsal láthatja. Ez egyenlő (1, 1024). Az 1 azt jelenti, hogy csak egy 1024-es képről van szó. Ha a köteg mérete kettőre van állítva, akkor két kép fog átmenni a folyamaton. (Ne módosítsa a köteg méretét. Ellenkező esetben hibát fog kiütni. Egyszerre csak egy kép mehet a plot_image() függvénybe.

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

Állítsa be az Adatkészlet-becslőt

Építsd fel a hálózatot

Ideje kiépíteni a hálózatot. Egy halmozott autoencodert, azaz több rejtett rétegű hálózatot fog tanítani.

Hálózatának egy bemeneti rétege lesz, 1024 ponttal, azaz 32×32 képformával.

A kódoló blokknak egy felső rejtett rétege lesz 300 neuronnal, egy központi rétege 150 neuronnal. A dekódoló blokk szimmetrikus a kódolóhoz. A hálózatot az alábbi képen láthatja. Vegye figyelembe, hogy módosíthatja a rejtett és a központi rétegek értékeit.

Építsd fel a hálózatot
Hálózat kiépítése az Autoencoder számára

Az autoencoder felépítése nagyon hasonlít bármely más mély tanulási modellhez.

A modellt az alábbi lépések szerint készítheti el:

  1. Határozza meg a paramétereket
  2. Határozza meg a rétegeket
  3. Határozza meg az architektúrát
  4. Határozza meg az optimalizálást
  5. Futtassa a modellt
  6. Értékelje a modellt

Az előző részben megtanulta, hogyan hozhat létre folyamatot a modell betáplálásához, így nincs szükség az adatkészlet újbóli létrehozására. Egy négyrétegű autoencodert fog készíteni. Ön a Xavier inicializálást használja. Ezzel a módszerrel a kezdeti súlyokat a bemenet és a kimenet varianciájával egyenlőnek kell állítani. Végül használja az elu aktiválási funkciót. A veszteségfüggvényt az L2 szabályosítóval szabályozza.

Step 1) Határozza meg a paramétereket

Az első lépésben meg kell határozni a neuronok számát az egyes rétegekben, a tanulási sebességet és a regularizáló hiperparaméterét.

Ezt megelőzően részben importálja a függvényt. Jobb módszer a sűrű rétegek paramétereinek meghatározására. Az alábbi kód az autoencoder architektúra értékeit határozza meg. Amint azt korábban felsoroltuk, az autoencodernek két rétege van, 300 neuronnal az első rétegekben és 150 neuronnal a második rétegben. Értékeiket n_hidden_1 és n_hidden_2 tárolja.

Meg kell határoznia a tanulási sebességet és az L2 hiperparamétert. Az értékeket a learning_rate és az l2_reg tárolja

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

A Xavier inicializálási technika az xavier_initializer objektummal kerül meghívásra a contrib becslésből. Ugyanabban a becslőben hozzáadhatja a szabályosítót az l2_regularizer paraméterrel

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

Step 2) Határozza meg a rétegeket

A sűrű rétegek összes paramétere be van állítva; mindent becsomagolhat a dense_layer változóba az objektum részleges használatával. dense_layer, amely az ELU aktiválást, a Xavier inicializálást és az L2 regularizációt használja.

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

Step 3) Határozza meg az architektúrát

Ha megnézi az architektúra képét, észreveszi, hogy a hálózat három réteget halmoz fel egy kimeneti réteggel. Az alábbi kódban összekapcsolja a megfelelő rétegeket. Például az első réteg kiszámítja a pontszorzatot a bemeneti mátrix jellemzői és a 300 súlyt tartalmazó mátrixok között. A pontszorzat kiszámítása után a kimenet az Elu aktiválási funkcióhoz kerül. A kimenet a következő réteg bemenete lesz, ezért használja a rejtett_2 kiszámítására és így tovább. A mátrixok szorzása minden rétegnél azonos, mert ugyanazt az aktiválási függvényt használja. Vegye figyelembe, hogy az utolsó réteg, a kimenetek, nem alkalmaz aktiválási funkciót. Ez logikus, mert ez a rekonstruált bemenet

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

Step 4) Határozza meg az optimalizálást

Az utolsó lépés az optimalizáló létrehozása. A Mean Square Error-t veszteségfüggvényként használja. Ha felidézi a lineáris regresszióról szóló oktatóanyagot, akkor tudja, hogy az MSE kiszámítása az előrejelzett kimenet és a valós címke közötti különbséggel történik. Itt a címke a jellemző, mert a modell megpróbálja rekonstruálni a bemenetet. Ezért az előrejelzett kimenet és a bemenet közötti négyzet különbségének átlagát szeretné megadni. A TensorFlow segítségével a veszteségfüggvényt a következőképpen kódolhatja:

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

Ezután optimalizálnia kell a veszteségfüggvényt. Az Adam optimalizálót használja a színátmenetek kiszámításához. A célfüggvény a veszteség minimalizálása.

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

Még egy beállítás a modell betanítása előtt. 150-es kötegméretet szeretne használni, azaz minden iterációt 150 képpel kell betölteni a folyamatba. Az iterációk számát manuálisan kell kiszámítani. Ezt triviális csinálni:

Ha minden alkalommal 150 képet szeretne átadni, és tudja, hogy 5000 kép van az adatkészletben, akkor az iterációk száma egyenlő. A pythonban a következő kódokat futtathatja, és győződjön meg arról, hogy a kimenet 33:

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

Step 5) Futtassa a modellt

Végül, de nem utolsósorban, képezze ki a modellt. Ön 100 korszakkal oktatja a modellt. Vagyis a modell 100-szoros képet fog látni az optimalizált súlyokhoz képest.

Ön már ismeri a kódokat, amelyekkel modellt taníthat a Tensorflow-ban. A csekély különbség az, hogy az adatokat az edzés futtatása előtt csővezetékben kell megadni. Ily módon a modell gyorsabban edz.

Érdekelne, hogy tíz korszak után kinyomtassa a veszteséget, hogy lássa, tanul-e valamit a modell (azaz csökken-e a veszteség). Az edzés a gép hardverétől függően 2-5 percig tart.

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

Step 6) Értékelje a modellt

Most, hogy a modelled kiképzett, itt az ideje, hogy értékeld. Importálnia kell a tesztkészletet a /cifar-10-batches-py/ fájlból.

test_data = unpickle('./cifar-10-batches-py/test_batch')
test_x = grayscale(test_data['data'])
#test_labels = np.array(test_data['labels'])

JEGYZET: A Windows gép, a kód a következő lesz: test_data = unpickle(r”E:\cifar-10-batches-py\test_batch”)

Megpróbálhatja kinyomtatni a képeket 13, ami egy ló

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

Értékelje a modellt

A modell kiértékeléséhez ennek a képnek a pixelértékét kell használni, és megnézni, hogy a kódoló képes-e ugyanazt a képet rekonstruálni 1024 pixel zsugorítása után. Ne feledje, hogy definiál egy függvényt a modell értékeléséhez különböző képeken. A modellnek csak lovakon kell jobban működnie.

A függvénynek két argumentuma van:

  • df: Importálja a tesztadatokat
  • kép_száma: adja meg, hogy milyen képet kell importálni

A funkció három részre oszlik:

  1. Alakítsa át a képet a megfelelő méretre, azaz 1, 1024-re
  2. Táplálja a modellt a nem látott képpel, kódolja/dekódolja a képet
  3. Nyomtassa ki a valódi és rekonstruált képet
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()

Most, hogy a kiértékelési függvény definiálva van, megtekintheti a tizenhárom számú rekonstruált képet

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

Értékelje a modellt

Összegzésként

  • Az autoencoder elsődleges célja a bemeneti adatok tömörítése, majd kicsomagolása egy olyan kimenetre, amely nagyon hasonlít az eredeti adatokhoz.
  • A pivot réteggel szimmetrikus autoencoder architektúráját központi rétegnek nevezték el.
  • Az automatikus kódolót a következők segítségével hozhatja létre:
  • Részleges: sűrű rétegek létrehozása a tipikus beállítással:

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

    sűrű_réteg(): a mátrixszorzás elkészítéséhez

  • A veszteségfüggvényt és az optimalizálást a következőkkel határozhatja meg:
  • loss = tf.reduce_mean(tf.square(outputs - features))
    optimizer = tf.train.AdamOptimizer(learning_rate)
    train  = optimizer.minimize(loss)
    
  • Utoljára futtasson egy munkamenetet a modell betanításához.