Discuz验证码识别(准备篇)-写给程序员的TensorFlow教程

蛰伏了快两个月了,终于迎来了新系列的第一篇文章。斟酌来斟酌去,决定将系列名字定为-《写给程序员的TensorFlow教程》也算是给这个系统文章定个基调。

太多的TensorFlow入门教程上来就是列了一系列国外的文献,视频。或者直接扔一堆代码,实在难以称之为入门。我们希望针对想学习TensorFlow的程序员来写一系列教程,聊一聊如何在基本掌握python的情况下,能够快速的使用TensorFlow这个工具解决实际问题。

首先,这个系列文章是之前的系列-《反爬与反反爬的奇技淫巧》的番外篇,

之所以是反爬系列的番外篇,因为我们主要是讨论如果使用TensorFlow解决爬虫中常见的问题,包括验证码,图片电话号码识别这类问题(这个系列主要是图像识别)。不过虽然跟反爬相关,但是这个系列依然可以独立来看,不做爬虫的朋友也不会受影响。

作为系列文章第一篇,先说说这个系列的定位,我们希望能给广大想转型机器学习(准确说是Tensorflow实现的神经网络)的程序员带来一些不一样的内容,我们不讲公式,只调方法,不聊文献,只说代码。不求最好,只求有用。正如下面这个自带bgm的表情:

那么我认为对于想要转型的程序员来说,做到以下四点就算基本转型成功了:

1.了解一定的机器学习原理(类似写web,我们要知道http的包结构,知道tcp的三次握手即可)

2.大方向上知道遇到什么问题该用什么机器学习算法来解决(成熟的大类就几个,很容易掌握)

3.熟悉主流算法的实现方案和用法,最好自己有一套对主流方案的封装(做到这一点其实已经很好了)

4.掌握整个从测试环境到生产环境的完整流程(通俗点就是会做能上线的产品,这一点很重要却最容易被忽略)

好了,扯了这么多题外话,我们正式开始:

一、准备部分

在我们动手写代码之前还是要有一些准备工作:

首先我们要对整个问题和解决方案有一个宏观的认知,另外为了方便,本文所有的提到机器学习的地方都可以等价为神经网络实现的监督学习这个领域,关于其他机器学习的领域不在本系列的讨论范围以内。(如果没入门的朋友可以忽略这句话)

1.知识的准备

先说说问题,我们今天要从一个最简单的验证码识别问题入手,我们看下我们的敌人:

就是这货,看着不复杂,没有太多杂点杂线。不过我们说他最简单,绝对不是说的这些,而是这个验证码我们是有生成代码的(Discuz是开源的)。这就意味着我们有无穷多的标注好的验证码图片(就是自带识别结果的图片)。这个对于机器学习来说简直就是无敌了。

聊完问题,我们再整体聊一聊Tensorflow和机器学习的解题思路。我们上学的时候,无论遇到什么问题总有一个解题思路,否则绝对是一头雾水。所谓隔行如隔山,很多时候是因为我们不了解那个行业解决一个常规问题的解题思路,那么机器学习的解题思路是什么呢?

当我们拿到一个问题决定用机器学习的方法解决他,我们要做以下几步:

第一步:将问题分解成输入(x)到输出(y)这样的结构,如Discuz验证码的输入是图片,输出是四个字符的字符串

第二步:找到很多同时包含输入输出的数据,比如很多有识别结果的验证码图片

第三步:针对不同问题,找到算法大神们的已经定义好的算法并实现成代码

第四步:尝试使用这个算法训练这些数据,如果效果不好,算法中有一些参数可以手动调整,至于怎么调,可以参考前人经验,也可以自己瞎调积累经验。

第五步:写一个程序载入模型,接受一个新的输入值,通过模型计算出新的输出值。

以上应该还算通俗易懂,唯一值得提一下的就是第四步中的效果不好,效果不好主要是指训练了大半天,准确度还是很低或者忽高忽低(所谓不收敛或者收敛的速度很慢),当然还有些其他效果不好,不过对于入门级来说,其他的效果不好我们甚至可以认为是成功了。

