Autoencoder v TensorFlow s příkladem
Co je Autoencoder v Deep Learning?
An Autokodér je nástroj pro efektivní učení kódování dat bez dozoru. Je to typ umělé neuronové sítě, která vám pomáhá naučit se reprezentaci datových sad pro redukci rozměrů tím, že trénuje neuronovou síť tak, aby ignorovala šum signálu. Je to skvělý nástroj pro opětovné vytvoření vstupu.
Jednoduše řečeno, stroj pořídí, řekněme obrázek, a dokáže vytvořit úzce související obrázek. Vstup v tomto druhu neuronové sítě není označen, což znamená, že síť je schopna se učit bez dozoru. Přesněji řečeno, vstup je zakódován sítí, aby se soustředil pouze na nejkritičtější funkci. To je jeden z důvodů, proč je autoencoder oblíbený pro redukci rozměrů. Kromě toho lze k výrobě použít automatické kodéry generativní modely učení. Například neuronová síť může být trénována pomocí sady tváří a poté může vytvářet nové tváře.
Jak funguje TensorFlow Autoencoder?
Účelem automatického kodéru je vytvořit aproximaci vstupu zaměřením se pouze na základní vlastnosti. Možná vás napadne, proč se jen nenaučit, jak zkopírovat a vložit vstup a vytvořit výstup. Autokodér je ve skutečnosti sada omezení, která nutí síť naučit se nové způsoby reprezentace dat, které se liší od pouhého kopírování výstupu.
Typický autoenkodér je definován se vstupem, vnitřní reprezentací a výstupem (aproximace vstupu). Učení probíhá ve vrstvách připojených k vnitřní reprezentaci. Ve skutečnosti existují dva hlavní bloky vrstev, které vypadají jako tradiční neuronová síť. Mírný rozdíl je v tom, že vrstva obsahující výstup se musí rovnat vstupu. Na obrázku níže jde původní vstup do prvního bloku s názvem kodér. Tato vnitřní reprezentace komprimuje (zmenšuje) velikost vstupu. Ve druhém bloku dochází k rekonstrukci vstupu. Toto je fáze dekódování.
Model aktualizuje váhy minimalizací funkce ztráty. Model je penalizován, pokud se výstup rekonstrukce liší od vstupu.
Konkrétně si představte obrázek o velikosti 50×50 (tj. 250 pixelů) a neuronovou síť s jedinou skrytou vrstvou složenou ze sta neuronů. Učení se provádí na mapě objektů, která je dvakrát menší než vstup. Znamená to, že síť musí najít způsob, jak rekonstruovat 250 pixelů pouze s vektorem neuronů rovným 100.
Příklad skládaného automatického kodéru
V tomto tutoriálu Autoencoder se naučíte používat skládaný autoencoder. Architektura je podobná tradiční neuronové síti. Vstup jde do skryté vrstvy, aby byl komprimován nebo zmenšil jeho velikost, a poté dosáhne rekonstrukční vrstvy. Cílem je vytvořit výstupní obraz stejně blízký jako originál. Model se musí naučit způsob, jak dosáhnout svého úkolu pod sadou omezení, to znamená s nižší dimenzí.
V dnešní době jsou automatické kodéry v Hluboké učení se používají hlavně k odšumování obrazu. Představte si obraz se škrábanci; člověk je stále schopen rozpoznat obsah. Myšlenka odšumovacího automatického kodéru je přidat do obrazu šum, aby se síť přinutila naučit se vzor za daty.
Další užitečnou rodinou Autoencoder Deep Learning je variační autoencoder. Tento typ sítě může generovat nové obrázky. Představte si, že trénujete síť s obrazem muže; taková síť může produkovat nové tváře.
Jak vytvořit automatický kodér s TensorFlow
V tomto tutoriálu se naučíte, jak vytvořit skládaný autokodér pro rekonstrukci obrázku.
Budete používat CIFAR-10 datový soubor který obsahuje 60000 32 barevných obrázků 32×50000. Dataset Autoencoderu je již rozdělen mezi 10000 XNUMX obrázků pro trénování a XNUMX XNUMX pro testování. Existuje až deset tříd:
- Letoun
- Automobil
- Pták
- Kočka
- Jelen
- Pes
- Žába
- Kůň
- Loď
- nákladní auto
Musíte si stáhnout obrázky z této adresy URL https://www.cs.toronto.edu/~kriz/cifar.html a rozbalit je. Složka for-10-batches-py obsahuje pět dávek dat po 10000 XNUMX snímcích v náhodném pořadí.
Než svůj model postavíte a vycvičíte, musíte použít určité zpracování dat. Budete postupovat následovně:
- Importujte data
- Převeďte data do černobílého formátu
- Připojte všechny dávky
- Sestavte trénovací datovou sadu
- Vytvořte vizualizér obrázků
Předzpracování obrazu
Krok 1) Importujte data
Podle oficiálních stránek můžete data nahrát pomocí následujícího kódu. Kód Autoencoder načte data do slovníku s datum a štítek. Všimněte si, že kód je funkce.
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
Krok 2) Převeďte data do černobílého formátu
Pro jednoduchost převedete data do odstínů šedi. To znamená, že pouze jeden rozměr proti třem pro barevný obraz. Většina neuronové sítě pracuje pouze s jednorozměrným vstupem.
def grayscale(im): return im.reshape(im.shape[0], 3, 32, 32).mean(1).reshape(im.shape[0], -1)
Krok 3) Připojte všechny dávky
Nyní, když jsou obě funkce vytvořeny a datová sada načtena, můžete napsat smyčku pro připojení dat do paměti. Pokud pečlivě zkontrolujete, rozbalený soubor s daty se jmenuje data_batch_ s číslem od 1 do 5. Soubory můžete opakovat a připojit je k datům.
Po dokončení tohoto kroku převedete data barev do formátu odstínů šedé. Jak můžete vidět, tvar dat je 50000 a 1024. 32*32 pixelů je nyní zploštěno na rok 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)
Poznámka: Změňte './cifar-10-batches-py/data_batch_' na skutečné umístění vašeho souboru. Například pro Windows počítači, cesta může být název_souboru = 'E:\cifar-10-batches-py\data_batch_' + str(i)
Krok 4) Vytvořte trénovací datovou sadu
Pro urychlení a usnadnění tréninku budete modelku trénovat pouze na obrázcích koně. Koně jsou v údajích na štítku sedmá třída. Jak je uvedeno v dokumentaci datové sady CIFAR-10, každá třída obsahuje 5000 obrázků. Můžete vytisknout tvar dat, abyste potvrdili, že existuje 5.000 1024 obrázků s XNUMX sloupci, jak je znázorněno níže TensorFlow Příklad kroku automatického kodéru.
horse_i = np.where(y == 7)[0] horse_x = x[horse_i] print(np.shape(horse_x)) (5000, 1024)
Krok 5) Vytvořte vizualizér obrázků
Nakonec vytvoříte funkci pro vykreslení obrázků. Tuto funkci budete potřebovat pro tisk rekonstruovaného obrázku z autokodéru.
Snadný způsob, jak tisknout obrázky, je použít objekt imshow z knihovny matplotlib. Všimněte si, že je potřeba převést tvar dat z 1024 na 32*32 (tj. formát obrázku).
# 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")
Funkce má 3 argumenty:
- Obraz: vstup
- Shape: seznam, rozměr obrázku
- cmap:vyberte barevnou mapu. Ve výchozím nastavení šedá
Můžete zkusit vykreslit první obrázek v datové sadě. Měli byste vidět muže na koni.
plot_image(horse_x[1], shape=[32, 32], cmap = "Greys_r")
Nastavit odhad datové sady
Dobře, nyní, když je datová sada připravena k použití, můžete začít používat Tensorflow. Než sestavíme model, použijme k napájení sítě estimátor datové sady Tensorflow.
Vytvoříte datovou sadu s odhadem TensorFlow. Chcete-li osvěžit svou mysl, musíte použít:
- z_tensor_slices
- opakovat
- várka
Úplný kód pro sestavení datové sady je:
dataset = tf.data.Dataset.from_tensor_slices(x).repeat().batch(batch_size)
Všimněte si, že x je zástupný symbol s následujícím tvarem:
- [None,n_inputs]: Nastavte na None, protože počet podání obrazu do sítě se rovná velikosti dávky.
podrobnosti naleznete ve výukovém programu na lineární regrese.
Poté musíte vytvořit iterátor. Bez tohoto řádku kódu neprojdou potrubím žádná data.
iter = dataset.make_initializable_iterator() # create the iteratorfeatures = iter.get_next()
Nyní, když je potrubí připraveno, můžete zkontrolovat, zda je první obrázek stejný jako předtím (tj. muž na koni).
Velikost dávky nastavíte na 1, protože chcete do datové sady vložit pouze jeden obrázek. Rozměr dat můžete vidět pomocí print(sess.run(features).shape). Je to rovno (1, 1024). 1 znamená, že každý je podáván pouze jeden obrázek s 1024. Pokud je velikost dávky nastavena na dvě, projdou potrubím dva obrázky. (Velikost dávky neměňte. V opačném případě dojde k chybě. K funkci plot_image() může přejít vždy pouze jeden obrázek.
## 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)
Vybudujte síť
Je čas vybudovat síť. Budete trénovat skládaný autokodér, tedy síť s více skrytými vrstvami.
Vaše síť bude mít jednu vstupní vrstvu s 1024 body, tj. 32×32, tvar obrázku.
Blok kodéru bude mít jednu vrchní skrytou vrstvu s 300 neurony a centrální vrstvu se 150 neurony. Blok dekodéru je symetrický vůči kodéru. Síť si můžete představit na obrázku níže. Všimněte si, že můžete změnit hodnoty skrytých a centrálních vrstev.
Vytvoření autokodéru je velmi podobné jakémukoli jinému modelu hlubokého učení.
Model vytvoříte podle následujících kroků:
- Definujte parametry
- Definujte vrstvy
- Definujte architekturu
- Definujte optimalizaci
- Spusťte model
- Vyhodnoťte model
V předchozí části jste se naučili, jak vytvořit potrubí pro napájení modelu, takže není potřeba znovu vytvářet datovou sadu. Vytvoříte autokodér se čtyřmi vrstvami. Používáte inicializaci Xavier. Toto je technika pro nastavení počátečních vah rovných rozptylu jak vstupu, tak výstupu. Nakonec použijete funkci aktivace elu. Regulátorem L2 regulujete funkci ztráty.
Krok 1) Definujte parametry
První krok znamená definovat počet neuronů v každé vrstvě, rychlost učení a hyperparametr regularizátoru.
Předtím funkci importujete částečně. Je to lepší metoda pro definování parametrů hustých vrstev. Níže uvedený kód definuje hodnoty architektury automatického kodéru. Jak bylo uvedeno výše, autokodér má dvě vrstvy, s 300 neurony v prvních vrstvách a 150 ve druhých vrstvách. Jejich hodnoty jsou uloženy v n_hidden_1 a n_hidden_2.
Musíte definovat rychlost učení a hyperparametr L2. Hodnoty jsou uloženy v learning_rate a 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
Technika inicializace Xavier je volána s objektem xavier_initializer z příspěvku estimatoru. Ve stejném odhadu můžete přidat regularizer pomocí 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)
Krok 2) Definujte vrstvy
Všechny parametry hustých vrstev byly nastaveny; vše můžete zabalit do proměnné hustá_vrstva pomocí objektu částečné. hustá_vrstva, která používá aktivaci ELU, inicializaci Xavier a regularizaci L2.
## Create the dense layer dense_layer = partial(tf.layers.dense, activation=tf.nn.elu, kernel_initializer=xav_init, kernel_regularizer=l2_regularizer)
Krok 3) Definujte architekturu
Když se podíváte na obrázek architektury, zjistíte, že síť skládá tři vrstvy s výstupní vrstvou. V níže uvedeném kódu propojíte příslušné vrstvy. Například první vrstva vypočítává bodový součin mezi vstupními znaky matice a maticemi obsahujícími 300 vah. Po výpočtu bodového součinu přejde výstup na aktivační funkci Elu. Výstup se stává vstupem další vrstvy, proto jej používáte k výpočtu hidden_2 a tak dále. Násobení matic je pro každou vrstvu stejné, protože používáte stejnou aktivační funkci. Všimněte si, že poslední vrstva, výstupy, neaplikuje aktivační funkci. Dává to smysl, protože se jedná o rekonstruovaný vstup
## 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)
Krok 4) Definujte optimalizaci
Posledním krokem je konstrukce optimalizátoru. Mean Square Error použijete jako ztrátovou funkci. Pokud si vzpomínáte na tutoriál o lineární regresi, víte, že MSE se počítá s rozdílem mezi předpokládaným výstupem a skutečným štítkem. Zde je popiskem prvek, protože model se snaží rekonstruovat vstup. Proto chcete střední hodnotu součtu rozdílu čtverce mezi předpokládaným výstupem a vstupem. Pomocí TensorFlow můžete funkci ztráty kódovat následovně:
loss = tf.reduce_mean(tf.square(outputs - features))
Poté musíte optimalizovat ztrátovou funkci. K výpočtu přechodů se používá optimalizátor Adam. Cílem je minimalizovat ztráty.
## Optimize loss = tf.reduce_mean(tf.square(outputs - features)) optimizer = tf.train.AdamOptimizer(learning_rate) train = optimizer.minimize(loss)
Ještě jedno nastavení před tréninkem modelu. Chcete použít velikost dávky 150, to znamená vložit do potrubí 150 obrázků v každé iteraci. Počet iterací musíte vypočítat ručně. Toto je triviální udělat:
Pokud chcete pokaždé předat 150 obrázků a víte, že v datové sadě je 5000 obrázků, počet iterací se rovná . V pythonu můžete spustit následující kódy a ujistěte se, že výstup je 33:
BATCH_SIZE = 150 ### Number of batches : length dataset / batch size n_batches = horse_x.shape[0] // BATCH_SIZE print(n_batches) 33
Krok 5) Spusťte model
V neposlední řadě vycvičte modelku. Trénujete model se 100 epochami. To znamená, že model uvidí 100krát více obrázků s optimalizovanými hmotnostmi.
Už jste obeznámeni s kódy pro trénování modelu v Tensorflow. Drobný rozdíl je v tom, že data před spuštěním tréninku zadáte potrubím. Model tak trénuje rychleji.
Máte zájem vytisknout ztrátu po deseti epochách, abyste viděli, zda se model něco učí (tj. ztráta se snižuje). Školení trvá 2 až 5 minut v závislosti na hardwaru vašeho stroje.
## 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
Krok 6) Vyhodnoťte model
Nyní, když máte svůj model natrénovaný, je čas jej vyhodnotit. Musíte importovat testovací sadu ze souboru /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'])
POZNÁMKA: Pro Windows stroj, kód se změní na test_data = unpickle(r”E:\cifar-10-batches-py\test_batch”)
Můžete zkusit vytisknout obrázky 13, což je kůň
plot_image(test_x[13], shape=[32, 32], cmap = "Greys_r")
K vyhodnocení modelu použijete hodnotu pixelu tohoto obrázku a uvidíte, zda kodér dokáže rekonstruovat stejný obrázek po zmenšení 1024 pixelů. Všimněte si, že definujete funkci pro vyhodnocení modelu na různých obrázcích. Model by měl lépe fungovat pouze na koních.
Funkce má dva argumenty:
- df: Import testovacích dat
- číslo_obrázku: označte, jaký obrázek chcete importovat
Funkce je rozdělena do tří částí:
- Změňte tvar obrázku na správný rozměr, tj. 1, 1024
- Naplňte model neviditelným obrázkem, zakódujte/dekódujte obrázek
- Vytiskněte skutečný a rekonstruovaný obrázek
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()
Nyní, když je definována vyhodnocovací funkce, můžete se podívat na rekonstruovaný obrázek číslo třináct
reconstruct_image(df =test_x, image_number = 13)
INFO:tensorflow:Restoring parameters from ./model.ckpt Model restored. (1, 1024)
Shrnutí
- Primárním účelem autokodéru je komprimovat vstupní data a poté je dekomprimovat do výstupu, který se podobá původním datům.
- Architektura autokodéru symetrická s pivotní vrstvou nazvanou centrální vrstva.
- Autokodér můžete vytvořit pomocí:
Částečný: pro vytvoření hustých vrstev s typickým nastavením:
tf.layers.dense, activation=tf.nn.elu, kernel_initializer=xav_init, kernel_regularizer=l2_regularizer
hustá_vrstva(): provést násobení matice
loss = tf.reduce_mean(tf.square(outputs - features)) optimizer = tf.train.AdamOptimizer(learning_rate) train = optimizer.minimize(loss)