Автокодировщик с небольшим количеством изображений не работает?

Вопрос или проблема

Я пытаюсь загрузить 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. Оценка качества модели

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

Рекомендации:

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

Заключение

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

Удачи вам в дальнейшем обучении вашей модели и решении проблемы с восстановлением изображений!

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

Капча загружается...