好,咱们了解这么多,就可以开始写代码了。

2.环境搭建:

俗话说万事开头难,对于程序员来说,就是搭建环境了。相对于其他环境来说 Tensorflow环境搭建起来应该说中度难度。顺利的话,按照官方教程一步步走完就好。不顺利就比较糟心了。这里我们蛰伏了两个月就是为了给大家提供一个免安装的实验环境,大家登陆神箭手,直接创建Tensorflow应用就可以在线写Tensorflow了,非常方便。我们后面的教程都是基于线上的,不过线上环境和线下环境完全兼容,所以在哪写都可以。

3.数据准备

前面说了解题思路,第一步,已经把验证码识别问题分解成输入x和输出y,那么我们就要进行第二步准备数据了。这步应该也是这一篇文章中唯一涉及代码的部分。我们首先下载Discuz源码,找到其中实现生成验证码的文件source\module\misc\misc_seccode.php,我们将核心代码抽取出来,并实现一个我们可以指定字符的逻辑,具体代码我已经上传到github上:

ShenJianShou/tensorflow_tutorial

另外我也自己上传了一份,大家可以通过访问如下地址获取生成的验证码图片:

shujuheiban.com/tutoria

大家可以替换label后面的字符生成自己想要的验证码图片。

虽然我们已经实现了在线生成无穷多的带结果的验证码图片,但是一般来说,我们还是尽量减少在TensorFlow中对网络的请求,这样会降低整个训练的速度。另外对我们最终上线的时候也会造成不必要的麻烦,所以我们一般都会把图片和识别结果整理好,这里我采用神箭手上的爬虫请求并存储15万的数据备用(其实想要多少就多少,15万我觉得足足够了)


代码也在github上:

ShenJianShou/tensorflow_tutorial

这两份代码我就不展开讲了,因为这不是我们的重点,如果大家不是在我们神箭手上写TensorFlow的话,第二份爬虫的代码完全可以自己本地实现,也可以用神箭手爬取好了之后导出到本地CSV,具体的大家可以自行根据自己的技术栈来完成这些准备工作。

这里特殊提一下一个小问题,下一篇文章我们也会在讲到,就是为什么我们要在爬虫里把base64中的一些字符进行替换:

page.raw = page.raw.replace(/\+/g,"-").replace(/\//g,"_").replace(/\s+/g,"")

那是因为TensorFlow自带的tf.decode_base64中并不是使用的标准base64,而是将标准base64中的+替换成了-,/替换成了_,因此我们提前先做一次转换。另外我们之所以用TensorFlow中的base64方法而不用python自带的base64方法我们会在下一篇文章中讲到。

4.算法准备

好了,到了最激动人心的算法准备部分了。这里先扔出一个观点(来自fast.ai的创始人):图像识别基本已经算是一个已解决的问题。也就是说我们以后凡是遇到图像中的物体识别,都可以考虑用机器学习来搞定,而搞定的方案也非常成熟,就是如日中天的CNN,当然具体也有很多种实现方式和架构,这里我们不深入讨论,既然是入门,我们只需要实现一个最基本的CNN即可,更何况我们的数据集可以是无限大,还能奢求什么呢。

你们以为我要讲CNN了吗,那这还是入门教程的第一课吗。其实什么是NN,什么是CNN我个人认为刚开始也不用太理解,大家只要知道这就是解决验证码识别目前的最佳方案就可以了,具体怎么实现,我们可以先抄代码,然后封装成一个函数,以后每次使用不就可以了(当然了,有人说keras都已经做好了,干嘛还要在用tensorflow费劲巴拉的实现一遍。这个嘛,咱们虽然现在是入门,但是也不能一直都停留在入门级别,所谓抄码百遍,其义自见,先混个眼熟)

=====================================================================

好了通过以上的准备,我们的解题思路中的第一、二步都搞定了,第三步选中的算法是最基本的CNN,不过还没有实现,第四、五步还没有做,那么我们下一篇文章就详细讨论下最基本的CNN如何使用TensorFlow实现以及过程中一些常见的问题。

分享到: