CNN实现验证码识别

Posted AI初见

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CNN实现验证码识别相关的知识,希望对你有一定的参考价值。

   验证码识别是CNN网络可以实现的一个较为简单的案例,通过本来,将会初步了解神经网络实现一项功能的大概步骤。此处先大体做个概括:

1)数据准备,准备需要的训练样本和测试样本,数据预处理等;

2)设计神经网络;

3)设置代价函数、优化策略、超参等;

4)训练,通过测试进行模型选择,不断调整网络结构、超参等重复训练选择最优模型

5)选择好模型后,测试模型

接下来按照上述步骤,一一做简介。


1      数据准备


  案例中以160*60*3RGB图像为例,即宽160、高60、包含RGB通道的彩色图像处理的数据,样式如图所示。

 本例中,采用captcha.image中的ImageCaptcha模块生成图片,生成方式如:

Image = ImageCaptcha(width, height); //设置图片宽高

context = image.generate(‘OStV’,’JPEG’); //生成内容为OStV的验证码图片

image.write(img, filepath); //保存

读取方式:

context = Image.open(filePath);

 

    因验证码识别不需要颜色等特征,只要有对应数字符号就行,因此可以把图像灰度化,如直接将RGB三个通道的像素值求平均,或者采用灰度转换公式Gray=R*0.299+G*0.584+B*0.114


2      CNN神经网络结构


CNN实现验证码识别

案例中的CNN网络结构大体如上图所示。

(1)    输入,160*60*1的图像

(2)    卷积层

卷积层的结构设计是一样的,步骤都是:

卷积->Relu->池化->dropout

三个卷积层设置不同

A)卷积层C1

卷积操作中:323*3*1的卷积核,步长为1Padding=’SAME’,即图像上下左右各补1个像素值为0,得到的卷积输出为160*60*32

卷积结果输入到Relu激励函数,得到激励的值

池化操作: 池化窗口2*2,步长2Padding=’SAME’,此处的Padding与卷积操作中不同,进行不对称补充,只补左、右中的一边和上、下中的一边,输出为80*30*32

Dropout操作:用于减少过拟合,最终得到得到的输出维度为80*30*32

B)卷积层C2

         卷积操作:643*3*32的卷积核,步长为1Padding=’SAME’,得到卷积结果80*30*64

卷积结果输入到Relu激励函数,得到激励的值

池化操作: 池化窗口2*2,步长2Padding=’SAME’,此处的Padding与卷积操作中不同,进行不对称补充,只补左、右中的一边和上、下中的一边,输出为40*15*64

Dropout操作:用于减少过拟合,最终得到得到的输出维度为40*15*64

C)卷积层C2

        卷积操作:643*3*64的卷积核,步长为1Padding=’SAME’,得到卷积结果40*15*64

卷积结果输入到Relu激励函数,得到激励的值

池化操作: 池化窗口2*2,步长2Padding=’SAME’,此处的Padding与卷积操作中不同,进行不对称补充,只补左、右中的一边和上、下中的一边,输出为20*8*64

Dropout操作:用于减少过拟合,最终得到得到的输出维度为20*8*64

 

(3)    全连接层


A)全连接FC1

      就是起到了分类器的作用,如果说卷积、池化、激活等操作将原始数据映射到隐层特征空间的话,全连接层则起到将学到的分布式特征表示映射到样本标记空间的作用。

B)全连接FC2

         其实际是输出层操作,全连接后将结果输入到Sigmoid函数,进而得到输出结果。


3      设置代价函数、优化策略、超参等


该示例中

a)代价函数为:最小错误率

b)优化策略:Adam

c)超参:

Batch:训练时为64,测试选择模型时为100

Dropout保存率keep_prob0.75,注意测试时应为全部的节点,即keep_prob设为1.0

 

4      训练


  创建session,初始化,并训练。在训练过程中,进行测试,不断调整超参等,优化训练结果,以争取获得最佳模型,保存模型。

 

5      测试


加载模型,输入待测图片,获取最佳判别结果。



6      部分源码


(1)    CNN网络

CNN实现验证码识别

CNN实现验证码识别

(2) 优化器与代价函数

CNN实现验证码识别

CNN实现验证码识别

(3) 训练主程序

CNN实现验证码识别

   训练程序的主要内容是:训练时获取批量样本(64个),进行训练,每训练100次就测试一次(100个测试样本),如果得到的准确率大于目前的准确率,就将模型保存,一旦准确率大于等于0.97时,就退出训练。最终得到训练的模型。

   保存的模型如图所示,0.97captcha.model-65000表示准确率为0.97,迭代了65000次,因为获取样本时时随机产生的,且batch为100,也就是说训练模型到0.97的准确率时,使用了650万条样本。此次训练大约用了4小时,如不同的设备时间不一致,当然设备性能越好时间越短。

 

7   测试结果


下图为一部分测试结果,Label为实际值,Predict为预测值,准确率为

0.795,很显然在测试样本上的准确率不如训练保存时的准确率,原因也很明显,待测样本有未知因素存在。



https://github.com/ldgang0530/wxgzh.git中的verificatonCode文件夹,该文件夹下有两个文件夹

verificationCode_image:先将生成的图片保存,然后读取图片再进行训练

verificationCode_noImage:不保存图片,而是使用时直接调用程序生成。此案例中采用verificationCode_noImage,训练用了大约4个小时;而 verificationCode_image耗时时间长,准确率差,由于程序可能存在一些问题,在训练的过程中前前后后改了一个周,效过也很差,如果有兴趣,可以研究研究。



以上是关于CNN实现验证码识别的主要内容,如果未能解决你的问题,请参考以下文章

验证码识别多输出模型

中文项目:快速识别验证码,CNN也能为爬虫保驾护航

(tensorflow CNN)验证码识别--生成验证码

用“活着的”CNN 进行验证码识别

验证码是怎么被机器识别的?Keras+CNN模型验证码识别详解

基于keras的cnn定长验证码识别