深度学习卷积神经网络识别光学字符验证码,及captcha使用简单案例

深度学习卷积神经网络识别验证码

文章目录

  • 深度学习卷积神经网络识别验证码
    • 一、引言
    • 二、导入必要的库
    • 三、防止 tensorflow 占用所有显存
    • 四、定义数据生成器并测试
    • 五、定义网络结构
    • 六、训练模型
    • 七、测试模型

一、引言

验证码识别,本身使用来判断访问网站的用户是不是一个真人,但是随着人工智能的发展,尤其是深度卷积神经网络的发展,使得验证码识别机器还是人的底线再被层层攻破,本文所使用的captcha 可以生成语音和图片验证码,验证码是由数字、大写字母、小写字母组成,可以自动生成验证码。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-E7jq6PxI-1693272688113)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20230828213513905.png)]

最好掌握的预备知识:

  • 有python脚本编程基础;
  • 了解图像处理、计算机视觉理论基础;
  • 对Opencv有一定的认识;
  • 对图像处理有操作经验;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6EZ6HRR7-1693272688114)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20230828213911621.png)]
目的:通过Python语言与其各种资源库如numpy,pillow,tensorflow,keras等来实现。将效果实现出来。了解如何使用catptcha自动生成验证码数据,同时使用tensorflow撰写网络,来完成验证码训练,将使用高级框架的keras作为手写字母的网络主体。

二、导入必要的库

我们需要导入一个叫 captcha 的库来生成验证码。

我们生成验证码的字符由数字和大写字母组成。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9xBRQPC1-1693272688115)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20230828185346056.png)]

导入成功后,我们使用jupyter notebook编写代码,使用py3.6.9,TensorFlow2.0+

from captcha.image import ImageCaptcha
import matplotlib.pyplot as plt
import numpy as np
import random
import tensorflow as tf%matplotlib inline
%config InlineBackend.figure_format = 'retina'#输出所有的ascii,用来生成验证码
import string
characters = string.digits + string.ascii_uppercase
print(characters)#验证码的长、宽、字符数、类别数
width, height, n_len, n_class = 128, 64, 4, len(characters)

输出结果:

0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ

三、防止 tensorflow 占用所有显存

#下面就是实现按需分配的代码
gpus = tf.config.experimental.list_physical_devices('GPU')
if gpus:try:#设置仅在需要时申请显存空间for gpu in gpus:tf.config.experimental.set_memory_growth(gpu, True)logical_gpus = tf.config.experimental.list_logical_devices('GPU')print(len(gpus), "Physical GPUs,", len(logical_gpus), "Logical GPUs")except RuntimeError as e:print(e)

四、定义数据生成器并测试

from tensorflow.keras.utils import Sequenceclass CaptchaSequence(Sequence):#这里传入的参数与上面的导入模块常量相对应def __init__(self, characters, batch_size, steps, n_len=4, width=128, height=64):self.characters = charactersself.batch_size = batch_sizeself.steps = stepsself.n_len = n_lenself.width = widthself.height = heightself.n_class = len(characters)self.generator = ImageCaptcha(width=width, height=height)def __len__(self):return self.stepsdef __getitem__(self, idx):X = np.zeros((self.batch_size, self.height, self.width, 3), dtype=np.float32)y = [np.zeros((self.batch_size, self.n_class), dtype=np.uint8) for i in range(self.n_len)]for i in range(self.batch_size):random_str = ''.join([random.choice(self.characters) for j in range(self.n_len)])X[i] = np.array(self.generator.generate_image(random_str)) / 255.0for j, ch in enumerate(random_str):y[j][i, :] = 0y[j][i, self.characters.find(ch)] = 1return X, y

测试代码:

def decode(y):y = np.argmax(np.array(y), axis=2)[:,0]return ''.join([characters[x] for x in y])
#注意每次运行输出结果可能不同,因为我们每次随机选择一个字符
data = CaptchaSequence(characters, batch_size=1, steps=1)  
X, y = data[0]
plt.imshow(X[0])
plt.title(decode(y))

结果如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8lx2zPpf-1693272688115)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20230828214749531.png)]

注意:生成的验证码中字可能会出现不清晰的情况

例如这样:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-w3VvkFwm-1693272688116)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20230828191026978.png)]

总结原因可能有以下几点:

  1. 图片尺寸过小:在代码中,如果设置了验证码图片的宽度和高度为64和32,这可能导致生成的验证码图片较小,从而导致字体较小且不清晰。可以尝试增大图片尺寸,例如将宽度设置为128,高度设置为64。
  2. 图片缩放导致失真:在生成图片时,使用了np.array(self.generator.generate_image(random_str)) / 255.0 将图像转换为numpy数组并进行了归一化处理。如果在这个过程中对图像进行了缩放操作,可能会导致图像失真,从而影响字体的清晰度。可以尝试去除归一化处理,或者调整归一化的方式,确保图像不失真。
  3. 字体类型和大小:验证码生成器ImageCaptcha使用默认的字体类型和大小生成验证码。如果默认字体类型和大小不适合生成清晰的验证码,可以尝试更换字体类型并调整字体大小。可以参考ImageCaptcha的文档,了解如何更改字体类型和大小。
  4. 图像参数调整:除了上述因素外,还可以尝试调整一些图像生成的参数,例如干扰线的宽度、噪点的数量等,以提高验证码的清晰度。

五、定义网络结构

train_data = CaptchaSequence(characters, batch_size=512, steps=1000)
valid_data = CaptchaSequence(characters, batch_size=128, steps=100)
x_train, y_train = train_data[0]
x_val, y_val = valid_data[0]
from tensorflow.keras.models import *
from tensorflow.keras.layers import *input_tensor = Input((height, width, 3))
x = input_tensor
for num_cnn,num_kernel in enumerate([32,16,8]):for j in range(num_cnn):x = Conv2D(num_kernel, kernel_size=(3,3), padding='same', kernel_initializer='he_uniform')(x)x = Conv2D(num_kernel, kernel_size=(3,3), padding='same')(x)x = BatchNormalization()(x)x = Activation('relu')(x)x = MaxPooling2D(pool_size=(2,2))(x)x = Flatten()(x)
x = [Dense(n_class, activation='softmax',name='c%d'%(i+1))(x) for i in range(n_len)]
model = Model(inputs=input_tensor, outputs=x)
model.summary()

网络结构总结如下:

Model: "model"
__________________________________________________________________________________________________
Layer (type)                    Output Shape         Param #     Connected to                     
==================================================================================================
input_1 (InputLayer)            [(None, 64, 128, 3)] 0                                            
__________________________________________________________________________________________________
conv2d (Conv2D)                 (None, 64, 128, 16)  448         input_1[0][0]                    
__________________________________________________________________________________________________
conv2d_1 (Conv2D)               (None, 64, 128, 16)  2320        conv2d[0][0]                     
__________________________________________________________________________________________________
batch_normalization (BatchNorma (None, 64, 128, 16)  64          conv2d_1[0][0]                   
__________________________________________________________________________________________________
activation (Activation)         (None, 64, 128, 16)  0           batch_normalization[0][0]        
__________________________________________________________________________________________________
max_pooling2d (MaxPooling2D)    (None, 32, 64, 16)   0           activation[0][0]                 
__________________________________________________________________________________________________
conv2d_2 (Conv2D)               (None, 32, 64, 8)    1160        max_pooling2d[0][0]              
__________________________________________________________________________________________________
conv2d_3 (Conv2D)               (None, 32, 64, 8)    584         conv2d_2[0][0]                   
__________________________________________________________________________________________________
batch_normalization_1 (BatchNor (None, 32, 64, 8)    32          conv2d_3[0][0]                   
__________________________________________________________________________________________________
activation_1 (Activation)       (None, 32, 64, 8)    0           batch_normalization_1[0][0]      
__________________________________________________________________________________________________
max_pooling2d_1 (MaxPooling2D)  (None, 16, 32, 8)    0           activation_1[0][0]               
__________________________________________________________________________________________________
conv2d_4 (Conv2D)               (None, 16, 32, 8)    584         max_pooling2d_1[0][0]            
__________________________________________________________________________________________________
conv2d_5 (Conv2D)               (None, 16, 32, 8)    584         conv2d_4[0][0]                   
__________________________________________________________________________________________________
batch_normalization_2 (BatchNor (None, 16, 32, 8)    32          conv2d_5[0][0]                   
__________________________________________________________________________________________________
activation_2 (Activation)       (None, 16, 32, 8)    0           batch_normalization_2[0][0]      
__________________________________________________________________________________________________
max_pooling2d_2 (MaxPooling2D)  (None, 8, 16, 8)     0           activation_2[0][0]               
__________________________________________________________________________________________________
flatten (Flatten)               (None, 1024)         0           max_pooling2d_2[0][0]            
__________________________________________________________________________________________________
c1 (Dense)                      (None, 36)           36900       flatten[0][0]                    
__________________________________________________________________________________________________
c2 (Dense)                      (None, 36)           36900       flatten[0][0]                    
__________________________________________________________________________________________________
c3 (Dense)                      (None, 36)           36900       flatten[0][0]                    
__________________________________________________________________________________________________
c4 (Dense)                      (None, 36)           36900       flatten[0][0]                    
==================================================================================================
Total params: 153,408
Trainable params: 153,344
Non-trainable params: 64

六、训练模型

开始训练

from tensorflow.keras.callbacks import EarlyStopping, ModelCheckpoint
from tensorflow.keras.optimizers import Adamcallbacks = [EarlyStopping(patience=3), ModelCheckpoint('cnn_best.h5', save_best_only=True)]model.compile(loss='categorical_crossentropy',optimizer=Adam(1e-3), metrics=['accuracy'])
history = model.fit(x_train, y_train, epochs=100, validation_data=(x_val,y_val),callbacks=callbacks, verbose=1)

载入最好的模型继续训练一会

model.load_weights('cnn_best.h5')callbacks = [EarlyStopping(patience=3),ModelCheckpoint('cnn_best.h5', save_best_only=True)]
#学习率降低,
model.compile(loss='categorical_crossentropy',optimizer=Adam(1e-4), metrics=['accuracy'])
model.fit(x_train, y_train, epochs=100, validation_data=(x_val,y_val),callbacks=callbacks, verbose=1)

保存最好的模型

model.save('../cnn_best.h5')

七、测试模型

X, y = data[0]
y_pred = model.predict(X)
plt.title('real: %s pred:%s'%(decode(y), decode(y_pred)))
plt.imshow(X[0], cmap='gray')
plt.axis('off')

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Q0NnLMwd-1693272688117)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20230828215633050.png)]

