zoukankan      html  css  js  c++  java
  • 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验证码下载地址
  • 相关阅读:
    python中的运算符的分类以及使用方法
    python的变量的命名规则以及定义
    C#和Java在重写上的区别
    IIS6 伪静态
    【读书笔记】Linux源码注释
    计算机是如何启动的?
    XSHELL下直接下载文件到本地(Windows)
    [转载]Linux 环境下编译 0.11版本内核 kernel
    虚拟化技术
    CentOS 6.4 编译安装LLVM3.3,Clang和Libc++
  • 原文地址:https://www.cnblogs.com/hls91/p/10880339.html
Copyright © 2011-2022 走看看