Почему моя модель автоэнкодера не учится? - PullRequest
0 голосов
/ 14 апреля 2020

Я пытаюсь решить набор данных с помощью автоэнкодера. набор данных - это изображения RGB.

Я преобразовал изображения RGB в один канал, то есть:

enter image description here

(Форма изображения (48, 200)).

Итак, что я сделал дальше, это использовал взять текст капчи (в нашем случае «emwpn») и создать другое изображение, с такой же формы (48, 200) с этим текстом, то есть:

enter image description here

И то, что я пытался, это снабдить кодировщик автоэнкодера капчами, и накормить декодер изображениями, которые я создал.

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

capchas_array_test_pred = conv_ae.predict(capchas_array_test)
plt.imshow(capchas_array_test_pred[1])

enter image description here

Это означает, что автоэнкодер прогнозирует 0 для все пиксели всех изображений.

Вот код для автоматического кодера conv:

def rounded_accuracy(y_true, y_pred):
    return keras.metrics.binary_accuracy(tf.round(y_true), tf.round(y_pred))

conv_encoder = keras.models.Sequential([
    keras.layers.Reshape([48, 200, 1], input_shape=[48, 200]),
    keras.layers.Conv2D(16, kernel_size=5, padding="SAME"),
    keras.layers.BatchNormalization(),
    keras.layers.Activation("relu"),
    keras.layers.Conv2D(32, kernel_size=5, padding="SAME", activation="selu"),
    keras.layers.Conv2D(64, kernel_size=5, padding="SAME", activation="selu"),
    keras.layers.AvgPool2D(pool_size=2),
])
conv_decoder = keras.models.Sequential([
    keras.layers.Conv2DTranspose(32, kernel_size=5, strides=2, padding="SAME", activation="selu",
                                input_shape=[6, 25, 64]),
    keras.layers.Conv2DTranspose(16, kernel_size=5, strides=1, padding="SAME", activation="selu"),
    keras.layers.Conv2DTranspose(1, kernel_size=5, strides=1, padding="SAME", activation="sigmoid"),
    keras.layers.Reshape([48, 200])
])

conv_ae = keras.models.Sequential([conv_encoder, conv_decoder])
conv_ae.compile(loss="mse", optimizer=keras.optimizers.Adam(lr=1e-1), metrics=[rounded_accuracy])
history = conv_ae.fit(capchas_array_train, capchas_array_rewritten_train, epochs=20,
                      validation_data=(capchas_array_valid, capchas_array_rewritten_valid))

Модель ничего не выучила:

Epoch 2/20
24/24 [==============================] - 1s 53ms/step - loss: 60879.9883 - rounded_accuracy: 0.0637 - val_loss: 60930.7344 - val_rounded_accuracy: 0.0635
Epoch 3/20
24/24 [==============================] - 1s 53ms/step - loss: 60878.5781 - rounded_accuracy: 0.0637 - val_loss: 60930.7344 - val_rounded_accuracy: 0.0635
Epoch 4/20
24/24 [==============================] - 1s 53ms/step - loss: 60879.2656 - rounded_accuracy: 0.0637 - val_loss: 60930.7344 - val_rounded_accuracy: 0.0635
Epoch 5/20
24/24 [==============================] - 1s 53ms/step - loss: 60876.4648 - rounded_accuracy: 0.0637 - val_loss: 60930.7344 - val_rounded_accuracy: 0.0635
Epoch 6/20
24/24 [==============================] - 1s 53ms/step - loss: 60878.4883 - rounded_accuracy: 0.0637 - val_loss: 60930.7344 - val_rounded_accuracy: 0.0635
Epoch 7/20
24/24 [==============================] - 1s 53ms/step - loss: 60880.8242 - rounded_accuracy: 0.0637 - val_loss: 60930.7344 - val_rounded_accuracy: 0.0635

I попытался проверить, что проверить, что произойдет, если я подаю кодировщик и декодер с одинаковыми изображениями:

conv_ae.compile(loss="mse", optimizer=keras.optimizers.Adam(lr=1e-1), metrics=[rounded_accuracy])
history = conv_ae.fit(capchas_array_train, capchas_array_train, epochs=20,
                      validation_data=(capchas_array_valid, capchas_array_valid))

И снова я получил фиолетовые изображения:

enter image description here

Ps Если вам интересно, это записная книжка: https://colab.research.google.com/drive/1gA1XN1NOZKylGDhVu4PKXWhrPU4q9Ady


EDIT-

Это предварительная обработка, которую я сделал к изображениям:

1. Convert RGB image to one channel.
2. Normalize the image from value from 0 to 255 for each pixel, to 0 to 1.
3. Resize the (50, 200) image to (48, 200) - for simpler pooling in the autoencoder (48 can be divided by 2 more times, and stay integer, than 50)

Это функция для предварительной обработки 1,2 шага:

def rgb2gray(rgb):
    r, g, b = rgb[:,:,0], rgb[:,:,1], rgb[:,:,2]
    gray = (0.2989 * r + 0.5870 * g + 0.1140 * b)

    for x in range(rgb.shape[1]):
      for y in range(rgb.shape[0]):
        if gray[y][x]>128:
          gray[y][x] = 1.0
        else:
          gray[y][x] = 0.0
    return gray 

1 Ответ

0 голосов
/ 15 апреля 2020
  1. Ваша архитектура не имеет никакого смысла. Если вы хотите создать автоэнкодер, вы должны понимать, что после кодирования вы собираетесь изменить процесс. Это означает, что если у вас есть три сверточных слоя с фильтрами в следующем порядке: 64, 32, 16; Вы должны создать следующую группу сверточных слоев, чтобы сделать обратное: 16, 32, 64. Вот почему ваш алгоритм не обучается.
  2. Вы не получите ожидаемого результата. Вы получите похожую структуру такого рода капчи, но вы не будете так четко выводить текст. Если вы хотите этого, вам нужен другой тип алгоритма (тот, который позволяет вам выполнять сегментацию символов).
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...