Автокодер TensorFlow: набір даних із прикладом глибокого навчання

Зміст:

Anonim

Що таке автокодер?

Автоассоціатор є інструментом для вивчення даних ефективного кодування в неконтрольованої манері. Це тип штучної нейронної мережі, яка допомагає вивчити подання наборів даних для зменшення розмірності, навчаючи нейронну мережу ігнорувати шум сигналу. Це чудовий інструмент для відтворення вхідних даних.

Простими словами, машина робить, скажімо, зображення, і може створити тісно пов’язану картину. Вхідні дані в такій нейронній мережі не мають маркування, тобто мережа здатна навчатися без нагляду. Точніше, вхід кодується мережею, щоб зосередитись лише на найважливішій характеристиці. Це одна з причин, чому автокодер популярний для зменшення розмірності. Крім того, автокодери можуть бути використані для створення генеративних моделей навчання . Наприклад, нейронну мережу можна навчити з набором граней, а потім створити нові грані.

У цьому посібнику з автоматичного кодування TensorFlow ви дізнаєтесь:

  • Що таке автокодер?
  • Як працює Autoencoder?
  • Приклад автоматичного кодування з накопиченням
  • Створіть автокодер за допомогою TensorFlow
  • Попередня обробка зображень
  • Встановити оцінювач набору даних
  • Побудуйте мережу

Як працює Autoencoder?

Призначення автокодера полягає в отриманні апроксимації вхідних даних, зосереджуючись лише на основних характеристиках. Ви можете подумати, чому б просто не навчитися копіювати та вставляти вхідні дані для отримання вихідних даних. Насправді автокодер - це набір обмежень, які змушують мережу вивчати нові способи представлення даних, відмінних від простого копіювання вихідних даних.

Типовий автокодер визначається із входом, внутрішнім поданням та виходом (наближення введення). Навчання відбувається в шарах, прикріплених до внутрішнього подання. Насправді є два основних блоки шарів, що виглядає як традиційна нейронна мережа. Невелика різниця полягає в тому, що шар, що містить вихідні дані, повинен дорівнювати введеному. На малюнку нижче оригінальний вхід надходить у перший блок, який називається кодером . Це внутрішнє подання стискає (зменшує) розмір вводу. У другому блоці відбувається реконструкція вводу. Це фаза декодування.

Робота автокодера

Модель оновить ваги, мінімізуючи функцію втрат. Модель карається, якщо вихід реконструкції відрізняється від вхідного.

По суті, уявіть собі зображення розміром 50x50 (тобто 250 пікселів) і нейронну мережу з лише одним прихованим шаром, що складається зі ста нейронів. Навчання виконується на карті об’єктів, яка в два рази менша за введену. Це означає, що мережі потрібно знайти спосіб відновити 250 пікселів лише з вектором нейронів, рівним 100.

Приклад автоматичного кодування з накопиченням

У цьому навчальному посібнику з Autoencoder ви дізнаєтесь, як користуватися складеним автокодером. Архітектура схожа на традиційну нейронну мережу. Вхідні дані надходять на прихований шар для стиснення або зменшення його розміру, а потім досягають шарів відновлення. Завдання полягає у створенні вихідного зображення, наближеного до оригіналу. Модель повинна вивчити спосіб досягнення свого завдання за набору обмежень, тобто з меншим виміром.

У наш час автокодери в системі глибокого навчання в основному використовуються для позначення зображення. Уявіть собі зображення з подряпинами; людина все ще здатна розпізнати зміст. Ідея відключення автокодера полягає в додаванні шуму до зображення, щоб змусити мережу вивчити шаблон, що лежить в основі даних.

Іншим корисним сімейством глибокого навчання 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) Імпортуйте дані.

Згідно з офіційним веб-сайтом, ви можете завантажити дані з таким кодом. Код автокодера завантажує дані у словник із даними та міткою . Зверніть увагу, що код є функцією.

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 зображень. Ви можете роздрукувати форму даних, щоб підтвердити наявність 5000 зображень із 1024 стовпцями, як показано на наступному етапі прикладу автокодера TensorFlow.

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. Це техніка встановлення початкових ваг, рівних дисперсії як вхідних, так і вихідних показників. Нарешті, ви використовуєте функцію активації елю. Ви регулюєте функцію втрат за допомогою регулятора 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, який використовує активацію 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. Вихід стає входом для наступного шару, тому ви використовуєте його для обчислення прихованих_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)) 

Потім вам потрібно оптимізувати функцію втрат. Ви використовуєте оптимізатор Адама для обчислення градієнтів. Цільовою функцією є мінімізація збитків.

## 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
  • щільний_шар (): зробити множення матриці

Ви можете визначити функцію втрат та оптимізацію за допомогою:

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

Останній запуск сесії для навчання моделі.