用 tf2 识别 4 位纯数字验证码,loss 一直不变,accuracy 也不变,是什么原因呢?

下面是我的网络模型:
model=tf.keras.models.Sequential([

    tf.keras.Input(shape=(H, W, C)),
    layers.Conv2D(32, 3, activation='relu'),
    layers.MaxPooling2D((2, 2)),

    layers.Conv2D(64, 3, activation='relu'),
    layers.MaxPooling2D((2, 2)),

    layers.Conv2D(64, 3, activation='relu'),
    layers.MaxPooling2D((2, 2)),

    layers.Conv2D(64, 3, activation='relu'),
    layers.MaxPooling2D((2, 2)),

    layers.Conv2D(64, 3, activation='relu'),
    layers.MaxPooling2D((2, 2)),

    layers.Flatten(),
    layers.Dense(1024, activation='relu'),

    layers.Dense(D * N_LABELS, activation='softmax'),
    layers.Reshape((D, N_LABELS)),
])

summary:

配置

    model.compile(optimizer='adam',
                  loss='categorical_crossentropy',
                  metrics= ['accuracy'])


callbacks=[
    tf.keras.callbacks.TensorBoard(log_dir='logs'),
    tf.keras.callbacks.ModelCheckpoint(filepath=check_point_path,
                                       save_weights_only=True,
                                       save_best_only=True)
]
history = model.fit(train_gen,
                    steps_per_epoch=len(train_idx)//batch_size,
                    epochs=100,
                    callbacks=callbacks,
                    validation_data=valid_gen,
                    validation_steps=len(valid_idx)//valid_batch_size)

train count: 7408, valid count: 3176, test count: 4536

训练结果:
Train for 231 steps, validate for 99 steps
Epoch 1/100
1/231 […] - ETA: 4:18 - loss: 2.2984 - accuracy: 0.1328
231/231 [==============================] - 143s 618ms/step - loss: 2.3032 - accuracy: 0.0971 - val_loss: 2.3029 - val_accuracy: 0.0987
Epoch 2/100
230/231 [============================>.] - ETA: 0s - loss: 2.3026 - accuracy: 0.1014
231/231 [==============================] - 121s 525ms/step - loss: 2.3026 - accuracy: 0.1013 - val_loss: 2.3031 - val_accuracy: 0.0986
Epoch 3/100
230/231 [============================>.] - ETA: 0s - loss: 2.3026 - accuracy: 0.1029
231/231 [==============================] - 138s 597ms/step - loss: 2.3026 - accuracy: 0.1026 - val_loss: 2.3032 - val_accuracy: 0.0986
Epoch 4/100
230/231 [============================>.] - ETA: 0s - loss: 2.3025 - accuracy: 0.1031
231/231 [==============================] - 124s 537ms/step - loss: 2.3025 - accuracy: 0.1031 - val_loss: 2.3032 - val_accuracy: 0.0987
Epoch 5/100
230/231 [============================>.] - ETA: 0s - loss: 2.3025 - accuracy: 0.1040
231/231 [==============================] - 123s 532ms/step - loss: 2.3025 - accuracy: 0.1039 - val_loss: 2.3032 - val_accuracy: 0.0989

Epoch 6/100
230/231 [============================>.] - ETA: 0s - loss: 2.3025 - accuracy: 0.1039
231/231 [==============================] - 118s 509ms/step - loss: 2.3025 - accuracy: 0.1038 - val_loss: 2.3033 - val_accuracy: 0.0988


Epoch 20/100
230/231 [============================>.] - ETA: 0s - loss: 2.3025 - accuracy: 0.1038
231/231 [==============================] - 120s 521ms/step - loss: 2.3025 - accuracy: 0.1038 - val_loss: 2.3034 - val_accuracy: 0.0988
Epoch 21/100
190/231 [=======================>…] - ETA: 20s - loss: 2.3025 - accuracy: 0.1032

loss 一直没有变化,accuracy 也很低,请问是什么原因呢?
验证码图片是(100,120,3),是用 captcha 生成的,如图:

0124_29d6909a-6105-46ee-a47f-0ade136f766d 0123_c2d487ee-26b7-44cd-a940-c34a8530a4f6

1 Like

@snowkylin

多位验证码识别不是简单地把单位验证码的模型的输出乘个 4 就可以的。建议想办法先对图像做分割预处理,把多个数字拆成单个分别识别,或者参考一下网上的多位验证码的解决方案。

1 Like

我看了网上是直接进行识别,不需要进行分隔。

我是参考的这个代码。

1 Like

好像之前发的那个链接无法访问到,我用我的 “版主权限” 稍微修改了一下链接地址。

train count: 441, valid count: 189, test count: 270

** 下面是我用 2 位验证码进行训练的结果:**

** 预测的结果 **

出现了过拟合现象,于是我就加大了数据集

train count: 4410, valid count: 1890, test count: 2700
然后出现了 loss 一直在 2.3,accuracy 在 0.09 左右。

网络结构依然采用上面的,input_shape(100,80,3)
这是我用 2 位的黑白图片的验证码进行了训练,效果很好,收敛也很快。

训练第 50 回合时:
Epoch 50/50
26/27 [============>…] - ETA: 0s - loss: 0.0150 - accuracy: 0.9940
27/27 [==============] - 8s 289ms/step - loss: 0.0212 - accuracy: 0.9936 - val_loss: 0.2348 - val_accuracy: 0.9446

随机选取了 30 张图片进行了测试,2 张识别错了:

** 样本:**

依然采用上面的网络结构,
这次使用的是 4 位黑白图片的验证码,有点过拟合,

train count: 2469, valid count: 1059, test count: 1512

训练第 20 回合:
Epoch 20/20
76/77 [====>.] - ETA: 0s - loss: 0.0409 - accuracy: 0.9860
77/77 [======] - 33s 429ms/step - loss: 0.0408 - accuracy: 0.9861 - val_loss: 0.3283 - val_accuracy: 0.9221

随机选取 30 张图片进行测试,8 张错误:

** 样本:**

依旧采用上面的网络结构:
这次我增加了数据集 4939 张,依旧使用的是 4 位黑白的验证码,训练结果还是挺好的:

train count: 4939, valid count: 2117, test count: 3024

第 20 回合:
Epoch 20/20
153/154 [==>.] - ETA: 0s - loss: 0.0327 - accuracy: 0.9898
154/154 [====] - 75s 488ms/step - loss: 0.0329 - accuracy: 0.9898 - val_loss: 0.1057 - val_accuracy: 0.9740

随机选取 30 张图片进行测试,6 张错误:

由此我觉得是噪点影响了深度学习的识别,我们需要将噪点处理掉,再喂入神经网络。

在上面的推理中,我感觉是噪点影响了神经网络的识别,于是乎我在送入网络之前进行了去噪,二值化操作,训练如下:
train count: 4939, valid count: 2117, test count: 3024,

从图中可以看出,模型收敛了,但有点过拟合。
第 20 回合训练结果:
Epoch 20/20
153/154 [==>.] - ETA: 0s - loss: 0.0407 - accuracy: 0.9861
154/154 [===] - 69s 450ms/step - loss: 0.0408 - accuracy: 0.9860 - val_loss: 0.3227 - val_accuracy: 0.9244

随机选取了 30 张图片进行了测试,8 张错误:

做到这里, 我对之前的推测有了猜疑,是噪点影响的吗?我觉得不是,我做了去燥(有的噪点还在),二值化,使得图片的信息量减少了,神经网络的计算量也大大减少了很多,我能很快看到训练过程中 loss 显著减少,accuracy 也在不断的提高。
整个过程,我用 CPU 进行训练的,电脑配置是 Intel(R)_Core™i7-6700HQ_CPU@_2.60GHz,8G 内存。如果大家的电脑配置高,用 GPU 进行训练,我觉得即使不做预处理,效果肯定也能出来。

1 Like

因为你全都用的最大池。最大池可以增大感受野,也会放大椒盐噪声。加点平均池或者就不要池化。如果是为了平移不变性大可不用加一堆最大池。

1 Like