TensorFlow Autoencoder: Набор от данни с пример за дълбоко обучение

Съдържание:

Anonim

Какво е Autoencoder?

Един Autoencoder е инструмент за изучаване на кодиране на данни ефективно в неконтролирана начин. Това е вид изкуствена невронна мрежа, която ви помага да научите представянето на набори от данни за намаляване на размерите чрез обучение на невронната мрежа да игнорира шума на сигнала. Това е чудесен инструмент за пресъздаване на вход.

С прости думи, машината прави, да кажем изображение, и може да създаде тясно свързана картина. Входът в този вид невронна мрежа е немаркиран, което означава, че мрежата може да учи без надзор. По-точно, входът се кодира от мрежата, за да се фокусира само върху най-критичната характеристика. Това е една от причините автоенкодерът да е популярен за намаляване на размерите. Освен това автокодерите могат да се използват за създаване на генеративни модели на обучение . Например, невронната мрежа може да бъде обучена с набор от лица и след това може да създаде нови лица.

В този урок за TensorFlow Autoencoder ще научите:

  • Какво е Autoencoder?
  • Как работи Autoencoder?
  • Пример за подреден автокодер
  • Изградете автокодер с TensorFlow
  • Предварителна обработка на изображения
  • Задайте оценител на набори от данни
  • Изградете мрежата

Как работи Autoencoder?

Целта на автокодера е да създаде приближение на входа, като се фокусира само върху основните характеристики. Може би си мислите защо просто не се научите как да копирате и поставите входа, за да произведете изхода. Всъщност, автокодерът е набор от ограничения, които принуждават мрежата да научи нови начини за представяне на данните, различни от простото копиране на изхода.

Типичният автокодер се дефинира с вход, вътрешно представяне и изход (приближение на входа). Обучението се извършва в слоевете, прикрепени към вътрешното представяне. Всъщност има два основни блока от слоеве, които изглеждат като традиционна невронна мрежа. Малката разлика е, че слоят, съдържащ изхода, трябва да бъде равен на входа. На снимката по-долу оригиналният вход влиза в първия блок, наречен енкодер . Това вътрешно представяне компресира (намалява) размера на входа. Във втория блок се извършва реконструкция на входа. Това е фазата на декодиране.

Работа на Autoencoder

Моделът ще актуализира тежестите, като минимизира функцията на загуба. Моделът се наказва, ако изходът за реконструкция е различен от входа.

Конкретно си представете картина с размер 50x50 (т.е. 250 пиксела) и невронна мрежа само с един скрит слой, съставен от сто неврона. Обучението се извършва на карта с характеристики, която е два пъти по-малка от въведената. Това означава, че мрежата трябва да намери начин да възстанови 250 пиксела само с вектор неврони, равен на 100.

Пример за подреден автокодер

В този урок за Autoencoder ще научите как да използвате подреден autoencoder. Архитектурата е подобна на традиционната невронна мрежа. Входът отива към скрит слой, за да бъде компресиран или да намали неговия размер, и след това достига до реконструиращите слоеве. Целта е да се получи изходно изображение, близко до оригинала. Моделът трябва да научи начин да постигне своята задача при набор от ограничения, т.е. с по-ниско измерение.

В днешно време автоенкодерите в дълбокото обучение се използват главно за деноизиране на изображение. Представете си изображение с драскотини; човек все още е в състояние да разпознае съдържанието. Идеята на denoising autoencoder е да добави шум към картината, за да принуди мрежата да научи модела зад данните.

Другото полезно семейство Autoencoder Deep Learning е вариационен autoencoder. Този тип мрежа може да генерира нови изображения. Представете си, че тренирате мрежа с образа на мъж; такава мрежа може да създаде нови лица.

Изградете автокодер с TensorFlow

В този урок ще научите как да изградите подреден автокодер за реконструкция на изображение.

Ще използвате набора от данни CIFAR-10, който съдържа 60000 цветни изображения 32x32. Наборът от данни на Autoencoder вече е разделен между 50000 изображения за обучение и 10000 за тестване. Има до десет класа:

  • Самолет
  • Автомобилни
  • Птица
  • Котка
  • Елен
  • Куче
  • Жаба
  • Кон
  • Кораб
  • Камион

Трябва да изтеглите изображенията в този URL адрес https://www.cs.toronto.edu/~kriz/cifar.html и да ги разархивирате. Папката for-10-batch-py съдържа пет партиди данни с по 10000 изображения в произволен ред.

Преди да изградите и обучите своя модел, трябва да приложите някаква обработка на данни. Ще продължите по следния начин:

  1. Импортирайте данните
  2. Преобразувайте данните в черно-бял формат
  3. Добавете всички партиди
  4. Изградете набора от данни за обучение
  5. Изградете визуализатор на изображения

Предварителна обработка на изображения

Стъпка 1) Импортирайте данните.

Според официалния уебсайт можете да качите данните със следния код. Кодът на Autoencoder ще зареди данните в речник с данните и етикета . Имайте предвид, че кодът е функция.

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

Стъпка 2) Преобразувайте данните в черно-бял формат

