使用tensorflow2識別4位驗證碼及思考總結

二餅二餅發表於2020-08-29

在學習了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的時候連帶著噪點也取樣了,我們需要將噪點處理掉,再喂入神經網路。

 下篇我需要把彩色驗證碼上噪點給去掉,然後再送入神經網路,請持續關注。

 

相關文章