Я пытаюсь решить набор данных с помощью автоэнкодера. набор данных - это изображения RGB.
Я преобразовал изображения RGB в один канал, то есть:
(Форма изображения (48, 200)).
Итак, что я сделал дальше, это использовал взять текст капчи (в нашем случае «emwpn») и создать другое изображение, с такой же формы (48, 200) с этим текстом, то есть:
И то, что я пытался, это снабдить кодировщик автоэнкодера капчами, и накормить декодер изображениями, которые я создал.
Я не знал, будет ли этот метод хорошим, но я не ожидал, что он ничему не научится. Когда я пытался предсказать набор тестовых данных, все, что я получил, было фиолетовыми изображениями, а именно:
capchas_array_test_pred = conv_ae.predict(capchas_array_test)
plt.imshow(capchas_array_test_pred[1])
Это означает, что автоэнкодер прогнозирует 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))
И снова я получил фиолетовые изображения:
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