За по-голяма простота ще преобразувате данните в скала на сивото. Тоест само с едно измерение спрямо три за цветно изображение. Повечето от невронната мрежа работи само с едно измерение.

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

Стъпка 3) Добавете всички партиди

Сега, когато и двете функции са създадени и наборът от данни е зареден, можете да напишете цикъл, за да добавите данните в паметта. Ако проверите внимателно, разархивираният файл с данните се нарича data_batch_ с номер от 1 до 5. Можете да преминете през файловете и да го добавите към данни.

Когато тази стъпка приключи, преобразувате данните за цветовете във формат на сивата скала. Както можете да видите, формата на данните е 50000 и 1024. 32 * 32 пиксела вече са изравнени към 2014 г.

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

Забележка: Променете „./cifar-10-batches-py/data_batch_“ на действителното местоположение на вашия файл. Например за Windows машина, пътят може да бъде filename = 'E: \ cifar-10-batches-py \ data_batch_' + str (i)

Стъпка 4) Изградете набора от данни за обучение

За да направите тренировката по-бърза и по-лесна, ще тренирате модел само на изображения на коне. Конете са седми клас от данните на етикета. Както е споменато в документацията на набора от данни CIFAR-10, всеки клас съдържа 5000 изображения. Можете да отпечатате формата на данните, за да потвърдите, че има 5.000 изображения с 1024 колони, както е показано в долната стъпка за пример на TensorFlow Autoencoder.

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

Стъпка 5) Изградете визуализатор на изображения

Накрая конструирате функция за нанасяне на изображенията. Тази функция ще ви е необходима, за да отпечатате реконструираното изображение от автокодера.

Лесен начин за отпечатване на изображения е използването на обекта imshow от библиотеката matplotlib. Имайте предвид, че трябва да конвертирате формата на данните от 1024 в 32 * 32 (т.е. формат на изображение).

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

Функцията отнема 3 аргумента:

  • Изображение: входът
  • Форма: списък, размерът на изображението
  • Cmap: изберете цветната карта. По подразбиране сиво

Можете да опитате да нанесете първото изображение в набора от данни. Трябва да видите човек на кон.

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

Задайте оценител на набори от данни

Добре, сега, когато наборът от данни е готов за използване, можете да започнете да използвате Tensorflow. Преди да изградим модела, нека използваме оценителя на набори от данни на Tensorflow за захранване на мрежата.

Ще изградите набор от данни с оценител TensorFlow. За да освежите ума си, трябва да използвате:

  • from_tensor_slices
  • повторете
  • партида

Пълният код за изграждане на набора от данни е:

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

Имайте предвид, че x е заместител със следната форма:

  • [None, n_inputs]: Задава се на None, тъй като броят на подаването на изображения към мрежата е равен на размера на партидата.

за подробности вижте урока за линейна регресия.

След това трябва да създадете итератора. Без този ред код няма данни да преминават през конвейера.

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

След като тръбопроводът е готов, можете да проверите дали първото изображение е същото като преди (т.е. човек на кон).

Задавате размера на партидата на 1, защото искате да захранвате набора от данни само с едно изображение. Можете да видите измерението на данните с print (sess.run (функции) .shape). Тя е равна на (1, 1024). 1 означава, че само едно изображение с 1024 се подава всяко. Ако размерът на партидата е зададен на две, тогава две изображения ще преминат през тръбопровода. (Не променяйте размера на партидата. В противен случай това ще доведе до грешка. Само едно изображение наведнъж може да премине към функцията 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)

Изградете мрежата

Време е да изградим мрежата. Ще обучите подреден автокодер, т.е. мрежа с множество скрити слоеве.

Вашата мрежа ще има един входен слой с 1024 точки, т.е. 32x32, формата на изображението.

Кодиращият блок ще има един горен скрит слой с 300 неврона, централен слой със 150 неврона. Декодерният блок е симетричен на енкодера. Можете да визуализирате мрежата на снимката по-долу. Имайте предвид, че можете да промените стойностите на скритите и централните слоеве.

Изграждане на мрежа за Autoencoder

Изграждането на автокодер е много подобно на всеки друг модел на дълбоко обучение.

Ще конструирате модела, като следвате тези стъпки:

  1. Определете параметрите
  2. Определете слоевете
  3. Определете архитектурата
  4. Определете оптимизацията
  5. Стартирайте модела
  6. Оценете модела

В предишния раздел научихте как да създадете конвейер за подаване на модела, така че няма нужда да създавате още веднъж набора от данни. Ще конструирате автокодер с четири слоя. Използвате инициализацията на Xavier. Това е техника за задаване на първоначалните тегла, равни на дисперсията както на входа, така и на изхода. Накрая използвате функцията за активиране на elu. Вие регулирате функцията на загубите с регулатор L2.

Стъпка 1) Дефинирайте параметрите

Първата стъпка предполага да се определи броят на невроните във всеки слой, скоростта на обучение и хиперпараметърът на регулатора.

Преди това импортирате функцията частично. По-добър метод е да се определят параметрите на плътните слоеве. Кодът по-долу определя стойностите на архитектурата на автоенкодера. Както е изброено по-горе, автокодерът има два слоя, с 300 неврона в първите слоеве и 150 във вторите слоеве. Стойностите им се съхраняват в n_hidden_1 и n_hidden_2.

