在实现网络爬虫的过程中,验证码的出现总是会阻碍爬虫的工作。本期介绍一种利用深度神经网络来实现的端到端的验证码识别方法。通过本方法,可以在不切割图片、不做模板匹配的情况下实现精度超过90%的识别结果。

本文分为两个部分,第一个部分介绍如何利用深度神经网络实现验证码的训练和识别,第二个部分介绍在实现过程中需要克服的工程问题。

一. 基于深度神经网络的验证码识别

验证码的识别是从图片到文字的过程。传统的算法如OCR正是为了解决此类问题而设计的。然而,在真实情形中,验证码通常并不以规则的文字出现,即文字通常会有不同程度的变形,图像本身也通常会被添加或多或少的噪声。这些干扰的出现,使得文字分割、模板匹配不再有效,进而OCR算法也很难解析出结果。

近年来,深度神经网络(DNN)在图像识别领域已经被证明了强大的识别能力。单个文字的识别是典型的分类问题。通常的做法为训练一个深度神经网络,网络的最后一层分为N种类别,代表字符的数目。比如对于英文字母,最后一层的分类器便是26个。比如经典的LeNet(http://yann.lecun.com/exdb/lenet/)即为解决单个文字识别的网络:

然而验证码通常包含多个字符,如何利用现有的网络实现这类分类问题呢?实际上这个问题再机器学习中被称为多标签训练问题。和上述每个图片输入只对应一个标签类别对比,这类分类的输出是多个标签。我们同样可以对传统的神经网络稍作改变以适应这种情况。

我们以最简单的英文字母为例介绍这个过程。如图一所示,此种验证码由5个字母组成;每个字母只取大写,共有26种类别;图片中有干扰线贯穿文字,使得文字分割比较困难。

图一. 验证码实例

接下来,我们设计如图二卷积神经网络:

图二. 卷积神经网络

图二中的网络和一般的CNN网络没有什么特殊之处,前部均是卷积、Pooling层,只有最后在分类时,将26个类别扩增到26*5=130个类别。对于每幅图片的标签而言,在这130维的向量中,每26个维度中有一个1,其余为0,编码了五个字母。接着依然使用交叉熵作为代价函数进而优化此网络。就这样,只要对原先的分类网络做简单的改变即可解决验证码的识别问题。

再如对于数学表达式类型的验证码,我们的网络也只是在编码上把26分类问题变成了13分类问题。下例中(见图三)最后一层的分类器便设计为3*13=39个类别。

图三. 数学式类型验证码的识别

按照此种思路我们破解了很多风格的验证码,如图四所示:

图四. 不同风格验证码破解实例

二. 一些需要解决的实际工程问题

(1) 合成训练数据

前文提到训练的前提是已经拥有了大量的训练数据,而实际在识别验证码时我们很难获取足够多的标注过的训练数据。所以,我们不得不人工合成训练数据。这一部分通常可以调用Java或者C#的文字渲染库来完成。

训练的数据并不是越多越好,主要的问题在于人工合成的数据未免和真实验证码在形态上有些差距,我们都很难合成出一模一样的结果。字体、字号及变形程度都或多或少与真实数据不同,而这种不同可能直接导致训练出的网络面对真实数据时无法发挥作用。

我们的经验是,针对真实数据的特点,在无法很相似地合成出训练数据的情况下,要增大样本的多样性,实际上也是遵循了深度学习中数据增强(Data Augmentation)的思想。如图五所示,左边为真实数据,我们在合成数据时特意增加了每个文字的旋转、平移,加大了噪声,使得训练出的网络能应对数据足够的变化,从而可以识别出左图中真实的例子。否则即便在合成数据上达到了很高的精度,在真实数据上也依然可能精度极低(即在合成数据上过拟合)。

图五. 合成数据实例

(2) 网络大小的选择

针对不同的任务,网络大小对结果的影响也是巨大的。并非所有的任务都得使用很深的网络来训练。理论上说,越深的网络自由度越大,同时也非常容易过拟合。虽然有weight_decay这样参数可以一定程度的对抗过拟合,但通常难度依然是很大的。所以一般来说,对于不太复杂的验证码应该选择较小的网络,只有遇到比较复杂的验证码如中文的成语等,我们的经验才是复杂的网络下效果才更好。

总之,验证码识别可以作为深度学习的一个练手项目来学习,在这个实际项目中可以更容易理解到深度学习理论中诸多概念。

转载于:http://www.saluzi.com/t/topic/16027

如何使用深度学习破解验证码 keras 连续验证码的更多相关文章

  1. TensorFlow - 深度学习破解验证码 实验

    TensorFlow - 深度学习破解验证码 简介:验证码主要用于防刷,传统的验证码识别算法一般需要把验证码分割为单个字符,然后逐个识别,如果字符之间相互重叠,传统的算法就然并卵了,本文采用cnn对验 ...

  2. 【转】TensorFlow练习20: 使用深度学习破解字符验证码

    验证码是根据随机字符生成一幅图片,然后在图片中加入干扰象素,用户必须手动填入,防止有人利用机器人自动批量注册.灌水.发垃圾广告等等 . 验证码的作用是验证用户是真人还是机器人:设计理念是对人友好,对机 ...

  3. 深度学习框架: Keras官方中文版文档正式发布

    今年 1 月 12 日,Keras 作者 François Chollet‏ 在推特上表示因为中文读者的广泛关注,他已经在 GitHub 上展开了一个 Keras 中文文档项目.而昨日,Françoi ...

  4. 吴裕雄--天生自然神经网络与深度学习实战Python+Keras+TensorFlow:TensorFlow与神经网络的实现

    import tensorflow as tf import numpy as np ''' 初始化运算图,它包含了上节提到的各个运算单元,它将为W,x,b,h构造运算部件,并将它们连接 起来 ''' ...

  5. 吴裕雄--天生自然神经网络与深度学习实战Python+Keras+TensorFlow:Bellman函数、贪心算法与增强性学习网络开发实践

    !pip install gym import random import numpy as np import matplotlib.pyplot as plt from keras.layers ...

  6. 吴裕雄--天生自然神经网络与深度学习实战Python+Keras+TensorFlow:RNN和CNN混合的鸡尾酒疗法提升网络运行效率

    from keras.layers import model = Sequential() model.add(embedding_layer) #使用一维卷积网络切割输入数据,参数5表示每各个单词作 ...

  7. 吴裕雄--天生自然神经网络与深度学习实战Python+Keras+TensorFlow:LSTM网络层详解及其应用

    from keras.layers import LSTM model = Sequential() model.add(embedding_layer) model.add(LSTM(32)) #当 ...

  8. 吴裕雄--天生自然神经网络与深度学习实战Python+Keras+TensorFlow:使用TensorFlow和Keras开发高级自然语言处理系统——LSTM网络原理以及使用LSTM实现人机问答系统

    !mkdir '/content/gdrive/My Drive/conversation' ''' 将文本句子分解成单词,并构建词库 ''' path = '/content/gdrive/My D ...

  9. 深度学习:Keras入门(一)之基础篇

    1.关于Keras 1)简介 Keras是由纯python编写的基于theano/tensorflow的深度学习框架. Keras是一个高层神经网络API,支持快速实验,能够把你的idea迅速转换为结 ...

