待破解的驗證碼形如:
這是一種常見的Java生成的驗證碼。網上有不少用 tensorflow 破解驗證碼的教程,代碼也不少,很多是學生畢業設計作品。
例如:使用深度學習來破解 captcha 驗證碼 : https://zhuanlan.zhihu.com/p/26078299
但是這種教程並不實用。我們知道,訓練神經網絡依賴於大規模人工標注數據集,要想破解驗證碼就要先准備數萬張驗證碼及其正確答案,而這些教程的第一步竟然是用驗證碼生成模塊生成二十萬張驗證碼得到數據集,須知現實場景是正確答案只有服務器知道。我也不知道它用的是哪個Java驗證碼生成庫,用的什么字體,扭曲划痕等等是如何設置的。
由這些教程只能得到兩個結論:
1. 需要有人標注不少於10萬份的驗證碼數據
2.需要買一塊N卡
二者均屬渺茫。最近Google出了一個 tensorflow.js,tfjs 能用 webgl 間接的使用上 mbp 的 intel iris 卡。終於重新燃起了希望。
我一鼓作氣標注了500張圖,滿懷希望的交給 tfjs 做訓練,然而結果不出意外, LOSS 極高,畢竟數據集太小了。MNIST 有 60 萬份數據集,而我只有 500 張圖。
幸而找到一篇實用教程:
用CNN識別驗證碼的實用教程 - Python開發社區 | CTOLib碼庫 : https://www.ctolib.com/fateleak-tensorflow-captcha-practice.html
根據該文形成如下思路:
1. 切割很重要。切割后一張圖的標注相當於 5 個標注。切割后訓練的目標變為字母,訓練難度大大下降。
2. 有打碼平台,可以交錢打碼。
目標驗證碼有較大的划痕,切割效果不算好,我從 500 張圖得到了 1368 個字母圖,標簽共 23 類。
然而該文代碼實用性較差,簡單的說就是不能直接跑起來。
這時又找到一篇好文:
15分鍾破解網站驗證碼 : http://www.bugcode.cn/break_captcha.html
利用該代碼,結合腐蝕等去除划痕的邏輯,僅靠這 500 張標注圖,訓練成功!
160/896 [====>.........................] - ETA: 1s - loss: 0.0492 - acc: 0.9875
224/896 [======>.......................] - ETA: 1s - loss: 0.0387 - acc: 0.9911
256/896 [=======>......................] - ETA: 0s - loss: 0.0342 - acc: 0.9922
320/896 [=========>....................] - ETA: 0s - loss: 0.0279 - acc: 0.9938
384/896 [===========>..................] - ETA: 0s - loss: 0.0268 - acc: 0.9948
448/896 [==============>...............] - ETA: 0s - loss: 0.0237 - acc: 0.9955
512/896 [================>.............] - ETA: 0s - loss: 0.0215 - acc: 0.9961
576/896 [==================>...........] - ETA: 0s - loss: 0.0245 - acc: 0.9948
640/896 [====================>.........] - ETA: 0s - loss: 0.0226 - acc: 0.9953
704/896 [======================>.......] - ETA: 0s - loss: 0.0211 - acc: 0.9957
768/896 [========================>.....] - ETA: 0s - loss: 0.0205 - acc: 0.9961
832/896 [==========================>...] - ETA: 0s - loss: 0.0193 - acc: 0.9964
896/896 [==============================] - 1s 1ms/step - loss: 0.0183 - acc: 0.9967 - val_loss: 0.1855 - val_acc: 0.9799
可以看到,識別成功率已達 0.9967!訓練這個模型花了多久呢?我,CPU,NOT GPU,不到一分鍾!500張圖 CPU 1 分鍾,這個結果相當理想了。
然而,字符切割並不總能成功,大部分圖切割不了(不能准確的切割為5個字符),切割成功率約 50%。但這也基本實用了,畢竟重新刷個一兩次就能登錄了,后面保持 session 即可。
該文使用的是 keras,在我的機器上以 tensorflow 為 backend。
為何前面的文說要有 1 萬張驗證碼呢?該文提到,打碼平台給的數據實際上有 2% 的標注信息的錯的,我在訓練過程發現,用錯誤的數據做訓練 loss 極高。這個驗證碼字體無變化,形狀略有扭曲而已,經過膨脹腐蝕等處理后訓練難度不高,但如果給的標注本身帶錯,對訓練的干擾將是災難。
之前公司項目里使用的也是這樣混合圖形算法和深度學習的技術方案。這次自己破解驗證碼體會很深,圖形算法較為經濟,速度快,耗費小,但是效果在復雜場景中差強人意,圖形算法不理想導致最終成功率偏低,在破解驗證碼是這樣,在公司項目也是這樣。深度學習算法對較為標准的較為單調的數據,對數據集的尺寸需求不高,模型訓練好之后,表現都能讓人滿意。
有時間會繼續摸索如何進一步提升成功率。
參考:
GitHub - lan2720/fuck-captcha: Machine Learning 2016 final project : https://github.com/lan2720/fuck-captcha
python驗證碼識別4:滴水算法分割圖片 - Hi!Roy! : http://www.hi-roy.com/2017/09/22/Python%E9%AA%8C%E8%AF%81%E7%A0%81%E8%AF%86%E5%88%AB4/
python-opencv2利用cv2.findContours()函數來查找檢測物體的輪廓 - CSDN博客 : https://blog.csdn.net/hjxu2016/article/details/77833336 ☆☆☆
用AI破解Captcha驗證碼 : https://zhuanlan.zhihu.com/p/32490928
15分鍾破解網站驗證碼 : http://www.bugcode.cn/break_captcha.html ☆☆☆☆
用CNN識別驗證碼的實用教程 - Python開發社區 | CTOLib碼庫 : https://www.ctolib.com/fateleak-tensorflow-captcha-practice.html ☆☆☆