目前随着深度学习,越来越蓬勃的发展,在图像识别和语音识别中也表现出了强大的生产力。对于普通的深度学习爱好者来说,一上来就去跑那边公开的大型数据库,比如ImageNet或者CoCo,可以会觉得这个屠龙之技离生活好遥远。那么本文就是希望将此技术运用到一些普通用户日常就能感知的场景上,让普通用户切实能够体会到深度学习工具的非凡能力。
关键字:深度学习,验证码,破解,识别,CNN
很多普通程序员在入门爬虫的时候,基本上都会遇到的环节---“验证码”。就是这个东西使得很多程序的自动化工作止步,让人懊恼不已。关于验证码的功能,以前提到过(todo),本文不再赘述,只用一句话来概括下:验证是一种防止程序自动化的一个措施,其最常见的表现形式就是看图识别字符。
验证码技术就是一种反自动化技术。本文所解决的问题则是,使用深度学习技术来实现“全自动化的识别验证码”(这听起来有那么点人工智能的味道了)。
因为现在新的形式的验证产品很多,光从外界的展现形式上就有:
但是本文是以学习为目标,并不指向任何一种验证形式,而是指向传统的字符型验证码。由浅入深来对验证码进行一些科普。下图就是网络上的各色各样的字符型验证码,敬请大家赏析:
首先说明本文的观点:随着深度学习技术在图像处理技术上越来越强大的表现,这些传统的纯依靠简单图片的码式验证已经没有任何的安全性可言。
但是这些不安全的验证码却即使是在今天写这篇文章的时候,还存在于互联网的各个角落,存在于大互联网公司,基于像银行,证券和保险等等这些金融领域。
这些主要的应用场景包括:注册,登录,找回密码,抢购下单,评论,投票等等。如果这个地方不安全的话,也就是说能够通过程序做自动化,那么网络上的资源就会全部被自动化程序抢夺过去,或者说直接落入少数会做自动化的人的手中。为什么呢?因为普通计算机程序的计算能力是人的几万甚至几百万倍。
如果还不能理解,我说一个简单的例子吧,如果你自己去注册你的帐号密码需要3分钟完成,但是通过程序可以一秒钟注册300个账号。讲到这个地方,如果你还不理解,那么你想象在去年的时候互联网金融行业非常火爆时,每注册一个账号就有20块钱可以拿。也就是说比较厉害的人可以通过这个程序,一秒钟赚6000块钱。
如果你还不能理解这个东西的话,再举一些和大家日常生活中非常相关度高的一个场景:
类似的事情特别特别多。这个产业就叫做“薅羊毛”,顾名思义就是积少成多,有很小的成本把一点点的小的利益聚集起来就会变成一个比较可观的利益。
https://www.cndns.com/members/signin.aspx
http://reg.email.163.com/unireg/call.do?cmd=register.entrance&from=163navi®Page=163
https://passport.58.com/validcode/get?vcodekey=d5S2Tk7dofqN30VwIN6WTwvOHP6AkyvC&time=1466065243496
https://www.pingan.com.cn/pinganone/pa/index.screen?sid_source=toagw
https://www.creditease.cn/a/user/loadRegisterUserPage
http://www.95590.cn/ebiz/loginSkin.jsp?loginBackUrl=http://www.95590.cn/
下面是字符验证码两种比较极端的表现形式:
简单类型的特点:
复杂类型的特点:
在上一部分内容中举的现在线上应用的例子,基本上属于比较复杂的类型,但是由于它的设计理念仍然停留在图像学上,所以对于现在的CNN来说,是完全没有技术上的问题,毕竟很多深度学习框架的入门教程就是对手写数字数据库MNIST进行识别。它们有的区别只是前期准备工作的工作量的不同,这里所说的前期准备工作就是指:带标记的数据的准备工作。所谓的“带标记的数据”是指,需要人预先告诉计算机什么样的图片对应着是什么样的字符串,因为本问题中所用的CNN方法是属于有监督学习的范围,需要有个场外的“老师”进行指导。
关于上面两种极端的字符验证码的识别的技术方法,请移步文章末尾链接。
里面有两个例子,并附上了完整的源码:
当然后面的那种CNN的方法是对于解决此类问题是属于核武器级别的,CNN模式的优点缺点都很明显:
- 优点:通用性强,换一个模式后,可以不用修改代码就可以直接训练出新的模型。
- 缺点:需要大量的带标注的数据,特别是端到端的复杂一点的,可能需要几万带标记的先验数据集。
在CNN的文章中给出的demo,因为只是做效果演示,里面的数据集的生成是直接用的第三方标准库无限生成的。如果是在具体的场景去使用,则需要准备大量的带标记数据,像本文提到的困难的字符验证,如果要达到90%以上的正确识别率,估计需要5万带标记数据。下图是生成的部分先验数据集:
对于不同的多字符验证码,根据其难易程度分类,可以有一些不同的处理方式,有“蛮力型”的通用识别方法,也有“特事特办”的特别识别方法。
所谓的通用识别方法就是:流程化作业,基本不太需要在编程上思考太多。
通用步骤如下:
这其实是一个深度学习对分类问题处理的标准化流程。有不明白的地方,请补充一点相关的知识:
https://www.tensorflow.org/get_started/mnist/beginners
https://www.tensorflow.org/get_started/mnist/pros
由Google公司主推的深度学习框架tensorflow的入门文档里面就介绍了分别用矩阵回归和CNN神经网络对手写数字识别的方法。
当然,关于如何获取带标记的数据,目前也有比较便宜的获取渠道,直接在网上搜索“打码平台”,提供这“人工智能”领域的“人工”服务的厂家也不少,而且是明码标价:
对于字符型验证码,基本上是几分钱一张标记图吧。
虽然上面的通用型方法可以百试不爽,但是每次来一个新的问题,你都要准备大量的带标记数据,这个未免也太繁琐了,而且像一些简单的字符验证码的问题,其实倒没有必要去大动干戈。那么这个时候就需要一些小的技巧了。
这里所说的特别识别方法,仍然是基于深度学习这种通用方法来做的,只是我们可以将一些复杂问题进行适当的简化,这个思想有点类似于“降维”处理的意思。
因为深度学习具有这样的神奇效果:理论上对绝大多数的线性或者非线性问题都能实现非常好的拟合。
但是对于越复杂的问题,对数据的需求量越大。这个现状是无法避免的,但是我们却能够做一些人为的自动化工作,以达成此目标。
比如像这些验证:
不管它们色彩有多么的变化,不管背后加些啥乱七八糟的干扰点或者线,但是有一个事实他们无法回避,就是:他们的字符之间都是非常好分割的。也就是说,像这些类型的验证码,可以很容易将一个本来要判定N位字符串的问题简化为“判定1位字符,然后将N个这样的图片再组合起来”。这样网络的复杂度可以大大的简化,训练所需要的样数量,还有训练的时长都会大量减少。
如果验证码图片可以从N维“降维”到1维了,这个字符的字体如果是单一的,比如下面这些验证:
那么问题就更简单了:只需要为每个字符分类准备一张图片即可。也不是说如果你的验证码范围是[0,9],则只需要从下载的图片集中对0~9这几个数字每个标记一张即可,然后就是使用一些普通的数据增强技术:贴图,绽放,上下自由截取,随机噪点等等,可以生成无限多的数据集了,当然这些全部是由程序自动化完成。
好的图像预处理也很重要,所谓好的图像预处理,就是指能够将图像里面的主体特征变得更加明显,例如:
好的图像预处理会使识别问题难度直线下降,比如上面左图如果用CNN估计可能要1万样本,而右边的那个经过预处理后,估计只需要1千样本就OK了。
关于如何做数据增强,在后续的文章中会进行具体介绍。
如果对本话题有兴趣请持续关注本系列文章。
如果还想进一步讨论相应的技术,请加入QQ群:592109504
手机QQ扫描二维码:https://mp.weixin.qq.com/s/7RCtZH0ljuF5Ti6jgQxyww
验证识别合辑技术文章:https://zhuanlan.zhihu.com/p/30871712
后续会有更多干货文章,敬请期待。。。
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有