待破解的验证码形如:
这是一种常见的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 ☆☆☆