Статьи про Нейросети

Уменьшение шума изображений с помощью автокодировщика на Python

Задачи:

  • Понять основной принцип работы искусственной нейронной сети.
  • Понять тип искусственных нейронных сетей, называемых Autoencoders
  • Использование автоэнкодеров для уменьшения шума в изображениях

Автоэнкодеры – это особый тип искусственных нейронных сетей (ИНС). Поэтому для понимания автоэнкодеров лучше всего сначала получить представление о том, как работает ANN.

Основы ANN

ИНС – это вычислительные модели, созданные на основе естественных нейронных сетей.

В упрощенном виде ИНС можно разделить на три основных компонента: входной слой, несколько скрытых слоев и выходной слой (см. рисунок 1).

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

Предположим, например, что вы хотите обучить сеть распознавать изображения цифр от 0 до 9, написанных от руки – Такой тип ANN, то есть принимающий изображения на вход, называется CNN (Convolutional Neural Network) – Тогда во время обучения вы должны предоставить в качестве входа несколько изображений цифр от 0 до 9, а также выходную переменную.

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

Первоначально весовым коэффициентам присваиваются случайные значения.

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

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

Таким образом, на каждой итерации ИНС “учится” правильно идентифицировать изображения рукописных цифр.

После обучения мы можем передать ей новое изображение (то есть то, которое не использовалось во время обучения), и сеть вернет на выходе, какая это цифра.

То есть, после обучения ANN сможет с высокой вероятностью успеха распознавать, какая цифра является цифрой, даже если он никогда ее не “видел”.

Рисунок 1

Рисунок 1: Входной слой может состоять, например, из значений пикселей изображения.

Под скрытыми слоями можно понимать некоторую функцию G, которая зависит от весов wi, входных значений Xi.

Функция G преобразует значения на входе и в зависимости от типа ANN может вернуть на выход другое изображение или вероятность того, что изображение на входе принадлежит к определенному ранее заданному типу.

Автокодировщики

Как упоминалось выше, автоэнкодеры являются частным случаем ANN.

Их особенность в том, что вход обычно точно такой же, как и выход.

Используя приведенный выше пример, если на вход передается изображение 0, автокодировщик вернет на выход изображение нуля, максимально приближенное к изображению на входе (рис. 2).

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

Основное отличие от обычных сетей заключается в том, что промежуточные слои (скрытые слои) сначала уменьшают свой размер (Encoder), а затем снова увеличивают его (Decoder) симметричным образом (рис. 2).

Рисунок 2: Общая архитектура автокодировщика.

Благодаря архитектуре этой ИНС основной слой представляет собой компактное представление входных переменных.

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

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

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

В этом смысле автокодировщики оказались альтернативным и более надежным методом, чем PCA (анализ главных компонент).

Автокодировщики как фильтры изображений

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

Для этого на этапе обучения необходимо передать на вход набор изображений с шумом, а на выход – соответствующие изображения без шума (рис. 3).

Рисунок 3: Общая архитектура автокодировщика для уменьшения шума изображения

Таким образом, автокодер “научится” удалять шум из изображений. После обучения он сможет удалять шум из любого изображения цифр от 0 до 9, даже если сеть никогда их не “видела”. Обратите внимание, что нет необходимости сообщать сети какое-либо конкретное правило или фильтр, она “учится” сама во время фазы обучения.

Код для создания автокодировщика для удаления шума изображения.

Ниже приведен код для создания автокодировщика для удаления шума изображения. В этом примере мы будем использовать изображения рукописных цифр, извлеченные из данных MNIST с помощью библиотеки Python sklearn. В библиотеке имеется 70 000 цифровых изображений.

Сначала мы разделяем набор изображений на две группы; первую группу составят данные, используемые для обучения сети (85%), а остальные (15%) – для оценки качества работы сети.

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

Эти изображения передаются на вход автокодировщика на этапе обучения, а оригинальные изображения, извлеченные из MNIST, передаются на выход.

Для определения архитектуры сети мы используем библиотеку Python keras, которая представляет собой очень простой интерфейс с TensorFlow.

