Вопрос или проблема
Я пытаюсь загрузить 2 изображения в автокодировщик, но по какой-то причине он не восстанавливает входное изображение.
Автокодировщик должен сжимать и распаковывать изображение. Однако при передаче двух изображений, с которыми он обучается, он показывает только черный цвет вместо соответствующего изображения.
import keras
from keras import layers
# Это размер наших закодированных представлений
encoding_dim = 32 # 32 числа с плавающей запятой -> сжатие в 24.5 раз, предполагая, что входные данные - 784 числа с плавающей запятой
# 28*28=784 размер изображений nmist
ancho=28
alto=28
n_pixels=alto*ancho
# Это наше входное изображение
input_img = keras.Input(shape=(n_pixels,))
# "encoded" - это закодированное представление входного изображения
encoded = layers.Dense(encoding_dim, activation='relu')(input_img)
# "decoded" - это сжатая реконструкция входных данных
decoded = layers.Dense(n_pixels, activation='sigmoid')(encoded)
# Эта модель отображает входные данные в их реконструкцию
autoencoder = keras.Model(input_img, decoded)
# Эта модель отображает входные данные в их закодированное представление
encoder = keras.Model(input_img, encoded)
# Это наш закодированный (32-мерный) вход
encoded_input = keras.Input(shape=(encoding_dim,)) # выход энкодера, то есть вход декодера
# Получаем последний слой модели автокодировщика
decoder_layer = autoencoder.layers[-1]
# Создаем модель декодера
decoder = keras.Model(encoded_input, decoder_layer(encoded_input))
Этот код предназначен для загрузки двух изображений с помощью модуля pil:
## загрузка пользовательских данных
from PIL import Image
import numpy as np
# data1=np.linspace(0,0,2)
# data1_test=np.linspace(0,0,2)
data1=[0,0,0]
data1_test=[0,0,0]
data2=np.linspace(0,0,n_pixels*2).reshape(2,n_pixels)
data1[0]=Image.open("/content/zero.png")
data1[1]=Image.open("/content/eight.png")
# custom_imagen_arr=np.array(list(custom_imagen)[0]).reshape(1,784)
custom_data_arr=np.linspace(0,0,n_pixels*2).reshape(2,n_pixels)
for i2 in range(2):
imm=list(data1[i2].getdata())
for i in range(len(list(data1[i2].getdata()))):
custom_data_arr[1,i]=imm[i][0] / 255.
for i in range(len(list(data1[i2].getdata()))):
data2[i2][i]=custom_data_arr[1,i]
data2 = data2.astype('float32') / 255.
data2 = data2.reshape((len(data2), np.prod(data2.shape[1:])))
Затем я обучаю:
autoencoder.compile(optimizer="adam", loss="binary_crossentropy")
import numpy as np
autoencoder.fit(data2, data2,
epochs=152,
batch_size=1,
verbose=1,
validation_data=(data2, data2))
После завершения обучения я выбираю одно из загруженных изображений и делаю предсказание, но на выходе получается черный цвет.
# предоставить произвольное изображение автокодировщику и сгенерировать изображение
from PIL import Image
custom_imagen=Image.open("/content/eight.png")
# custom_imagen_arr=np.array(list(custom_imagen)[0]).reshape(1,784)
custom_imagen_arr=np.linspace(1,0,n_pixels*2).reshape(2,n_pixels)
imm=list(custom_imagen.getdata())
for i in range(len(list(custom_imagen.getdata()))):
custom_imagen_arr[1,i]=imm[i][0] / 255.
encoded_imgs = encoder.predict(custom_imagen_arr)
decoded_imgs = decoder.predict(encoded_imgs)
# Используем Matplotlib (не спрашивайте)
import matplotlib.pyplot as plt
n = 2 # Сколько цифр мы будем отображать
plt.figure(figsize=(20, 4))
for i in range(n):
# Отображаем оригинал
ax = plt.subplot(2, n, i + 1)
plt.imshow(custom_imagen_arr[i].reshape(alto, ancho))
plt.gray()
ax.get_xaxis().set_visible(False)
ax.get_yaxis().set_visible(False)
# Отображаем реконструкцию
ax = plt.subplot(2, n, i + 1 + n)
plt.imshow(decoded_imgs[i].reshape(alto, ancho))
plt.gray()
ax.get_xaxis().set_visible(False)
ax.get_yaxis().set_visible(False)
plt.show()
Как мне сделать так, чтобы выход автокодировщика не был черным, и чтобы совпадало с номером, на котором я обучал?
Код изменен из здесь.
На самом деле я делаю то же самое. Мне пришлось найти инструменты, потому что я тоже получал черные изображения.
Этот вариант сработал для меня:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.figure import Figure
from matplotlib.backends.backend_agg import FigureCanvas
from PIL import Image
import tensorflow as tf
keras_imager = tf.keras.preprocessing.image
# создание фигуры для отображения данных
fig = Figure(figsize=(3, 2), dpi=96) # настройте ваши параметры
canvas = FigureCanvas(fig)
ax = fig.add_subplot(111)
# отрисовка данных
ax.plot(your_data)
# отрисуем холст, кешируем рендерер
canvas.draw()
s, (width, height) = canvas.print_to_buffer()
# преобразуем в массив NumPy.
X = np.frombuffer(s, np.uint8).reshape((height, width, 4))
# преобразуем в 3D rgb массив данных
img = keras_imager.array_to_img(X)
rgb = img.convert('RGB')
arr = keras_imager.img_to_array(rgb)
# стандартизируем каждое изображение
arr = tf.image.per_image_standardization(arr)
# Если хотите изменить размер
arr = tf.image.resize(arr, (32, 32), # <- настройте ваши параметры
preserve_aspect_ratio=True)
# вы можете увидеть преобразованное изображение keras
keras_imager.array_to_img(rgb)
Честно говоря, я не совсем понимаю все параметры, но это самый простой способ, который я смог изменить, чтобы он работал для моей ситуации. Удачи.
Активирующие функции, необходимые для вашей задачи, зависят от нормализации ваших данных. Например, если вы используете MNIST (значения пикселей находятся в диапазоне от 0 до 1), тогда вам нужно использовать сигмоид для энкодера и декодера. Однако если ваше входное изображение не нормализовано как MNIST, тогда вам нужно использовать Relu активацию после энкодера и сигмоид после декодера. Это правило не является окончательным, но это общее представление.
Вы можете попробовать нормализовать данные и изменить функции активации.
Ответ или решение
Почему автокодировщик с малым количеством изображений может не работать
Ваш опыт с автокодировщиком, который не может правильно восстанавливать изображения, скорее всего, связан с несколькими ключевыми факторами. Давайте подробнее разберем возможные причины и пути их решения.
1. Ограниченное количество данных для обучения
Автокодировщики, как правило, требуют значительного объема данных для того, чтобы эффективно обучаться. В вашем случае вы используете только два изображения, что недостаточно для генерализации модели. Система может просто не иметь достаточных примеров, чтобы выучить распределение входных данных.
Рекомендации:
- Добавить больше изображений. Попробуйте предобучить автокодировщик на более крупном наборе данных. Например, MNIST содержит 60,000 изображений рукописных цифр, что позволит модели лучше обучиться.
- Использовать аугментацию данных. Увеличьте доступное количество изображений путем применения трансформаций (например, поворот, отражение, изменение яркости) к вашим исходным изображениям.
2. Нормализация данных
Вы используете сигмоидную активацию на выходе вашего автокодировщика, что предполагает, что входные данные находятся в диапазоне [0, 1]. Убедитесь, что вы правильно нормализуете данные перед обучением:
custom_data_arr = np.array(data2) / 255.0 # Нормализация изображений
Рекомендации:
- Проверьте нормализацию. Убедитесь, что все значения ваших входных изображений находятся в диапазоне [0, 1] до передачи в модель.
- Используйте другие активации. В некоторых случаях можно попробовать использовать ReLU на выходе и другие функции активации, если ваши данные не нормализованы как MNIST.
3. Артефакты при практике
Ваша реализация кода содержит несколько потенциальных ошибок, которые могли повлиять на результат. Например:
- Обратите внимание на то, как вы создаете и предсказываете изображения. Вы используете
custom_imagen_arr
для формирования входа в модель, но не инициализируете его правильно, что может привести к ошибкам.
Рекомендации:
- Исправьте процесс создания входных данных. Проверьте и перепроверьте логику использования
Image.open()
и преобразования изображений в массивы с подходящей формой. - Используйте однородные переменные. Избегайте использования произвольных чисел и переменных, которые не четко обозначают их предназначение.
# Перепроверьте создание входных массивов
custom_imagen_arr = np.array(custom_imagen) / 255.0
custom_imagen_arr = custom_imagen_arr.flatten().reshape(1, -1) # Приведите к необходимой форме
4. Оценка качества модели
После завершения обучения важно не только оценивать работоспособность автокодировщика, но и визуализировать результаты.
Рекомендации:
- Используйте визуализацию. После предсказания изображений убедитесь, что визуализация осуществляется правильно, чтобы сравнить оригинал с восстановленным изображением.
- Следите за метриками обучения. Проанализируйте графики потерь и других метрик, чтобы понять, как хорошо ваш автокодировщик обучился.
Заключение
Использование автокодировщиков для восстановления изображений может оказаться сложной задачей, особенно с малым объемом данных. Чтобы добиться успеха, вам следует увеличить количество входных изображений, использовать должную нормализацию данных и внимательно следить за реализацией кода. Ваша модель требует должной подготовки, чтобы генерировать корректные и визуально соответствующие выходные данные.
Удачи вам в дальнейшем обучении вашей модели и решении проблемы с восстановлением изображений!