可见测试模型效果并不理想,因为我们的训练迭代次数少,网络结构简单,不过我们可以增加网络层数,调节网络参数然后重新训练一个更好的模型。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/110388.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【JSDocvscode】使用JSDoc、在vscode中开启node调试、使用vscode编写运行Python程序

JSDoc JSDoc是JavaScript的一种注释语法,同时通过JSDoc注释也可以规避js弱类型中不进行代码提示的问题 图形展示JSDoc的效果: 上述没有进行JSDoc,然后我们a点什么 是没有任何提示的 上述就是加上 JSDoc的效果 常用的 vscode 其实内置了 js…

SpringBoot整合JUnit、MyBatis、SSM

🐌个人主页: 🐌 叶落闲庭 💨我的专栏:💨 c语言 数据结构 javaEE 操作系统 石可破也,而不可夺坚;丹可磨也,而不可夺赤。 SpringBoot整合 一、SpringBoot整合JUnit二、Spri…

Android获取手机已安装应用列表JAVA实现

最终效果: 设计 实现java代码: //获取包列表private List<String> getPkgList() {List<String> packages new ArrayList<String>();try {//使用命令行方式获取包列表Process p Runtime.getRuntime().exec("pm list packages");//取得命令行输出…

11.2.1-通货膨胀CPI

文章目录 1. 什么是CPI2. 在哪里获取CPI数据3. CPI的同比、环比到底是什么意思&#xff1f;4. 计算购买力侵蚀5. 复利计算 微不足道的小事也会引发惊人的结果&#xff0c; 每念及此&#xff0c; 我就认为世上无小事。——布鲁斯巴登&#xff08;Bruce Barton&#xff09; 核心内…

大数据Flink实时计算技术

1、架构 2、应用场景 Flink 功能强大&#xff0c;支持开发和运行多种不同种类的应用程序。它的主要特性包括&#xff1a;批流一体化、精密的状态管理、事件时间支持以及精确一次的状态一致性保障等。在启用高可用选项的情况下&#xff0c;它不存在单点失效问题。事实证明&#…

Scrum敏捷研发迭代式开发

Scrum是一个迭代式增量软件开发过程&#xff0c;是敏捷方法论中的重要框架之一。它通常用于敏捷软件开发&#xff0c;包括了一系列实践和预定义角色的过程骨架。Scrum中的主要角色包括Scrum主管&#xff08;Scrum Master&#xff09;、产品负责人&#xff08;Product Owner&…

Dockerfile文件详细

Dockerfile 是一个文本文件&#xff0c;里面包含组装新镜像时用到的基础镜像和各种指令&#xff0c;使用dockerfile 文件来定义镜像&#xff0c;然后运行镜像&#xff0c;启动容器。 构建镜像步骤 ① 编写一个 dockerfile 文件 ② 使用 ​​​docker build​​​构建镜像 ③ …

引领未来商业:循环购模式的创新突破-微三云门门

尊敬的创业者们&#xff0c;我是微三云门门。今天&#xff0c;我将与您深入探讨一种崭新的商业模式——循环购模式。该模式在私域流量领域取得了巨大成功&#xff0c;仅用6个月时间就创造了超过400万的用户数量&#xff01; 循环购商业模式的核心概念涵盖三个关键要素&#xf…

C语言(第三十一天)

6. 调试举例1 求1!2!3!4!...10!的和&#xff0c;请看下面的代码&#xff1a; #include <stdio.h> //写一个代码求n的阶乘 int main() {int n 0;scanf("%d", &n);int i 1;int ret 1;for(i1; i<n; i){ret * i;}printf("%d\n", ret);return …