# Импорт библиотек from sklearn.datasets import fetch_openml from sklearn.model_selection import train_test_split import numpy as np import matplotlib.pyplot as plt from keras.layers import Input, Dense, Conv2D, MaxPooling2D, UpSampling2D from keras.models import Model from keras import backend as K #Импорт изображений цифр из библиотеки MNIST X, y = fetch_openml('mnist_784', version=1, return_X_y=True) #Разделение на группы для обучения и для проверки train_img, test_img, train_lbl, test_lbl = train_test_split( X, y, test_size=1/7.0, random_state=100) #Просмотр некоторых изображений #Эту часть кода вы должны выполнить сами, чтобы #Проверить, как выглядят изображения из библиотеки MNIST plt.figure(figsize=(10,10)) for index, (image, label) in enumerate(zip(train_img[0:15], train_lbl[0:15])): plt.subplot(3, 5, index + 1) plt.imshow(np.reshape(image, (28,28)), cmap=plt.cm.gray) plt.title('Training: %s' % label, fontsize = 20) #Нормализация изображений от 0 до 1 train_img = train_img.astype('float32') / 255 test_img = test_img.astype('float32') / 255 # Добавляем к исходным изображениям гауссовский шум с центром 0,5 и std=0,5. noise = np.random.normal(loc=0.5, scale=0.5, size=train_img.shape) x_img_train_noisy = train_img + noise noise = np.random.normal(loc=0.5, scale=0.5, size=test_img.shape) x_img_test_nosisy = test_img + noise # Настройка размера изображения x_train_noisy = np.reshape(x_img_train_noisy, [-1, 28, 28, 1]) x_test_nosisy = np.reshape(x_img_test_nosisy, [-1, 28, 28, 1]) #Определение архитектуры автокодировщика input_img = Input(shape=(28, 28, 1)) x = Conv2D(16, (3, 3), activation='relu', padding='same')(input_img) x = MaxPooling2D((2, 2), padding='same')(x) x = Conv2D(8, (3, 3), activation='relu', padding='same')(x) x = MaxPooling2D((2, 2), padding='same')(x) x = Conv2D(8, (3, 3), activation='relu', padding='same')(x) encoded = MaxPooling2D((2, 2), padding='same')(x) x = Conv2D(8, (3, 3), activation='relu', padding='same')(encoded) x = UpSampling2D((2, 2))(x) x = Conv2D(8, (3, 3), activation='relu', padding='same')(x) x = UpSampling2D((2, 2))(x) x = Conv2D(16, (3, 3), activation='relu')(x) x = UpSampling2D((2, 2))(x) decoded = Conv2D(1, (3, 3), activation='sigmoid', padding='same')(x) autoencoder = Model(input_img, decoded) autoencoder.compile(optimizer='adadelta', loss='binary_crossentropy') # Обучение автокодировщика. Обратите внимание, что первые два аргумента # функции соответствуют входным и выходным данным соответственно. H1 = autoencoder.fit(x_train_noisy, x_train, epochs=30, batch_size=128, shuffle=True, validation_data=(x_test_nosisy, x_test) ) # Применение обученного автокодировщика к набору изображений в группе проверки. denoised_img = autoencoder.predict(x_test_nosisy) # Отображение входных изображений и результата после применения автокодирования (Рисунок 4) n = 9 plt.figure(figsize=(20, 4)) for i in range(n): # Отображение оригиналов ax = plt.subplot(2, n, i+1) plt.imshow(x_test_nosisy[i].reshape(28, 28)) plt.gray() ax.get_xaxis().set_visible(False) ax.get_yaxis().set_visible(False) # отображение изображений после удаления шума ax = plt.subplot(2, n, i + n+1) plt.imshow(denoised_img[i].reshape(28, 28)) plt.gray() ax.get_xaxis().set_visible(False) ax.get_yaxis().set_visible(False) plt.show()
Code language: PHP (php)

В заключение приведем результаты, полученные при применении автокодировщика к некоторым изображениям из проверочного набора (рис. 4).

Рисунок 4: Изображения с гауссовским шумом (верхняя строка) и соответствующие изображения, полученные фильтрующим автокодировщиком (нижняя строка).

Как видно на рисунке 4, результат весьма впечатляющий.

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

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

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

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

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *