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.

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
- Ló
- 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:
- Importálja az adatokat
- Konvertálja az adatokat fekete-fehér formátumba
- Csatlakoztassa az összes tételt
- Készítse el a képzési adatkészletet
- 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")
Á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)
É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.

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:
- Határozza meg a paramétereket
- Határozza meg a rétegeket
- Határozza meg az architektúrát
- Határozza meg az optimalizálást
- Futtassa a modellt
- É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")
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:
- Alakítsa át a képet a megfelelő méretre, azaz 1, 1024-re
- Táplálja a modellt a nem látott képpel, kódolja/dekódolja a képet
- 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)
Ö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
loss = tf.reduce_mean(tf.square(outputs - features)) optimizer = tf.train.AdamOptimizer(learning_rate) train = optimizer.minimize(loss)