使用tensorflow2识别4位验证码及思考总结

在学习了CNN之后,自己想去做一个验证码识别,网上找了很多资料,杂七杂八的一大堆,但是好多是tf1写的,对tf1不太熟悉,有点看不懂,于是自己去摸索吧。

摸索的过程是异常艰难呀,一开始我直接用captcha 生成了10080张验证码去识别,发现loss一直停留在2.3左右,accuracy一直是0.1左右,训练了100回合,也没啥变化,电脑都快要跑废了,咋办呀,于是网上各种问大佬,找到机会就发问,说我识别验证码出现的问题,其中一位大佬对我的问题很有帮助,感谢魏巍老师。

下面就是我寻找问题答案的每一步:

第一回

网络结构的搭建:

 1 model=tf.keras.models.Sequential([
 2 
 3     tf.keras.Input(shape=(H, W, C)),
 4     layers.Conv2D(32, 3, activation='relu'),
 5     layers.MaxPooling2D((2, 2)),
 6 
 7     layers.Conv2D(64, 3, activation='relu'),
 8     layers.MaxPooling2D((2, 2)),
 9 
10     layers.Conv2D(64, 3, activation='relu'),
11     layers.MaxPooling2D((2, 2)),
12 
13     layers.Conv2D(64, 3, activation='relu'),
14     layers.MaxPooling2D((2, 2)),
15 
16     layers.Conv2D(64, 3, activation='relu'),
17     layers.MaxPooling2D((2, 2)),
18 
19     layers.Flatten(),
20     layers.Dense(1024, activation='relu'),
21 
22     layers.Dense(D * N_LABELS, activation='softmax'),
23     layers.Reshape((D, N_LABELS)),
24 ])


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)

summary:

我的训练数据量: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 也很低,不知道出现了什么原因,困扰一两个星期呀,都想要放弃了,太难了。。。。

但是我不死心呀,非要把它搞出来,咋搞呢,4位识别不出来,能不能先识别一位呢?好,那就开始搞,一位比较简单,跟Mnist 数据集很相似,在这我就不详细了。

第二回

接着来识别2位的验证码,

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

样本图:

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

 

 

 

30张图片进行测试,结果:

 

 

 

哎呦,有感觉了,有了起色了,出现了过拟合的现象,解决过拟合的方法主要有:

1、get more trainning data
2、reduce the capacity of the network
3、 add weight regularization
4、add dropout
5、data-augmentation
6、batch normalization

第三回

于是我就增加了数据集,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位验证码。

第五回

依然采用上面的网络结构,
这次使用的是 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 张错误:

 

 4位验证码的样本图:

 

 从结果来看,,有点过拟合,没关系,继续加大数据集,

第六回

依旧采用上面的网络结构:
这次我增加了数据集 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 张错误:

 

 

好了,搞了这么多,由此我觉得是噪点影响了深度学习的识别,maxpool的时候连带着噪点也采样了,我们需要将噪点处理掉,再喂入神经网络。

 下篇我需要把彩色验证码上噪点给去掉,然后再送入神经网络,请持续关注。