• Tensorflow实战(二):Discuz验证码识别


    一、前言

    验证码是根据随机字符生成一幅图片,然后在图片中加入干扰象素,用户必须手动填入,防止有人利用机器人自动批量注册、灌水、发垃圾广告等等 。

    验证码的作用是验证用户是真人还是机器人。

    本文将使用深度学习框架Tensorflow训练出一个用于破解Discuz验证码的模型。

    自动生成验证码接口关闭,原因如下:

    Tensorflow实战(二):Discuz验证码识别

    接口是用来方便大家获取验证码图片的,已经声明至少加200ms延时,但是有些人就是不管不顾,个人网站带宽不大,直接被占满(自己写代码让别人爬自己网站真是找罪受),服务器被蹂躏十多分钟。这种情况已经出现很多次了,实在受不了,只能关闭此功能,望谅解了。

    想要Discuz验证码生成代码(php)的,到网盘下载吧(密码:nf1t):

    二、背景介绍

    我们先看下简单的Discuz验证码。

    Tensorflow实战(二):Discuz验证码识别

    打开下面的连接,你就可以看到这个验证码了。

    https://cuijiahua.com/tutrial/discuz/index.php?label=jack

    怎么获取其他验证码呢?我已经为大家准备好了api,格式如下:

    观察上述链接,你会发现label后面跟着的就是要显示的图片字母,改变label后面的值,我们就可以获得不同的Discuz验证码图片。

    如果会网络爬虫,我想根据这个api获取Discuz验证码图片对你来说应该很Easy。

    不会网络爬虫也没有关系,爬虫代码我已经为你准备好了。创建一个get_discuz.py文件,添加如下代码:

    运行上述代码,你就可以下载5000张Discuz验证码图片到本地,但是要注意的一点是:请至少加200ms延时,避免给我的服务器造成过多的压力,如发现影响服务器正常工作,我会关闭此功能。

    你好我也好,大家好才是真的好!

    验证码下载过程如下图所示:

    Tensorflow实战(二):Discuz验证码识别

    当然,如果你想省略麻烦的下载步骤也是可以的,我已经为大家准备好了6万张的Discuz验证码图片。我想应该够用了吧,如果感觉不够用,可以自行使用爬虫程序下载更多的验证码。

    6万张的Discuz验证码图片可到文章末尾处下载。

    准备好的数据集,它们都是100*30大小的图片:

    Tensorflow实战(二):Discuz验证码识别

    什么?你说这个图片识别太简单?没关系,有高难度的!

    点我查看,认出是什么字母算我输!

    我打开的图片如下所示:

    Tensorflow实战(二):Discuz验证码识别

    这是一个动图,并且还带倾斜、扭曲等特效。怎么通过api获得这种图片呢?

    没错,只要添加一些参数就可以了,格式如上图所示,每个参数的说明如下:

    • label:验证码
    • width:验证码宽度
    • height:验证码高度
    • background:是否随机图片背景
    • adulterate:是否随机背景图形
    • ttf:是否随机使用ttf字体
    • angle:是否随机倾斜度
    • warping:是否随机扭曲
    • scatter:是否图片打散
    • color:是否随机颜色
    • size:是否随机大小
    • shadow:是否文字阴影
    • animator:是否GIF动画

    你可以根据你的喜好,定制你想要的验证码图片。

    个人感觉,下面这样的动图还是不错的:

    Tensorflow实战(二):Discuz验证码识别

    不过,为了简单起见,我们只使用最简单的验证码图片进行验证码识别。

    数据集已经准备好,那么接下来进入本文的重点,Tensorflow实战。

    三、Discuz验证码识别

    我们已经将验证码下载好,并且文件名就是对应图片的标签。这里需要注意的是:我们忽略了图片中英文的大小写。

    1、数据预处理

    首先,数据预处理分为两个部分,第一部分是读取图片,并划分训练集和测试集。因为整个数据集为6W张图片,所以我们可以让训练集为5W张,测试集为1W张。随后,虽然标签是文件名,我们认识,但是机器是不认识的,因此我们要使用text2vec,将标签进行向量化。

    明确了目的,那开始实践吧!

    读取数据:

    我们通过定义rate,来确定划分比例。例如:测试集1W张,训练集5W张,那么rate=1W/5W=0.2。

    标签向量化:

    既然需要将标签向量化,那么,我们也需要将向量化的标签还原回来。

    运行上述测试代码,你会发现,文本向量化竟如此简单:Tensorflow实战(二):Discuz验证码识别

    这里我们包括了63个字符的转化,0-9 a-z A-Z _(验证码如果小于4,用_补齐)。

    2、根据batch_size获取数据

    我们在训练模型的时候,需要根据不同的batch_size"喂"数据。这就需要我们写个函数,从整体数据集中获取指定batch_size大小的数据。

    上述代码无法运行,这是我封装到类里的函数,整体代码会在文末放出。现在理解下这段代码,我们通过train_flag来确定是从训练集获取数据还是测试集获取数据,通过batch_size来获取指定大小的数据。获取数据之后,将batch_size大小的图片数据和经过向量化处理的标签存放到numpy数组中。

    3、CNN模型

    网络模型如下:

    3卷积层+1全链接层。

    继续看下我封装到类里的函数:

    为了省事,name_scope什么都没有设定。每个网络层的功能,维度都已经在注释里写清楚了,甚至包括tensorflow相应函数的说明也注释好了。

    如果对于网络结构计算不太了解,推荐看下LeNet-5网络解析:

    https://cuijiahua.com/blog/2018/01/dl_3.html

    LeNet-5的网络结构研究清楚了,这里也就懂了。

    4、训练函数

    准备工作都做好了,我们就可以开始训练了。

    上述代码依旧是我封装到类里的函数,与我的上篇文章《Tensorflow实战(一):打响深度学习的第一枪 – 手写数字识别(Tensorboard可视化)》重复的内容不再讲解,包括Tensorboard的使用方法。

    这里需要强调的一点是,我们需要在迭代到500次的时候重新获取下数据集,这样做其实就是打乱了一次数据集。为什么要打乱数据集呢?因为如果不打乱数据集,在训练的时候,Tensorboard绘图会有如下现象:

    Tensorflow实战(二):Discuz验证码识别

    可以看到,准确率曲线和Loss曲线存在跳变,这就是因为我们没有在迭代一定次数之后打乱数据集造成的。

    同时,虽然我定义了dropout层,但是在训练的时候没有使用它,所以才把dropout值设置为1。

    5、整体训练代码

    指定GPU,指定Tensorboard数据存储路径,指定最大迭代次数,跟Tensorflow实战(一)的思想都是一致的。这里,设置最大迭代次数为100W次。

    我使用的GPU是Titan X,如果是使用CPU训练估计会好几天吧....

    创建train.py文件,添加如下代码:

    代码跑了一个多小时终于跑完了,Tensorboard显示的数据:

    Tensorflow实战(二):Discuz验证码识别

    准确率达到百分之90以上吧。

    6、测试代码

    已经有训练好的模型了,怎么加载已经训练好的模型进行预测呢?在和train.py相同目录下,创建test.py文件,添加如下代码:

    运行程序,随机从测试集挑选5张图片,效果还行,错了一个字母:

    Tensorflow实战(二):Discuz验证码识别

    四、总结

    • 通过修改网络结构,以及超参数,学习如何调参。
    • 可以试试其他的网络结构,准确率还可以提高很多的。
    • Discuz验证码可以使用更复杂的,这仅仅是个小demo。
    • 如有问题,请留言。如有错误,还望指正,谢谢!

    本文出现的所有代码和数据集,均可在我的github上下载,欢迎Follow、Star:https://github.com/760730895/Tensorflow-Discuz-

    【. . . . . .本博客仅作个人生活、工作、学习等的日常记录。说明: (1) 内容有参考其他博主、网页等,有因“懒”直接粘贴来,会备注出处。若遇雷同,或忘备注,并无故意抄袭之意,请诸“原主”谅解,很感谢您的辛勤"笔记"可供本人参考学习。 (2) 如遇同行,有参考学习者,因个人学识有限,不保证所写内容完全正确。您对本博文有任何的意见或建议,欢迎留言,感谢指正。 (3) 若您认为本主的全博客还不错,可以点击关注,便于互相学习。 (4) 感谢您的阅读,希望对您有一定的帮助。欢迎转载或分享,但请注明出处,谢谢。. . . . . .】

    文件下载Discuz验证码下载地址
  • 相关阅读:
    链表--判断一个链表是否为回文结构
    矩阵--“之”字形打印矩阵
    二叉树——平衡二叉树,二叉搜索树,完全二叉树
    链表--反转单向和双向链表
    codeforces 490C. Hacking Cypher 解题报告
    codeforces 490B.Queue 解题报告
    BestCoder19 1001.Alexandra and Prime Numbers(hdu 5108) 解题报告
    codeforces 488A. Giga Tower 解题报告
    codeforces 489C.Given Length and Sum of Digits... 解题报告
    codeforces 489B. BerSU Ball 解题报告
  • 原文地址:https://www.cnblogs.com/hls91/p/10880339.html
Copyright © 2020-2023  润新知