Keras 为什么我的自动编码器模型没有学习?

Keras 为什么我的自动编码器模型没有学习?,keras,conv-neural-network,tensorflow2.0,autoencoder,Keras,Conv Neural Network,Tensorflow2.0,Autoencoder,我正在尝试使用自动编码器解决验证码数据集。最重要的是RGB图像 我将RGB图像转换为一个通道,即: 图像的形状是48200 所以我接下来要做的是,在我们的例子emwpn中使用captcha的文本,并创建另一个图像,与此文本具有相同的形状48200,即: 我试着给自动编码器的编码器输入CAPTCHA,给解码器输入我创建的图像 我不知道这个方法是否好,但我没想到它什么也学不到。当我试图预测测试数据集时,我得到的只是紫色图像,即: capchas_array_test_pred = conv_ae.p

我正在尝试使用自动编码器解决验证码数据集。最重要的是RGB图像

我将RGB图像转换为一个通道,即:

图像的形状是48200

所以我接下来要做的是,在我们的例子emwpn中使用captcha的文本,并创建另一个图像,与此文本具有相同的形状48200,即:

我试着给自动编码器的编码器输入CAPTCHA,给解码器输入我创建的图像

我不知道这个方法是否好,但我没想到它什么也学不到。当我试图预测测试数据集时,我得到的只是紫色图像,即:

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
我试图检查,如果我给编码器和解码器提供相同的图像,会发生什么情况:

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))
我又一次看到了紫色的图像:

注:如果您感兴趣,这是笔记本:

编辑-

这是我对图像所做的预处理:

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 
你的架构没有任何意义。若你们想创建一个自动编码器,你们需要知道你们将在编码后反向处理。这意味着如果你有三个卷积层,滤波器的顺序是:64,32,16;你应该做下一组卷积层来做相反的事情:16,32,64。这就是为什么你的算法没有学习的原因。 你不会得到你期望的结果。你会得到类似的验证码结构,但你不会得到清晰的文本输出。如果你想这样做,你需要另一种算法——一种允许你进行字符分割的算法。
文本不在同一位置,您可能应该将其标准化。您的解码器在Conv2d层之间缺少下采样,这是故意的吗?我将首先尝试使用仅具有重塑的模型,以检查学习是否正确设置。然后添加一个Conv2dlayer@jonnor是的,这就是为什么我不希望它工作得很好,但至少做点什么。编码器也对过滤器进行了上采样。@jonnor只是尝试了重塑,这会给出与输入相同的图像。据我所知,解码器是我代码中编码器的反向过程。解码器获取形状[6,25,64]的图像,图像大小为6,25,带有64个过滤器,然后过滤器的数量变为32,16,然后变为1。如果您有解决方案,请告诉我在代码中修复什么。