Co to jest autoenkoder?
Autoencoder jest narzędziem do nauki kodowania danych w efektywny sposób, bez nadzoru. Jest to rodzaj sztucznej sieci neuronowej, która pomaga nauczyć się reprezentacji zestawów danych w celu zmniejszenia wymiarowości poprzez uczenie sieci neuronowej ignorowania szumu sygnału. To świetne narzędzie do odtwarzania danych wejściowych.
Mówiąc prościej, maszyna wykonuje, powiedzmy, obraz i może stworzyć blisko powiązany obraz. Dane wejściowe w tego rodzaju sieci neuronowej są nieoznaczone, co oznacza, że sieć jest zdolna do uczenia się bez nadzoru. Dokładniej, dane wejściowe są kodowane przez sieć, aby skupić się tylko na najbardziej krytycznej funkcji. Jest to jeden z powodów, dla których autoenkoder jest popularny ze względu na redukcję wymiarów. Poza tym autoenkodery mogą być używane do tworzenia generatywnych modeli uczenia się . Na przykład sieć neuronowa może być trenowana za pomocą zestawu twarzy, a następnie może tworzyć nowe twarze.
Z tego samouczka TensorFlow Autoencoder dowiesz się:
- Co to jest autoenkoder?
- Jak działa Autoencoder?
- Przykład skumulowanego autoenkodera
- Zbuduj Autoenkoder za pomocą TensorFlow
- Wstępne przetwarzanie obrazu
- Ustaw estymator zbioru danych
- Zbuduj sieć
Jak działa Autoencoder?
Celem autoenkodera jest uzyskanie przybliżenia danych wejściowych poprzez skupienie się tylko na podstawowych cechach. Możesz pomyśleć, dlaczego po prostu nie nauczysz się kopiować i wklejać dane wejściowe, aby uzyskać wynik. W rzeczywistości autoenkoder to zestaw ograniczeń, które zmuszają sieć do uczenia się nowych sposobów przedstawiania danych, różniących się od zwykłego kopiowania danych wyjściowych.
Typowy autoenkoder jest definiowany za pomocą wejścia, wewnętrznej reprezentacji i wyjścia (przybliżenie wejścia). Uczenie się odbywa się w warstwach dołączonych do wewnętrznej reprezentacji. W rzeczywistości istnieją dwa główne bloki warstw, które wyglądają jak tradycyjna sieć neuronowa. Niewielka różnica polega na tym, że warstwa zawierająca dane wyjściowe musi być równa wartości wejściowej. Na poniższym rysunku oryginalne wejście przechodzi do pierwszego bloku zwanego koderem . Ta wewnętrzna reprezentacja kompresuje (zmniejsza) rozmiar danych wejściowych. W drugim bloku następuje rekonstrukcja wejścia. To jest faza dekodowania.
Model zaktualizuje wagi poprzez zminimalizowanie funkcji straty. Model podlega karze, jeśli dane wyjściowe rekonstrukcji różnią się od danych wejściowych.
Konkretnie, wyobraź sobie obraz o rozmiarze 50x50 (tj. 250 pikseli) i sieć neuronową z tylko jedną ukrytą warstwą złożoną ze stu neuronów. Nauka odbywa się na mapie cech, która jest dwa razy mniejsza niż dane wejściowe. Oznacza to, że sieć musi znaleźć sposób na zrekonstruowanie 250 pikseli z wektorem neuronów równym 100.
Przykład skumulowanego autoenkodera
W tym samouczku dotyczącym autoenkodera dowiesz się, jak używać skumulowanego autoenkodera. Architektura jest podobna do tradycyjnej sieci neuronowej. Dane wejściowe trafiają do warstwy ukrytej w celu skompresowania lub zmniejszenia jej rozmiaru, a następnie docierają do warstw rekonstrukcji. Celem jest uzyskanie obrazu wyjściowego tak zbliżonego do oryginału. Model musi nauczyć się, jak realizować swoje zadanie przy zbiorze ograniczeń, czyli przy niższym wymiarze.
Obecnie autokodery w głębokim uczeniu się są używane głównie do odszumiania obrazu. Wyobraź sobie obraz z zadrapaniami; człowiek wciąż jest w stanie rozpoznać treść. Ideą odszumiania autoenkodera jest dodanie szumu do obrazu, aby zmusić sieć do nauczenia się wzoru kryjącego się za danymi.
Inną przydatną rodziną Autoencoder Deep Learning jest wariacyjny autoenkoder. Ten typ sieci może generować nowe obrazy. Wyobraź sobie, że trenujesz sieć z wizerunkiem mężczyzny; taka sieć może stworzyć nowe twarze.
Zbuduj Autoenkoder za pomocą TensorFlow
W tym samouczku nauczysz się, jak zbudować skumulowany autoenkoder w celu zrekonstruowania obrazu.
Będziesz używać zbioru danych CIFAR-10, który zawiera 60000 kolorowych obrazów 32x32. Zestaw danych Autoencoder jest już podzielony na 50000 obrazów do uczenia i 10000 do testowania. Istnieje maksymalnie dziesięć klas:
- Samolot
- Samochód
- Ptak
- Kot
- Jeleń
- Pies
- Żaba
- Koń
- Statek
- Ciężarówka
Musisz pobrać obrazy z tego adresu URL https://www.cs.toronto.edu/~kriz/cifar.html i rozpakować. Folder dla-10-partie-py zawiera pięć partii danych po 10000 obrazów w przypadkowej kolejności.
Zanim zbudujesz i wytrenujesz model, musisz zastosować pewne przetwarzanie danych. Będziesz postępować w następujący sposób:
- Zaimportuj dane
- Przekonwertuj dane na format czarno-biały
- Dołącz wszystkie partie
- Skonstruuj zbiór danych szkoleniowych
- Skonstruuj wizualizator obrazu
Wstępne przetwarzanie obrazu
Krok 1) Zaimportuj dane.
Zgodnie z oficjalną stroną internetową możesz przesłać dane za pomocą następującego kodu. Kod Autoencoder załaduje dane do słownika wraz z danymi i etykietą . Zauważ, że kod jest funkcją.
import numpy as npimport tensorflow as tfimport pickledef unpickle(file):import picklewith open(file, 'rb') as fo:dict = pickle.load(fo, encoding='latin1')return dict
Krok 2) Przekonwertuj dane na format czarno-biały
Dla uproszczenia dane zostaną przekonwertowane na skalę szarości. Oznacza to, że dla obrazu kolorów jest tylko jeden wymiar na trzy. Większość sieci neuronowych działa tylko z jednym wymiarem wejściowym.
def grayscale(im):return im.reshape(im.shape[0], 3, 32, 32).mean(1).reshape(im.shape[0], -1)
Krok 3) Dołącz wszystkie partie
Po utworzeniu obu funkcji i załadowaniu zestawu danych można napisać pętlę, aby dołączyć dane do pamięci. Jeśli dokładnie sprawdzisz, rozpakowany plik z danymi ma nazwę data_batch_ z liczbą od 1 do 5. Możesz zapętlić pliki i dołączyć je do danych.
Po wykonaniu tego kroku dane dotyczące kolorów zostaną przekonwertowane do formatu skali szarości. Jak widać, dane mają kształt 50000 i 1024. 32 * 32 piksele są teraz spłaszczone do 2014 roku.
# Load the data into memorydata, labels = [], []## Loop over the bfor 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)
Uwaga: zmień „./cifar-10-batches-py/data_batch_” na rzeczywistą lokalizację pliku. Na przykład w przypadku komputera z systemem Windows ścieżka może mieć postać nazwa_pliku = 'E: \ cifar-10-partie-py \ data_batch_' + str (i)
Krok 4) Skonstruuj zbiór danych szkoleniowych
Aby trening był szybszy i łatwiejszy, będziesz trenować model tylko na obrazach koni. Konie są siódmą klasą w danych na etykiecie. Jak wspomniano w dokumentacji zbioru danych CIFAR-10, każda klasa zawiera 5000 obrazów. Możesz wydrukować kształt danych, aby potwierdzić, że istnieje 5.000 obrazów z 1024 kolumnami, jak pokazano w poniższym przykładzie kroku TensorFlow Autoencoder.
horse_i = np.where(y == 7)[0]horse_x = x[horse_i]print(np.shape(horse_x))(5000, 1024)
Krok 5) Skonstruuj wizualizator obrazu
Na koniec konstruujesz funkcję wykreślającą obrazy. Będziesz potrzebował tej funkcji, aby wydrukować zrekonstruowany obraz z autoenkodera.
Łatwym sposobem drukowania obrazów jest użycie obiektu imshow z biblioteki matplotlib. Zwróć uwagę, że musisz przekonwertować kształt danych z 1024 na 32 * 32 (tj. Format obrazu).
# To plot pretty figures%matplotlib inlineimport matplotlibimport matplotlib.pyplot as pltdef plot_image(image, shape=[32, 32], cmap = "Greys_r"):plt.imshow(image.reshape(shape), cmap=cmap,interpolation="nearest")plt.axis("off")
Funkcja przyjmuje 3 argumenty:
- Obraz: wejście
- Kształt: lista, wymiar obrazu
- Cmap: wybierz mapę kolorów. Domyślnie szary
Możesz spróbować wykreślić pierwszy obraz w zestawie danych. Powinieneś zobaczyć mężczyznę na koniu.
plot_image(horse_x[1], shape=[32, 32], cmap = "Greys_r")
Ustaw estymator zbioru danych
W porządku, teraz, gdy zbiór danych jest gotowy do użycia, możesz zacząć korzystać z Tensorflow. Przed zbudowaniem modelu użyjmy estymatora zestawu danych Tensorflow do zasilania sieci.
Zbudujesz zestaw danych z estymatorem TensorFlow. Aby odświeżyć umysł, musisz użyć:
- from_tensor_slices
- powtarzać
- partia
Pełny kod do zbudowania zestawu danych to:
dataset = tf.data.Dataset.from_tensor_slices(x).repeat().batch(batch_size)
Zwróć uwagę, że x to symbol zastępczy o następującym kształcie:
- [Brak, n_inputs]: Ustaw na Brak, ponieważ liczba przesyłanych obrazów do sieci jest równa rozmiarowi wsadu.
Szczegółowe informacje można znaleźć w samouczku dotyczącym regresji liniowej.
Następnie musisz utworzyć iterator. Bez tej linii kodu żadne dane nie przejdą przez potok.
iter = dataset.make_initializable_iterator() # create the iteratorfeatures = iter.get_next()
Teraz, gdy rurociąg jest gotowy, możesz sprawdzić, czy pierwszy obraz jest taki sam jak poprzednio (tj. Mężczyzna na koniu).
Ustawiasz rozmiar partii na 1, ponieważ chcesz zasilić zbiór danych tylko jednym obrazem. Możesz zobaczyć rozmiar danych za pomocą print (sess.run (features) .shape). Równa się (1, 1024). 1 oznacza, że tylko jeden obraz z 1024 jest podawany każdy. Jeśli rozmiar partii jest ustawiony na dwa, przez potok przejdą dwa obrazy. (Nie zmieniaj rozmiaru partii. W przeciwnym razie wystąpi błąd. Tylko jeden obraz naraz może przejść do funkcji plot_image ().
## Parametersn_inputs = 32 * 32BATCH_SIZE = 1batch_size = tf.placeholder(tf.int64)# using a placeholderx = tf.placeholder(tf.float32, shape=[None,n_inputs])## Datasetdataset = tf.data.Dataset.from_tensor_slices(x).repeat().batch(batch_size)iter = dataset.make_initializable_iterator() # create the iteratorfeatures = iter.get_next()## Print the imagewith tf.Session() as sess:# feed the placeholder with datasess.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)
Zbuduj sieć
Czas zbudować sieć. Nauczysz się ułożonego w stos autoenkodera, czyli sieci z wieloma ukrytymi warstwami.
Twoja sieć będzie miała jedną warstwę wejściową z 1024 punktami, tj. 32x32, kształt obrazu.
Blok kodera będzie miał jedną górną ukrytą warstwę z 300 neuronami, warstwę centralną ze 150 neuronami. Blok dekodera jest symetryczny względem kodera. Możesz zwizualizować sieć na poniższym obrazku. Zwróć uwagę, że możesz zmienić wartości warstw ukrytych i środkowych.
Budowanie autoenkodera jest bardzo podobne do każdego innego modelu uczenia głębokiego.
Model utworzysz w następujący sposób:
- Zdefiniuj parametry
- Zdefiniuj warstwy
- Zdefiniuj architekturę
- Zdefiniuj optymalizację
- Uruchom model
- Oceń model
W poprzedniej sekcji dowiedziałeś się, jak utworzyć potok do zasilania modelu, więc nie ma potrzeby ponownego tworzenia zestawu danych. Zbudujesz autoenkoder z czterema warstwami. Używasz inicjalizacji Xaviera. Jest to technika ustawiania początkowych wag równych wariancji danych wejściowych i wyjściowych. Na koniec używasz funkcji aktywacji elu. Funkcję straty regulujesz regulatorem L2.
Krok 1) Zdefiniuj parametry
Pierwszy krok polega na zdefiniowaniu liczby neuronów w każdej warstwie, szybkości uczenia się i hiperparametru regulatora.
Wcześniej częściowo importujesz funkcję. Lepszą metodą jest określenie parametrów warstw zwartych. Poniższy kod definiuje wartości architektury autoencodera. Jak wspomniano wcześniej, autoenkoder ma dwie warstwy, z 300 neuronami w pierwszej warstwie i 150 w drugiej. Ich wartości są przechowywane w n_hidden_1 i n_hidden_2.
Musisz zdefiniować szybkość uczenia się i hiperparametr L2. Wartości są przechowywane w learning_rate i l2_reg
from functools import partial## Encodern_hidden_1 = 300n_hidden_2 = 150 # codings## Decodern_hidden_3 = n_hidden_1n_outputs = n_inputslearning_rate = 0.01l2_reg = 0.0001
Technika inicjalizacji Xaviera jest wywoływana z obiektem xavier_initializer z wkładu estymatora. W tym samym estymatorze możesz dodać regularyzator za pomocą l2_regularizer
## Define the Xavier initializationxav_init = tf.contrib.layers.xavier_initializer()## Define the L2 regularizerl2_regularizer = tf.contrib.layers.l2_regularizer(l2_reg)
Krok 2) Zdefiniuj warstwy
Wszystkie parametry warstw zwartych zostały ustawione; możesz spakować wszystko w zmiennej dense_layer, używając obiektu częściowego. dense_layer, który wykorzystuje aktywację ELU, inicjalizację Xaviera i regularyzację L2.
## Create the dense layerdense_layer = partial(tf.layers.dense,activation=tf.nn.elu,kernel_initializer=xav_init,kernel_regularizer=l2_regularizer)
Krok 3) Zdefiniuj architekturę
Jeśli spojrzysz na obraz architektury, zauważysz, że sieć układa trzy warstwy z warstwą wyjściową. W poniższym kodzie łączysz odpowiednie warstwy. Na przykład pierwsza warstwa oblicza iloczyn skalarny między cechami macierzy wejściowej a macierzami zawierającymi 300 wag. Po obliczeniu iloczynu skalarnego wyjście przechodzi do funkcji aktywacji Elu. Dane wyjściowe stają się danymi wejściowymi następnej warstwy, dlatego używasz ich do obliczania hidden_2 i tak dalej. Mnożenie macierzy jest takie samo dla każdej warstwy, ponieważ używasz tej samej funkcji aktywacji. Zwróć uwagę, że ostatnia warstwa, wyjścia, nie stosuje funkcji aktywacji. Ma to sens, ponieważ jest to zrekonstruowany wkład
## Make the mat mulhidden_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) Zdefiniuj optymalizację
Ostatnim krokiem jest skonstruowanie optymalizatora. Używasz średniej kwadratowej błędu jako funkcji straty. Jeśli przypomnisz sobie samouczek dotyczący regresji liniowej, wiesz, że MSE jest obliczane z różnicą między przewidywaną wartością wyjściową a rzeczywistą etykietą. Tutaj etykieta jest funkcją, ponieważ model próbuje zrekonstruować dane wejściowe. Dlatego chcesz średnią z sumy różnicy kwadratów między przewidywaną wydajnością a danymi wejściowymi. Dzięki TensorFlow możesz zakodować funkcję utraty w następujący sposób:
loss = tf.reduce_mean(tf.square(outputs - features))
Następnie musisz zoptymalizować funkcję strat. Używasz Adama Optimizer do obliczania gradientów. Zadaniem celu jest zminimalizowanie straty.
## Optimizeloss = tf.reduce_mean(tf.square(outputs - features))optimizer = tf.train.AdamOptimizer(learning_rate)train = optimizer.minimize(loss)
Jeszcze jedno ustawienie przed treningiem modelu. Chcesz użyć partii o rozmiarze 150, czyli zasilać potok 150 obrazami w każdej iteracji. Musisz ręcznie obliczyć liczbę iteracji. To trywialne:
Jeśli chcesz przesłać 150 obrazów za każdym razem i wiesz, że w zestawie danych jest 5000 obrazów, liczba iteracji jest równa. W Pythonie możesz uruchomić następujące kody i upewnić się, że wynik ma wartość 33:
BATCH_SIZE = 150### Number of batches : length dataset / batch sizen_batches = horse_x.shape[0] // BATCH_SIZEprint(n_batches)33
Krok 5) Uruchom model
Na koniec wytrenuj model. Trenujesz model w 100 epokach. Oznacza to, że model będzie widział 100 razy więcej obrazów, aby zoptymalizować wagę.
Znasz już kody do trenowania modelu w Tensorflow. Niewielka różnica polega na przesłaniu danych przed uruchomieniem treningu. W ten sposób model trenuje szybciej.
Jesteś zainteresowany wydrukowaniem straty po dziesięciu epokach, aby sprawdzić, czy model się czegoś uczy (tj. Strata maleje). Szkolenie trwa od 2 do 5 minut, w zależności od sprzętu komputerowego.
## Set paramsn_epochs = 100## Call Saver to save the model and re-use it later during evaluationsaver = tf.train.Saver()with tf.Session() as sess:sess.run(tf.global_variables_initializer())# initialise iterator with train datasess.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 shownprint("\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.45510 Train MSE: 1672.67620 Train MSE: 1514.70930 Train MSE: 1404.311840 Train MSE: 1425.05850 Train MSE: 1479.063160 Train MSE: 1609.525970 Train MSE: 1482.322380 Train MSE: 1445.703590 Train MSE: 1453.8597Model saved in path: ./model.ckpt
Krok 6) Oceń model
Teraz, gdy masz już wytrenowany model, czas go ocenić. Musisz zaimportować testowy sert z pliku / cifar-10-partie-py /.
test_data = unpickle('./cifar-10-batches-py/test_batch')test_x = grayscale(test_data['data'])#test_labels = np.array(test_data['labels'])
UWAGA: w przypadku komputera z systemem Windows kod staje się test_data = unpickle (r "E: \ cifar-10-partie-py \ test_batch")
Możesz spróbować wydrukować obrazy 13, które przedstawiają konia
plot_image(test_x[13], shape=[32, 32], cmap = "Greys_r")
Aby ocenić model, użyjesz wartości piksela tego obrazu i zobaczysz, czy koder może zrekonstruować ten sam obraz po zmniejszeniu o 1024 piksele. Zwróć uwagę, że definiujesz funkcję oceny modelu na różnych obrazach. Model powinien działać lepiej tylko na koniach.
Funkcja przyjmuje dwa argumenty:
- df: Importuj dane testowe
- image_number: wskaż, jaki obraz zaimportować
Funkcja podzielona jest na trzy części:
- Zmień kształt obrazu do odpowiedniego wymiaru, tj. 1, 1024
- Nakarm model niewidocznym obrazem, zakoduj / zdekoduj obraz
- Wydrukuj rzeczywisty i zrekonstruowany obraz
def reconstruct_image(df, image_number = 1):## Part 1: Reshape the image to the correct dimension i.e 1, 1024x_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 imagewith 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 imageoutputs_val = outputs.eval()print(outputs_val.shape)fig = plt.figure()# Plot realax1 = fig.add_subplot(121)plot_image(x_test_1, shape=[32, 32], cmap = "Greys_r")# Plot estimatedax2 = fig.add_subplot(122)plot_image(outputs_val, shape=[32, 32], cmap = "Greys_r")plt.tight_layout()fig = plt.gcf()
Teraz, gdy funkcja oceny jest zdefiniowana, możesz spojrzeć na zrekonstruowany obraz numer trzynaście
reconstruct_image(df =test_x, image_number = 13)
INFO:tensorflow:Restoring parameters from ./model.ckptModel restored.(1, 1024)
Podsumowanie
Głównym celem autoenkodera jest kompresja danych wejściowych, a następnie dekompresowanie ich do postaci wyjściowej, która wygląda bardzo podobnie do oryginalnych danych.
Architektura autoenkodera symetrycznego z warstwą obrotową zwaną warstwą centralną.
Możesz stworzyć autoenkoder używając:
- Częściowe: do tworzenia gęstych warstw przy typowym ustawieniu:
-
tf.layers.dense,activation=tf.nn.elu,kernel_initializer=xav_init,kernel_regularizer=l2_regularizer
- dense_layer (): aby wykonać mnożenie macierzy
możesz zdefiniować funkcję straty i optymalizację za pomocą:
loss = tf.reduce_mean(tf.square(outputs - features))optimizer = tf.train.AdamOptimizer(learning_rate)train = optimizer.minimize(loss)
Uruchom ostatnio sesję, aby wytrenować model.