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

by moiseevrus

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

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

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

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

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

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

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

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

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

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

Самолет
Автомобиль
Птица
Кошка
Олень
Собака
Лягушка
Лошадь
Судно
Грузовая машина
Вам необходимо загрузить изображения по этому URL-адресу https://www.cs.toronto.edu/~kriz/cifar.html и разархивировать его. Папка for-10-batches-py содержит пять пакетов данных по 10000 изображений в каждом в случайном порядке.

Перед построением и обучением модели необходимо выполнить некоторую обработку данных. Вы будете действовать следующим образом:

Импорт данных
Преобразование данных в черно-белый формат
Добавить все пакеты
Создайте обучающий набор данных
Создайте визуализатор изображений
Предварительная обработка изображения
Шаг 1) Импорт данных

Согласно официальному сайту, вы можете загрузить данные с помощью следующего кода. Код автоэнкодера загрузит данные в словарь с данными и меткой . Обратите внимание, что код является функцией.

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

Шаг 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 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)

римечание. Измените «./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 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”)

Функция принимает 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]: установите значение «Нет», так как количество изображений, передаваемых в сеть, равно размеру пакета.
подробности см. в учебнике по линейной регрессии.

После этого вам нужно создать итератор. Без этой строки кода никакие данные не будут проходить через конвейер.

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

Теперь, когда конвейер готов, вы можете проверить, является ли первое изображение таким же, как и раньше (т. е. человек на лошади).

Вы установили размер пакета равным 1, потому что хотите загрузить в набор данных только одно изображение. Вы можете увидеть размер данных с помощью print(sess.run(features).shape). Он равен (1, 1024). 1 означает, что подается только одно изображение с разрешением 1024. Если размер пакета установлен равным двум, то два изображения будут проходить через конвейер. (Не изменяйте размер пакета. В противном случае будет выдана ошибка. В функцию plot_image() может передаваться только одно изображение за раз.

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

Создайте сеть
Пришло время построить сеть. Вы будете обучать многоуровневый автоэнкодер, то есть сеть с несколькими скрытыми слоями.

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

Блок кодировщика будет иметь один верхний скрытый слой с 300 нейронами и центральный слой со 150 нейронами. Блок декодера симметричен кодеру. Вы можете визуализировать сеть на картинке ниже. Обратите внимание, что вы можете изменить значения скрытых и центральных слоев.

Построение сети для Autoencoder
Построение сети для Autoencoder

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

Вы построите модель, выполнив следующие шаги:

Определите параметры
Определите слои
Определить архитектуру
Определите оптимизацию
Запустите модель
Оценить модель
В предыдущем разделе вы узнали, как создать конвейер для подачи модели, поэтому нет необходимости создавать набор данных еще раз. Вы создадите автоэнкодер с четырьмя слоями. Вы используете инициализацию Xavier. Это метод установки начальных весов равными дисперсии входных и выходных данных. Наконец, вы используете функцию активации elu. Вы регуляризуете функцию потерь с помощью регуляризатора L2.

Шаг 1) Определите параметры

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

Перед этим вы импортируете функцию частично. Это лучший метод определения параметров плотных слоев. В приведенном ниже коде определяются значения архитектуры автоэнкодера. Как упоминалось ранее, автоэнкодер имеет два слоя: 300 нейронов в первых слоях и 150 во вторых слоях. Их значения хранятся в n_hidden_1 и n_hidden_2.

Вам необходимо определить скорость обучения и гиперпараметр L2. Значения хранятся в Learning_rate и 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

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

Шаг 2) Определите слои

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

## Create the dense layer
dense_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 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)

Шаг 4) Определите оптимизацию

Последним шагом является создание оптимизатора. Вы используете среднеквадратичную ошибку в качестве функции потерь. Если вы помните учебник по линейной регрессии, вы знаете, что MSE вычисляется с разницей между прогнозируемым результатом и реальной меткой. Здесь метка является функцией, потому что модель пытается восстановить входные данные. Следовательно, вам нужно среднее значение суммы разности квадратов между прогнозируемым выходом и входом. С помощью TensorFlow вы можете закодировать функцию потерь следующим образом:

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

Затем вам нужно оптимизировать функцию потерь. Вы используете оптимизатор Adam для вычисления градиентов. Целевой функцией является минимизация потерь.

## Optimize
loss = 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 size
n_batches = horse_x.shape[0] // BATCH_SIZE
print(n_batches)
33

Шаг 5) Запустите модель

И последнее, но не менее важное: обучите модель. Вы тренируете модель со 100 эпохами. То есть модель увидит в 100 раз больше изображений с оптимизированными весами.

Вы уже знакомы с кодами для обучения модели в Tensorflow. Небольшая разница заключается в передаче данных перед запуском обучения. Таким образом модель тренируется быстрее.

Вам нужно распечатать потери через десять эпох, чтобы увидеть, учится ли модель чему-то (т. е. уменьшается ли потеря). Обучение занимает от 2 до 5 минут, в зависимости от аппаратного обеспечения вашей машины.

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

Шаг 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”)
Построение сети для Autoencoder
Чтобы оценить модель, вы будете использовать значение пикселя этого изображения и посмотреть, сможет ли кодировщик восстановить то же изображение после сжатия на 1024 пикселя. Обратите внимание, что вы определяете функцию для оценки модели на разных изображениях. Модель должна лучше работать только на лошадях.

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

df : импорт тестовых данных
image_number : укажите, какое изображение импортировать
Функция разделена на три части:

Измените изображение на правильный размер, т.е. 1, 1024
Скармливайте модели невидимое изображение, кодируйте/декодируйте изображение
Распечатайте реальное и реконструированное изображение

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

Теперь, когда функция оценки определена, вы можете посмотреть реконструированное изображение номер тринадцать.

reconstruct_image(df =test_x, image_number = 13)
INFO:tensorflow:Restoring parameters from ./model.ckpt
Model 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)

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

Статья является переводом www.guru99.com

You may also like

Leave a Comment