Автоэнкодер TensorFlow: набор данных с примером глубокого обучения

Содержание:

Anonim

Что такое автоэнкодер?

Автоассоциатор является инструментом для изучения данных эффективного кодирования в неконтролируемой манере. Это тип искусственной нейронной сети, которая помогает вам изучить представление наборов данных для уменьшения размерности, обучая нейронную сеть игнорировать шум сигнала. Это отличный инструмент для воссоздания ввода.

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

В этом руководстве по автоэнкодеру TensorFlow вы узнаете:

  • Что такое автоэнкодер?
  • Как работает автоэнкодер?
  • Пример составного автоэнкодера
  • Создайте автоэнкодер с помощью TensorFlow
  • Предварительная обработка изображений
  • Установить оценщик набора данных
  • Постройте сеть

Как работает автоэнкодер?

Назначение автоэнкодера - приблизить ввод, сосредоточив внимание только на основных функциях. Вы можете подумать, почему бы просто не научиться копировать и вставлять ввод для получения вывода. Фактически, автоэнкодер - это набор ограничений, которые заставляют сеть изучать новые способы представления данных, отличные от простого копирования вывода.

Типичный автокодировщик определяется входом, внутренним представлением и выходом (приближением входа). Обучение происходит в слоях, прикрепленных к внутреннему представлению. Фактически, есть два основных блока слоев, которые выглядят как традиционная нейронная сеть. Небольшая разница в том, что слой, содержащий выход, должен быть равен входному. На картинке ниже исходный ввод поступает в первый блок, называемый кодировщиком . Это внутреннее представление сжимает (уменьшает) размер ввода. Во втором блоке происходит реконструкция входа. Это этап декодирования.

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

Модель обновит веса, минимизируя функцию потерь. Модель получает штраф, если результат реконструкции отличается от входного.

Конкретно, представьте себе изображение размером 50x50 (т. Е. 250 пикселей) и нейронную сеть с одним скрытым слоем, состоящим из ста нейронов. Обучение осуществляется на карте функций, которая в два раза меньше входной. Это означает, что сети необходимо найти способ восстановить 250 пикселей, используя только вектор нейронов, равный 100.

Пример составного автоэнкодера

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

В настоящее время автоэнкодеры в глубоком обучении в основном используются для шумоподавления изображения. Представьте себе изображение с царапинами; человек все еще может распознать контент. Идея автоэнкодера с шумоподавлением состоит в том, чтобы добавить к изображению шум, чтобы заставить сеть изучить закономерность, лежащую в основе данных.

Другое полезное семейство Autoencoder Deep Learning - вариационный автоэнкодер. Этот тип сети может генерировать новые изображения. Представьте, что вы тренируете сеть с изображением мужчины; такая сеть может создавать новые лица.

Создайте автоэнкодер с помощью TensorFlow

В этом руководстве вы узнаете, как создать составной автокодер для восстановления изображения.

Вы будете использовать набор данных CIFAR-10, который содержит 60000 цветных изображений 32x32. Набор данных Autoencoder уже разделен на 50000 изображений для обучения и 10000 изображений для тестирования. Всего существует до десяти классов:

  • Самолет
  • Автомобиль
  • Птица
  • Кот
  • Олень
  • Собака
  • Лягушка
  • Лошадь
  • Корабль
  • Грузовая машина

Вам необходимо загрузить изображения по этому URL-адресу https://www.cs.toronto.edu/~kriz/cifar.html и разархивировать его. Папка для-10-batches-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 ниже.

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 (sessions.run (features) .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 нейронами. Блок декодера симметричен кодеру. Вы можете визуализировать сеть на картинке ниже. Обратите внимание, что вы можете изменить значения скрытых и центральных слоев.

Построение сети для автоэнкодера

Создание автоэнкодера очень похоже на любую другую модель глубокого обучения.

Вы создадите модель, выполнив следующие действия:

  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 из contrib оценщика. В том же оценщике вы можете добавить регуляризатор с 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) Определите слои

Заданы все параметры плотных слоев; вы можете упаковать все в переменную density_layer, используя партиал объекта. density_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 для вычисления градиентов. Целевая функция - минимизировать потери.

## 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
  • density_layer (): для умножения матриц

вы можете определить функцию потерь и оптимизацию с помощью:

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

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