在學習了 CNN 之后,我一直想去做一個驗證碼識別。網上找了很多資料,雜七雜八的一大堆,但是好多是 tf1 寫的。我對 tf1 不太熟悉,于是自己開始了基于 TensorFlow 2 的摸索實踐。
摸索的過程異常艱難,一開始我直接用 captcha 生成了 10080 張驗證碼去識別,發現 loss 一直停留在 2.3 左右,accuracy 一直是 0.1 左右,訓練了 100 回合,也沒什么提升,電腦都快要跑廢了,咋辦呀?于是網上各種問大佬,找到機會就提問,其中一位大佬的回答讓我受到了啟發,他說:你可以先識別 1 位,然后 2 位,3 位,最后 4 位,一步一步來……。
本文主要描述我在驗證碼識別過程中的一些摸索,整理出來以供大家參考:
第一回:搭建網絡結構
首先我們需要搭建網絡結構,如下:
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)), ]) 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 位彩色驗證碼訓練
接著來識別 2 位的驗證碼。train count: 441, valid count: 189, test count: 270
樣本圖:
下面是我用 2 位驗證碼進行訓練的結果:
30 張圖片進行測試,結果:
哎呦,有感覺了,有了起色了,但是出現了過擬合的現象,解決過擬合的方法主要有:
Get more training data
Reduce the capacity of the network
Add weight regularization
Add dropout
Data-augmentation
Batch normalization
第三回:增加彩色驗證碼數據集
于是我就增加了數據集。train count: 4410, valid count: 1890, test count: 2700
然后又出現了 loss 一直在 2.3,accuracy 在 0.09 左右,這是什么鬼呢?但是我還是不死心呀,繼續想辦法呀,既然彩色的有難度,我先識別黑白的樣本行不行呢,先試試吧。
第四回:2 位黑白驗證碼訓練
網絡結構依然采用上面的,input_shape(100,120,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 位黑白驗證碼訓練
依然采用上面的網絡結構,這次使用的是 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 的時候連帶著噪點也采樣了,我們需要將噪點處理掉,再喂入神經網絡。
第七回:預處理
在上面的推理中,我感覺是噪點影響了神經網絡的識別,于是乎我在送入網絡之前進行了去噪,二值化操作,訓練如下: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 張錯誤:
做到這里, 我對之前的推測有了猜疑:是噪點影響的嗎?我覺得不完全是。核心原因是我在嘗試的過程中對驗證碼進行了處理,從 RGB 的驗證碼變成了單通道的黑白驗證碼,使得圖片的信息減少了,神經網絡的計算量也大大減少了,網絡模型很快得到了收斂,loss 顯著減少,accuracy 在不斷提高。
整個過程是使用 CPU 進行訓練的,電腦配置是 Intel_Corei7-6700HQ_CPU@_2.60GHz,8G 內存。如果大家的電腦配置高,用 GPU 進行訓練,我覺得即使不做預處理,效果也能出來。
責任編輯:lq
-
cnn
+關注
關注
3文章
353瀏覽量
22281 -
tensorflow
+關注
關注
13文章
329瀏覽量
60583 -
驗證碼
+關注
關注
2文章
20瀏覽量
4722
原文標題:經驗總結:使用 TensorFlow 2 識別驗證碼過程中踩過的坑
文章出處:【微信號:tensorflowers,微信公眾號:Tensorflowers】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論