C语言的发展及特点

1. C语言的发展历程 C语言作为计算机编程领域的重要里程碑&#xff0c;其发展历程承载着无数开发者的智慧和创新。C语言诞生于20世纪70年代初&#xff0c;由计算机科学家Dennis Ritchie在贝尔实验室首次推出。当时&#xff0c;Ritchie的目标是为Unix操作系统开发一门能够更方便…

WPF读取dicom序列:实现上一帧、下一帧、自动播放、暂停

一、整体设计概况 创建WPF程序使用.Net Framework4.8定义Image控件展示图像增加标签展示dcm文件信息规划按钮触发对应的事件:上一帧、下一帧、自动播放、暂停、缩放、播放速率二、页面展示 三、代码逻辑分析 Windows窗体加载Loaded事件:生成初始图像信息Windows窗体加载Mous…

如何清空小程序会员卡的电子票

​电子票不仅方便了用户的购票和消费&#xff0c;还提升了用户的购物体验和忠诚度。然而&#xff0c;在一些特殊情况下&#xff0c;可能需要手动清空会员的电子票。那么&#xff0c;下面我们就来探讨一下在小程序中如何手动清空会员的电子票。 1. 找到指定的会员卡。在管理员后…

构建个人博客_Obsidian_github.io_hexo

1 初衷 很早就开始分享文档&#xff0c;以技术类的为主&#xff0c;一开始是 MSN&#xff0c;博客&#xff0c;随着平台的更替&#xff0c;后来又用了 CSDN&#xff0c;知乎&#xff0c;简书…… 再后来是 Obsidian&#xff0c;飞书&#xff0c;Notion&#xff0c;常常有以下困…

uniapp 开发小程序,封装一个方法,让图片使用线上地址

1.在main.js文件中&#xff0c;添加以下代码&#xff1a; 复制使用&#xff1a; // 图片使用网络地址 Vue.prototype.localImgSrc function(img){//项目的地址域名&#xff0c;例如百度return "https://baidu.cn/static/index/images/" img; }2.在页面中直接使用&…

Python怎么解决性能问题?

Python的性能问题可以通过以下一些方法来解决或改善&#xff1a; 使用更高效的算法和数据结构&#xff1a; 选择适当的数据结构和算法可以显著提升代码的性能。了解不同算法的时间复杂度和空间复杂度&#xff0c;选择最适合问题的解决方案。 优化代码逻辑&#xff1a; 仔细审查…

Zenity 简介

什么使 Zenity Zenity 是一个开源的命令行工具&#xff0c;它提供了一种简单的方式来创建图形化的用户界面&#xff08;GUI&#xff09;对话框&#xff0c;以与用户进行交互。它基于 GTK 库&#xff0c;可以在 Linux 和其他 UNIX-like 系统上使用。 Zenity 可以通过命令行或脚…

服务器数据恢复-服务器RAID6硬盘故障离线的数据恢复案例

服务器数据恢复环境&#xff1a; 服务器中有一组由6块磁盘组建的RAID6磁盘阵列。服务器作为WEB服务器使用&#xff0c;上面运行了MYSQL数据库以及存放了网站代码和其他数据文件。 服务器故障&#xff1a; 在服务器运行过程中该raid6阵列中有两块磁盘先后离线&#xff0c;但是管…

【高等数学基础知识篇】——导数与微分

本文仅用于个人学习记录&#xff0c;使用的教材为汤家凤老师的《高等数学辅导讲义》。本文无任何盈利或者赚取个人声望的目的&#xff0c;如有侵权&#xff0c;请联系删除&#xff01; 文章目录 一、导数与微分的基本概念1.1 导数的基本概念1.2 微分的基本概念1.3 连续、可导、…

【腾讯云 TDSQL-C Serverless 产品测评】- 云原生时代的TDSQL-C MySQL数据库技术实践

一、活动介绍&#xff1a; “腾讯云 TDSQL-C 产品测评活动”是由腾讯云联合 CSDN 推出的针对数据库产品测评及产品体验活动&#xff0c;本次活动主要面向 TDSQL-C Serverless版本&#xff0c;初步的产品体验或针对TDSQL-C产品的自动弹性能力、自动启停能力、兼容性、安全、并发…

经典卷积网络

目录 一、经典神经网络出现的时间线​编辑 二、LeNet 三、AlexNet 四、VGGNet 五、InceptionNet 六、ResNet 总结&#xff1a; 一、经典神经网络出现的时间线 二、LeNet 背景&#xff1a;LeNet由Yann LeCun于1998年提出&#xff0c;卷积网络开篇之作。 解释&#xff1…