Автор | Орхан Гази Ялчинв Компилировать|ВКонтакте Источник | К науке о данных
Возможно, вы немного знакомы с различными архитектурами нейронных сетей. Возможно, вы слышали о нейронных сетях с прямой связью, CNN, RNN, которые очень полезны для решения контролируемых задач обучения, таких как регрессия и классификация.
Однако в области неконтролируемого обучения мы сталкиваемся с большим количеством проблем, таких как уменьшение размерности, извлечение признаков, обнаружение аномалий, генерация данных, улучшение и подавление шума. Для этих задач нам нужна помощь специальных нейронных сетей, специально разработанных для задач обучения без учителя.
Поэтому они должны иметь возможность обучаться без присмотра. Одной из специальных структур нейронной сети является автоэнкодер.
автоэнкодер
Что такое автоэнкодер?
Автоэнкодер — это структура нейронной сети, состоящая из двух подсетей, сетей кодирования и декодирования, которые связаны друг с другом через скрытое пространство.
Автоэнкодеры были впервые разработаны в 1980-х Джеффри Хинтоном и группой PDP. Цель Хинтона и группы PDP - решить проблему «обратного распространения без учителя», то есть обучения без учителя, с входом в качестве учителя. Другими словами, они просто используют данные объектов как данные объектов и данные меток. Давайте подробнее рассмотрим, как работают автоэнкодеры!
Архитектура автоэнкодера
Автоэнкодер состоит из сети кодировщиков, которая получает данные объектов и кодирует их, чтобы они соответствовали скрытому пространству. Декодер использует эти закодированные данные (т. е. код) для преобразования их обратно в данные объектов. В кодировщике модель учится эффективно кодировать данные, чтобы декодер мог преобразовать их обратно в исходные данные. Поэтому ключом к обучению автоэнкодера является создание оптимизированного скрытого пространства.
Теперь знайте, что в большинстве случаев количество нейронов в скрытом пространстве намного меньше, чем во входном и выходном слоях, но это не обязательно. Существуют различные типы автокодировщиков, такие как недополные, сверхполные, разреженные, шумоподавляющие, компрессионные и вариационные автокодировщики. В этом руководстве мы сосредоточимся только на неполных автоэнкодерах для шумоподавления.
слои в автоэнкодере
Стандартной практикой при создании автоэнкодера является разработка кодировщика и создание обратной версии сети в качестве декодера для этого автоэнкодера. Следовательно, вы можете добавлять любой уровень к этим подсетям, если существует обратная связь между сетями кодера и декодера. Например, если вы имеете дело с данными изображений, вам обязательно нужны слои свертки и объединения. С другой стороны, если вы имеете дело с последовательными данными, вам могут понадобиться модули LSTM, GRU или RNN. Важным моментом здесь является то, что вы вольны строить все, что хотите.
Теперь, когда у вас есть представление об автоэнкодере, который может создавать шумоподавление изображения, мы можем перейти к учебнику и приступить к кодированию модели шумоподавления изображения. В этом руководстве мы решили использовать одно из официальных руководств TensorFlow, Introduction to Autoencoders [1], и мы будем использовать очень популярный набор данных среди членов сообщества ИИ: Fashion MNIST.
Загрузите набор данных Fashion MNIST
Fashion MNIST разработан и поддерживается Zalando, европейской компанией электронной коммерции, базирующейся в Берлине, Германия. Fashion MNIST состоит из обучающего набора из 60 000 изображений и тестового набора из 10 000 изображений. Каждый пример представляет собой изображение в градациях серого 28×28, связанное с метками из 10 классов.
Fashion MNIST содержит изображения одежды (как показано) и был разработан в качестве замены набора данных MNIST, который содержит рукописные цифры. Мы выбрали Fashion MNIST просто потому, что MNIST слишком часто используется во многих учебниках.
Следующие строки импортируют TensorFlow и загружают Fashion MNIST:
import tensorflow as tf
from tensorflow.keras.datasets import fashion_mnist
# 我们不需要y_train和y_test
(x_train, _), (x_test, _) = fashion_mnist.load_data()
print('Max value in the x_train is', x_train[0].max())
print('Min value in the x_train is', x_train[0].min())
Теперь давайте создадим сетку со следующими строками, используя примеры в наборе данных:
import matplotlib.pyplot as plt
fig, axs = plt.subplots(5, 10)
fig.tight_layout(pad=-1)
plt.gray()
a = 0
for i in range(5):
for j in range(10):
axs[i, j].imshow(tf.squeeze(x_test[a]))
axs[i, j].xaxis.set_visible(False)
axs[i, j].yaxis.set_visible(False)
a = a + 1
Наш вывод показывает первые 50 образцов тестового набора данных:
Обработка данных Fashion MNIST
Чтобы повысить эффективность вычислений и надежность модели, мы должны применить нормализацию Minmax к данным изображения, ограничивая диапазон значений от 0 до 1. Поскольку наши данные представлены в формате RGB, поэтому минимальное значение равно 0, а максимальное значение равно 255, мы можем использовать следующий код для нормализации минимума и максимума:
x_train = x_train.astype('float32') / 255.
x_test = x_test.astype('float32') / 255.
Мы также должны изменить размеры массива NumPy, потому что текущая форма набора данных (60000, 28, 28) и (10000, 28, 28). Нам просто нужно добавить четвертое измерение с одним значением (например, от (60000, 28, 28) до (60000, 28, 28, 1)).
Четвертое измерение в значительной степени доказывает, что наши данные представлены в формате оттенков серого. Если у нас есть цветное изображение, то нам нужно иметь три значения в четвертом измерении. Но нам нужно только четвертое измерение с одним значением, так как мы используем изображения в градациях серого. Следующие строки кода делают это:
x_train = x_train[…, tf.newaxis]
x_test = x_test[…, tf.newaxis]
Давайте посмотрим на форму массива NumPy со следующими строками:
print(x_train.shape)
print(x_test.shape)
вывод: (60000, 28, 1) и (10000, 28, 28, 1)
добавить шум к изображению
Помните, что наша цель — построить модель, которая избавляет изображение от шума. Для этого мы будем использовать существующие данные изображения и добавлять к ним случайный шум.
Затем мы берем исходное изображение в качестве входных данных и зашумленное изображение в качестве выходных данных. Наш автоэнкодер узнает взаимосвязь между чистыми и зашумленными изображениями, а также как очищать зашумленные изображения.
Итак, давайте создадим шумную версию.
Для этой задачи мы используем метод tf.random.normal. Затем мы умножаем случайное значение на коэффициент шума, который вы можете использовать по своему усмотрению. Следующий код добавляет шум к изображению:
noise_factor = 0.4
x_train_noisy = x_train + noise_factor * tf.random.normal(shape=x_train.shape)
x_test_noisy = x_test + noise_factor * tf.random.normal(shape=x_test.shape)
Также нам нужно убедиться, что значения элементов массива находятся в диапазоне от 0 до 1. Для этого мы можем использоватьtf.clip_by_valueметод. clip_by_value — это метод TensorFlow, который обрезает и заменяет значения за пределами диапазона «минимум-максимум» указанным «минимум» или «максимум». Следующий код отсекает значения вне допустимого диапазона:
x_train_noisy = tf.clip_by_value(x_train_noisy, clip_value_min=0., clip_value_max=1.)
x_test_noisy = tf.clip_by_value(x_test_noisy, clip_value_min=0., clip_value_max=1.)
Теперь, когда мы создали регуляризованную и зашумленную версию нашего набора данных, мы можем увидеть, как она выглядит:
n = 5
plt.figure(figsize=(20, 8))
plt.gray()
for i in range(n):
ax = plt.subplot(2, n, i + 1)
plt.title("original", size=20)
plt.imshow(tf.squeeze(x_test[i]))
plt.gray()
bx = plt.subplot(2, n, n+ i + 1)
plt.title("original + noise", size=20)
plt.imshow(tf.squeeze(x_test_noisy[i]))
plt.show()
Как видите, почти невозможно понять, что мы видим на зашумленном изображении. Однако наш автоэнкодер волшебным образом научится его очищать.
Построить нашу модель
В TensorFlow, помимо последовательного и функционального API, есть третий способ построения моделей: подклассы моделей. В подклассах моделей мы можем реализовать все с нуля.
Подклассы моделей полностью настраиваются, что позволяет нам реализовывать собственные модели. Это очень мощный метод, потому что мы можем построить любой тип модели. Однако для этого требуются базовые знания объектно-ориентированного программирования. Наш пользовательский класс — это объект tf.keras.Model. Также необходимо объявить несколько переменных и функций.
Также обратите внимание, что, поскольку мы имеем дело с данными изображения, более эффективно построить сверточный автоэнкодер следующим образом:
Чтобы построить модель, мы просто выполняем следующие задачи:
-
Создайте объект, расширяющий keras.Model.
-
Создайте функцию для объявления двух независимых моделей, созданных с помощью последовательного API. В них нам нужно объявить слои, обращенные друг к другу. Один слой Conv2D используется для модели кодировщика, а один слой Conv2DTranspose используется для модели декодера.
-
Используйте метод **__init__** для создания функции вызова, которая сообщает модели, как использовать инициализированные переменные для обработки ввода.
-
Нам нужно вызвать исходную модель кодировщика, которая принимает изображение в качестве входных данных.
-
Нам также нужно вызвать инициализированную модель декодера, которая принимает выходные данные модели кодировщика (закодированные) в качестве входных данных.
-
Возвращает вывод декодера
Мы можем достичь всех этих целей с помощью следующего кода:
from tensorflow.keras.layers import Conv2DTranspose, Conv2D, Input
class NoiseReducer(tf.keras.Model):
def __init__(self):
super(NoiseReducer, self).__init__()
self.encoder = tf.keras.Sequential([
Input(shape=(28, 28, 1)),
Conv2D(16, (3,3), activation='relu', padding='same', strides=2),
Conv2D(8, (3,3), activation='relu', padding='same', strides=2)])
self.decoder = tf.keras.Sequential([
Conv2DTranspose(8, kernel_size=3, strides=2, activation='relu', padding='same'),
Conv2DTranspose(16, kernel_size=3, strides=2, activation='relu', padding='same'),
Conv2D(1, kernel_size=(3,3), activation='sigmoid', padding='same')])
def call(self, x):
encoded = self.encoder(x)
decoded = self.decoder(encoded)
return decoded
Давайте создадим модель с вызовом объекта:
autoencoder = NoiseReducer()
Настройте нашу модель
Для этой задачи мы будем использовать оптимизатор Адама и среднеквадратичную ошибку модели. Мы можем легко настроить наш автоэнкодер с помощью функции компиляции следующим образом:
autoencoder.compile(optimizer='adam', loss='mse')
Наконец, мы можем запустить нашу модель с входным шумом и чистыми изображениями в 10 эпох, что займет около 1 минуты для обучения. Мы также используем тестовый набор данных для проверки. Для обучения модели используется следующий код:
autoencoder.fit(x_train_noisy,
x_train,
epochs=10,
shuffle=True,
validation_data=(x_test_noisy, x_test))
Подавление шума изображения с помощью нашего обученного автоэнкодера
Теперь мы можем приступить к очистке зашумленного изображения. Обратите внимание, что у нас есть доступ к сетям кодировщика и декодера, поскольку мы определили их в объекте NoiseReducer.
Итак, во-первых, мы будем использовать кодировщик для кодирования нашего тестового набора данных с шумом (x_test_noise). Затем мы передаем закодированный вывод в декодер, чтобы получить чистое изображение. Следующий код выполняет эти задачи:
encoded_imgs=autoencoder.encoder(x_test_noisy).numpy()
decoded_imgs=autoencoder.decoder(encoded_imgs)
Давайте построим 10 лучших образцов для параллельного сравнения:
n = 10
plt.figure(figsize=(20, 7))
plt.gray()
for i in range(n):
# 显示原始+噪声
bx = plt.subplot(3, n, i + 1)
plt.title("original + noise")
plt.imshow(tf.squeeze(x_test_noisy[i]))
ax.get_xaxis().set_visible(False)
ax.get_yaxis().set_visible(False)
# 显示重建
cx = plt.subplot(3, n, i + n + 1)
plt.title("reconstructed")
plt.imshow(tf.squeeze(decoded_imgs[i]))
bx.get_xaxis().set_visible(False)
bx.get_yaxis().set_visible(False)
# 显示原始
ax = plt.subplot(3, n, i + 2*n + 1)
plt.title("original")
plt.imshow(tf.squeeze(x_test[i]))
ax.get_xaxis().set_visible(False)
ax.get_yaxis().set_visible(False)
plt.show()
Первая строка предназначена для зашумленного изображения, вторая строка — очищенного (реконструированного) изображения и, наконец, третья строка — исходного изображения. Посмотрите, насколько очищенное изображение похоже на оригинал:
конец
Вы построили модель автоэнкодера, которая успешно очищает очень зашумленные изображения, чего она никогда раньше не видела (мы используем тестовый набор данных).
Очевидно, есть какие-то неустраненные деформации, такие как отсутствие подошвы тапочек на втором фото справа. Однако, если учитывать степень искажения зашумленного изображения, можно сказать, что наша модель достаточно успешно восстанавливает искаженное изображение.
В глубине души можно было бы сказать — подумайте о том, чтобы расширить этот автоэнкодер и встроить его в приложение для улучшения фотографий, что улучшило бы резкость и четкость фотографии.
Ссылаться на
[1] Intro to Autoencoders, TensorFlow, available on woohoo.tensorflow.org/tutorials/…
Оригинальная ссылка:к data science.com/image-noise…
Добро пожаловать на сайт блога Panchuang AI:panchuang.net/
sklearn машинное обучение китайские официальные документы:sklearn123.com/
Добро пожаловать на станцию сводки ресурсов блога Panchuang:docs.panchuang.net/