使用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的時候連帶著噪點也取樣了,我們需要將噪點處理掉,再喂入神經網路。
下篇我需要把彩色驗證碼上噪點給去掉,然後再送入神經網路,請持續關注。
&n