在學(xué)習(xí)了 CNN 之后,我一直想去做一個驗(yàn)證碼識別。網(wǎng)上找了很多資料,雜七雜八的一大堆,但是好多是 tf1 寫的。我對 tf1 不太熟悉,于是自己開始了基于 TensorFlow 2 的摸索實(shí)踐。
摸索的過程異常艱難,一開始我直接用 captcha 生成了 10080 張驗(yàn)證碼去識別,發(fā)現(xiàn) loss 一直停留在 2.3 左右,accuracy 一直是 0.1 左右,訓(xùn)練了 100 回合,也沒什么提升,電腦都快要跑廢了,咋辦呀?于是網(wǎng)上各種問大佬,找到機(jī)會就提問,其中一位大佬的回答讓我受到了啟發(fā),他說:你可以先識別 1 位,然后 2 位,3 位,最后 4 位,一步一步來……。
本文主要描述我在驗(yàn)證碼識別過程中的一些摸索,整理出來以供大家參考:
第一回:搭建網(wǎng)絡(luò)結(jié)構(gòu)
首先我們需要搭建網(wǎng)絡(luò)結(jié)構(gòu),如下:
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:
我的訓(xùn)練數(shù)據(jù)量:train count: 7408, valid count: 3176, test count: 4536
樣本圖:
訓(xùn)練結(jié)果:
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 也很低,不知道出現(xiàn)了什么原因,困擾一兩個星期,都想要放棄了,太難了。但是我不死心,非要把它搞出來,4 位識別不出來,能不能先識別一位呢?好,那就開始搞,一位比較簡單,跟 Mnist 數(shù)據(jù)集很相似,在這我就不贅述了。
第二回:2 位彩色驗(yàn)證碼訓(xùn)練
接著來識別 2 位的驗(yàn)證碼。train count: 441, valid count: 189, test count: 270
樣本圖:
下面是我用 2 位驗(yàn)證碼進(jìn)行訓(xùn)練的結(jié)果:
30 張圖片進(jìn)行測試,結(jié)果:
哎呦,有感覺了,有了起色了,但是出現(xiàn)了過擬合的現(xiàn)象,解決過擬合的方法主要有:
Get more training data
Reduce the capacity of the network
Add weight regularization
Add dropout
Data-augmentation
Batch normalization
第三回:增加彩色驗(yàn)證碼數(shù)據(jù)集
于是我就增加了數(shù)據(jù)集。train count: 4410, valid count: 1890, test count: 2700
然后又出現(xiàn)了 loss 一直在 2.3,accuracy 在 0.09 左右,這是什么鬼呢?但是我還是不死心呀,繼續(xù)想辦法呀,既然彩色的有難度,我先識別黑白的樣本行不行呢,先試試吧。
第四回:2 位黑白驗(yàn)證碼訓(xùn)練
網(wǎng)絡(luò)結(jié)構(gòu)依然采用上面的,input_shape(100,120,3)。
這是我用 2 位的黑白圖片的驗(yàn)證碼進(jìn)行了訓(xùn)練,效果很好,收斂也很快。
訓(xùn)練第 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
隨機(jī)選取了 30 張圖片進(jìn)行了測試,2 張識別錯了:
樣本圖:
看著這結(jié)果,我露出了潔白的大牙,信心大增呀,繼續(xù)搞,直接上 4 位驗(yàn)證碼。
第五回:4 位黑白驗(yàn)證碼訓(xùn)練
依然采用上面的網(wǎng)絡(luò)結(jié)構(gòu),這次使用的是 4 位黑白圖片的驗(yàn)證碼。train count: 2469, valid count: 1059, test count: 1512
訓(xùn)練第 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
隨機(jī)選取 30 張圖片進(jìn)行測試,8 張錯誤:
4 位驗(yàn)證碼的樣本圖:
從結(jié)果來看,有點(diǎn)過擬合,沒關(guān)系,繼續(xù)加大數(shù)據(jù)集。
第六回:增加黑白驗(yàn)證碼數(shù)據(jù)集
依舊采用上面的網(wǎng)絡(luò)結(jié)構(gòu),這次我增加了數(shù)據(jù)集 4939 張,依舊使用的是 4 位黑白的驗(yàn)證碼,訓(xùn)練結(jié)果還是挺好的: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
可以看出 訓(xùn)練集的準(zhǔn)確率 跟驗(yàn)證集上很接近,隨機(jī)選取 30 張圖片進(jìn)行測試,6 張錯誤圖如下:
好了,搞了這么多,由此我覺得是噪點(diǎn)影響了深度學(xué)習(xí)的識別,maxpool 的時候連帶著噪點(diǎn)也采樣了,我們需要將噪點(diǎn)處理掉,再喂入神經(jīng)網(wǎng)絡(luò)。
第七回:預(yù)處理
在上面的推理中,我感覺是噪點(diǎn)影響了神經(jīng)網(wǎng)絡(luò)的識別,于是乎我在送入網(wǎng)絡(luò)之前進(jìn)行了去噪,二值化操作,訓(xùn)練如下:train count: 4939, valid count: 2117, test count: 3024
從圖中可以看出,模型收斂了,但有點(diǎn)過擬合,第 20 回合訓(xùn)練結(jié)果如下:
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
隨機(jī)選取了 30 張圖片進(jìn)行了測試,8 張錯誤:
做到這里, 我對之前的推測有了猜疑:是噪點(diǎn)影響的嗎?我覺得不完全是。核心原因是我在嘗試的過程中對驗(yàn)證碼進(jìn)行了處理,從 RGB 的驗(yàn)證碼變成了單通道的黑白驗(yàn)證碼,使得圖片的信息減少了,神經(jīng)網(wǎng)絡(luò)的計(jì)算量也大大減少了,網(wǎng)絡(luò)模型很快得到了收斂,loss 顯著減少,accuracy 在不斷提高。
整個過程是使用 CPU 進(jìn)行訓(xùn)練的,電腦配置是 Intel_Corei7-6700HQ_CPU@_2.60GHz,8G 內(nèi)存。如果大家的電腦配置高,用 GPU 進(jìn)行訓(xùn)練,我覺得即使不做預(yù)處理,效果也能出來。
責(zé)任編輯:lq
-
cnn
+關(guān)注
關(guān)注
3文章
352瀏覽量
22231 -
tensorflow
+關(guān)注
關(guān)注
13文章
329瀏覽量
60537 -
驗(yàn)證碼
+關(guān)注
關(guān)注
2文章
20瀏覽量
4717
原文標(biāo)題:經(jīng)驗(yàn)總結(jié):使用 TensorFlow 2 識別驗(yàn)證碼過程中踩過的坑
文章出處:【微信號:tensorflowers,微信公眾號:Tensorflowers】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
評論