随机推荐

  1. 表达式求值 (栈) 用C++实现

    #include <cstdio> #include <cstdlib> #include <cmath> #include <stack> #incl ...

  2. Android 百度地图 SDK v3.0.0 (四) 引入离线地图功能

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/37758097 一直觉得地图应用支持离线地图很重要啊,我等移动2G屌丝,流量不易, ...

  3. jQuery事件与动画

    一 事件 1 加载DOM事件 $(document).ready():执行时机:DOM元素准备就绪  执行次数:多次  简单写法:原:$(document).ready(function(){})  ...

  4. hdu 2190

    //hdu2190 水题  题意是给一个n*3的教室,用1*1,2*2的砖去铺满,有多少种铺法,一开始没发现这个规律,想了一下,应该是递归. #include <iostream> usi ...

  5. 浅谈PHP代码设计结构

    浅谈PHP代码设计结构 您的评价:       还行  收藏该经验       coding多年,各种代码日夜相伴,如何跟代码友好的相处,不光成为职业生涯的一种回应,也是编写者功力的直接显露. 如何看 ...

  6. iOS-OC-基础-NSObject常用方法

    Person *person1 = [[Person alloc]init]; Person *person2 = [[Person alloc]init]; // 可以调用类中的私有方法,但是会有一 ...

  7. preventDefault() 方法 取消掉与事件关联的默认动作

    前几天写的 响应键盘的图片切换 中, 键盘总是让浏览器滚动,为了取消掉默认的事件,使用了 preventDefault() 方法 定义和用法 preventDefault() 方法取消事件的默认动作. ...

  8. 【推荐】Java工程师如何从普通成为大神值得一读

    本文源自 http://www.hollischuang.com/archives/489 一点感悟 java作为一门编程语言,在各类编程语言中作为弄潮儿始终排在前三的位置,这充分肯定了java语言的 ...

  9. swing菜单,常用组件,常用容器

    1菜单 import javax.swing.*; import java.awt.*; import java.awt.event.InputEvent; import java.awt.event ...

  10. Qt 数据库创建表失败原因之数据库关键字

    本人数据库新手,在创建表时出现问题,最后经查证,找出问题所在.下面的程序是部分节选,在创建数据库表的时候,起先使用的L24的CreateDB,经测试,一直输出 Create testResult Fa ...