Трябва да дефинирате скоростта на обучение и хиперпараметъра L2. Стойностите се съхраняват в learning_rate и 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

Техниката за инициализация на Xavier се извиква с обекта xavier_initializer от приноса на оценителя. В същия оценител можете да добавите регулатора с l2_regularizer

## Define the Xavier initializationxav_init = tf.contrib.layers.xavier_initializer()## Define the L2 regularizerl2_regularizer = tf.contrib.layers.l2_regularizer(l2_reg)

Стъпка 2) Определете слоевете

Всички параметри на плътните слоеве са зададени; можете да опаковате всичко в променливата thick_layer, като използвате частичния обект. thick_layer, който използва ELU активиране, Xavier инициализация и L2 регуларизация.

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

Стъпка 3) Определете архитектурата

Ако погледнете картината на архитектурата, ще забележите, че мрежата подрежда три слоя с изходен слой. В кода по-долу свързвате съответните слоеве. Например, първият слой изчислява точковото произведение между входните матрични характеристики и матриците, съдържащи 300 тегла. След като точният продукт се изчисли, изходът отива към функцията за активиране на Elu. Изходът се превръща в вход за следващия слой, затова го използвате, за да изчислите hidden_2 и т.н. Умножението на матриците е еднакво за всеки слой, защото използвате една и съща функция за активиране. Имайте предвид, че последният изходен слой не прилага функция за активиране. Има смисъл, защото това е реконструираният вход

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

Стъпка 4) Определете оптимизацията

Последната стъпка е изграждането на оптимизатора. Използвате средната квадратна грешка като функция за загуба. Ако си припомните урока за линейна регресия, знаете, че MSE се изчислява с разликата между прогнозирания изход и реалния етикет. Тук етикетът е характеристиката, защото моделът се опитва да реконструира входа. Следователно искате средната стойност на сумата на разликата на квадрата между прогнозирания изход и входа. С TensorFlow можете да кодирате функцията за загуба, както следва:

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

След това трябва да оптимизирате функцията за загуба. Използвате Adam optimizer за изчисляване на градиентите. Целевата функция е да се минимизират загубите.

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

Още една настройка преди тренировка на модела. Искате да използвате партиден размер от 150, тоест захранвайте тръбопровода със 150 изображения всяка итерация. Трябва ръчно да изчислите броя на итерациите. Това е тривиално да се направи:

Ако искате да предадете 150 изображения всеки път и знаете, че в набора от данни има 5000 изображения, броят на итерациите е равен на. В python можете да изпълните следните кодове и да се уверите, че изходът е 33:

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

Стъпка 5) Стартирайте модела

Не на последно място, обучете модела. Тренирате модела със 100 епохи. Тоест, моделът ще види 100 пъти изображенията до оптимизирани тегла.

Вече сте запознати с кодовете за обучение на модел в Tensorflow. Малката разлика е да изпратите данните преди провеждането на обучението. По този начин моделът тренира по-бързо.

Интересувате се да отпечатате загубата след десет епохи, за да видите дали моделът научава нещо (т.е. загубата намалява). Обучението отнема 2 до 5 минути, в зависимост от хардуера на вашата машина.

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

Стъпка 6) Оценете модела

Сега, когато сте обучили модела си, е време да го оцените. Трябва да импортирате тестовия серт от файла / 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'])

ЗАБЕЛЕЖКА: За машина с Windows кодът става test_data = unpickle (r "E: \ cifar-10-batches-py \ test_batch")

Можете да опитате да отпечатате изображенията 13, което е кон

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

За да оцените модела, ще използвате пикселната стойност на това изображение и ще видите дали енкодерът може да реконструира същото изображение след свиване на 1024 пиксела. Имайте предвид, че вие ​​дефинирате функция за оценка на модела на различни снимки. Моделът трябва да работи по-добре само на коне.

Функцията взема два аргумента:

  • df: Импортиране на тестовите данни
  • image_number: посочете какво изображение да импортирате

Функцията е разделена на три части:

  1. Преоформете изображението до правилното измерение, т.е. 1, 1024
  2. Нахранете модела с невидимото изображение, кодирайте / декодирайте изображението
  3. Отпечатайте реалното и реконструирано изображение
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()

Сега, когато функцията за оценка е дефинирана, можете да видите реконструираното изображение номер тринадесет

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

Обобщение

Основната цел на автокодера е да компресира входните данни и след това да ги компресира в изход, който прилича отблизо на оригиналните данни.

Архитектурата на автокодер, симетричен с шарнирен слой, наречен централен слой.

Можете да създадете автокодера, като използвате:

  • Частично: за създаване на плътни слоеве с типичната настройка:
  • tf.layers.dense,activation=tf.nn.elu,kernel_initializer=xav_init,kernel_regularizer=l2_regularizer
  • thick_layer (): за умножаване на матрицата

можете да дефинирате функцията за загуба и оптимизацията с:

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

Последно изпълнете сесия за обучение на модела.