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í.

Práce s Autoencoderem
Práce s Autoencoderem

Práce s Autoencoderem

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ě:

  1. Importujte data
  2. Převeďte data do černobílého formátu
  3. Připojte všechny dávky
  4. Sestavte trénovací datovou sadu
  5. 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")

Vytvořte vizualizér obrázků

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)

Nastavit odhad datové sady

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.

Vybudujte síť
Budování sítě pro Autoencoder

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ů:

  1. Definujte parametry
  2. Definujte vrstvy
  3. Definujte architekturu
  4. Definujte optimalizaci
  5. Spusťte model
  6. 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")

Vyhodnoťte model

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í:

  1. Změňte tvar obrázku na správný rozměr, tj. 1, 1024
  2. Naplňte model neviditelným obrázkem, zakódujte/dekódujte obrázek
  3. 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)

Vyhodnoťte model

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

  • Ztrátovou funkci a optimalizaci můžete definovat pomocí:
  • loss = tf.reduce_mean(tf.square(outputs - features))
    optimizer = tf.train.AdamOptimizer(learning_rate)
    train  = optimizer.minimize(loss)
    
  • Poslední spusťte relaci pro trénování modelu.