当前位置: 首页 > news >正文

利用深度学习实现验证码识别-4-ResNet18+imagecaptcha

在当今的数字化世界中,验证码(CAPTCHA)是保护网站免受自动化攻击的重要工具。然而,对于用户来说,验证码有时可能会成为一种烦恼。为了解决这个问题,我们可以利用深度学习技术来自动识别验证码,从而提高用户体验。本文将介绍如何使用ResNet18模型来识别ImageCaptcha生成的验证码。
在这里插入图片描述

1. 环境设置与数据准备

首先,我们需要检查CUDA是否可用,以便利用GPU加速训练过程。

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
print(f'Using device: {device}')

接下来,我们定义一个数据生成器CaptchaDataset,它使用imagecaptcha库生成验证码图像。

class CaptchaDataset(Dataset):def __init__(self, length=1000, charset=None, captcha_length=5, transform=None):self.length = lengthself.transform = transformself.charset = charset if charset is not None else string.ascii_letters + string.digitsself.captcha_length = captcha_lengthself.num_classes = len(self.charset)self.image_generator = ImageCaptcha(width=160, height=60)def __len__(self):return self.lengthdef __getitem__(self, idx):text = ''.join(random.choices(self.charset, k=self.captcha_length))image = self.image_generator.generate_image(text)if self.transform:image = self.transform(image)label = [self.charset.index(c) for c in text]return image, torch.tensor(label, dtype=torch.long)
2. 数据增强与预处理

为了提高模型的泛化能力,我们使用了一系列的数据增强和预处理步骤。

transform = transforms.Compose([transforms.Grayscale(),  # 将图像转换为灰度transforms.Resize((40, 100)),transforms.ToTensor(),transforms.Normalize((0.5,), (0.5,))
])
3. 数据集划分与加载

我们将数据集划分为训练集和验证集,并使用DataLoader进行批量加载。

dataset = CaptchaDataset(length=2000, charset=charset, captcha_length=captcha_length, transform=transform)
train_size = int(0.8 * len(dataset))
val_size = len(dataset) - train_size
train_dataset, val_dataset = random_split(dataset, [train_size, val_size])train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True)
val_loader = DataLoader(val_dataset, batch_size=64, shuffle=False)
4. 模型定义与迁移学习

我们使用预训练的ResNet18模型,并对其进行微调以适应验证码识别任务。

class CaptchaModel(nn.Module):def __init__(self, num_classes, captcha_length):super(CaptchaModel, self).__init__()self.captcha_length = captcha_lengthself.resnet = models.resnet18(weights=models.ResNet18_Weights.DEFAULT)self.resnet.conv1 = nn.Conv2d(1, 64, kernel_size=7, stride=2, padding=3, bias=False)num_ftrs = self.resnet.fc.in_featuresself.resnet.fc = nn.Linear(num_ftrs, num_classes * self.captcha_length)def forward(self, x):x = self.resnet(x)return x.view(-1, self.captcha_length, num_classes)
5. 训练与评估

我们定义了训练函数train_model,并在每个epoch结束时保存模型检查点。

def train_model(epochs, resume=False):start_epoch = 0if resume and os.path.isfile("captcha_model_checkpoint.pth.tar"):checkpoint = load_checkpoint()model.load_state_dict(checkpoint['state_dict'])optimizer.load_state_dict(checkpoint['optimizer'])start_epoch = checkpoint['epoch']scaler = torch.cuda.amp.GradScaler()for epoch in range(start_epoch, epochs):model.train()running_loss = 0.0for images, labels in train_loader:images, labels = images.to(device), labels.to(device)optimizer.zero_grad()with torch.cuda.amp.autocast():outputs = model(images)loss = sum(criterion(outputs[:, i, :], labels[:, i]) for i in range(captcha_length))scaler.scale(loss).backward()scaler.step(optimizer)scaler.update()running_loss += loss.item()val_accuracy = evaluate_accuracy(val_loader)print(f'Epoch [{epoch+1}/{epochs}], Loss: {running_loss / len(train_loader):.4f}, Val Accuracy: {val_accuracy:.4f}')save_checkpoint({'epoch': epoch + 1,'state_dict': model.state_dict(),'optimizer': optimizer.state_dict(),})
6. 可视化预测结果

最后,我们定义了一个函数visualize_predictions来可视化模型的预测结果。

def visualize_predictions(num_samples=16):model.eval()samples, labels = next(iter(DataLoader(val_dataset, batch_size=num_samples, shuffle=True)))samples, labels = samples.to(device), labels.to(device)with torch.no_grad():outputs = model(samples)predicted = torch.argmax(outputs, dim=2)samples = samples.cpu()predicted = predicted.cpu()labels = labels.cpu()fig, axes = plt.subplots(4, 4, figsize=(10, 10))for i in range(16):ax = axes[i // 4, i % 4]ax.imshow(samples[i].squeeze(), cmap='gray')true_text = ''.join([dataset.charset[l] for l in labels[i]])pred_text = ''.join([dataset.charset[p] for p in predicted[i]])ax.set_title(f'True: {true_text}\nPred: {pred_text}')ax.axis('off')plt.show()
7. 训练与可视化

最后,我们调用train_model函数进行模型训练,并使用visualize_predictions函数来可视化模型的预测结果。

train_model(epochs=180, resume=True)
visualize_predictions()

通过上述步骤,我们成功地使用ResNet18模型来识别ImageCaptcha生成的验证码。这种方法不仅提高了验证码识别的准确性,还提升了用户体验。希望本文能为您在验证码识别领域的研究和应用提供有价值的参考。在这里插入图片描述

相关文章:

利用深度学习实现验证码识别-4-ResNet18+imagecaptcha

在当今的数字化世界中,验证码(CAPTCHA)是保护网站免受自动化攻击的重要工具。然而,对于用户来说,验证码有时可能会成为一种烦恼。为了解决这个问题,我们可以利用深度学习技术来自动识别验证码,从…...

IDC基础学习笔记

一、数据中心介绍 1、数据中心级别划分: 2、数据中心结构: 3、IT系统组成 二、数据中心硬件知识 1、服务器组件 服务器的正面接口: 服务器的反面接口: (1)CPU CPU定义:中央处理器&#xff08…...

Mysql基础练习题 1527.患某种疾病的患者 (力扣)

查询患有 I 类糖尿病的患者 ID (patient_id)、患者姓名(patient_name)以及其患有的所有疾病代码(conditions)。I 类糖尿病的代码总是包含前缀 DIAB1 。 题目链接: https://leetcode.cn/proble…...

Mysql链接异常 | [08001] Public Key Retrieval is not allowed

Datagrid报错 [08001] Public Key Retrieval is not allowed 这个错误通常是由于 MySQL 8.0 中的新特性导致的。默认情况下,MySQL 8.0 使用 caching_sha2_password 作为认证插件,而你需要在连接 URL 中明确允许公钥检索或者使用老版本的认证方式 mysql…...

vue3项目中如何动态循环设置ref并获取使用

前言:vue2可通过ref来获取当前的dom,但是vue3有个问题,就是必须定义ref的变量名,才能使用;倘若有多个ref,一个个去定义未免过于繁琐,还有一种情况就是dom是使用v-for循环出来的,那么…...

stm32之SPI通信协议

文章目录 前言一、SPI通信协议1.1 SPI简介1.2 SPI通信特点1.3 SPI与I2C对比 二、SPI硬件电路三、SPI通信原理四、SPI时序单元4.1 起始和终止条件4.2 交换一个字节(模式1)4.3 交换一个字节(模式0)4.4 交换一个字节(模式2和3) 五、SPI时序5.1 发送指令5.2 指定地址写5.3 指定地址…...

Unity 摄像机(Camera)详解

文章目录 0.前言1.相机属性介绍2.Unity 中多个相机画面堆叠显示2.1 3D 摄像机2.2 UI 摄像机2.3 摄像机的Culling Mask设置 0.前言 本文介绍的是使用Unity默认的内置渲染管线下的Camera组件,使用URP或HDRP则不同。 1.相机属性介绍 Clear Flags: 清除标记…...

数学基础 -- 线性代数之LU分解

LU分解 LU分解(LU Decomposition)是线性代数中非常重要的一种矩阵分解方法。它将一个方阵分解为一个下三角矩阵(L矩阵)和一个上三角矩阵(U矩阵)的乘积。在数值线性代数中,LU分解广泛用于求解线…...

高职人工智能训练师边缘计算实训室解决方案

一、引言 随着物联网(IoT)、大数据、人工智能(AI)等技术的飞速发展,计算需求日益复杂和多样化。传统的云计算模式虽在一定程度上满足了这些需求,但在处理海量数据、保障实时性与安全性、提升计算效率等方面…...

【Java】SpringCloud中使用set方法报错空指针

前言:今天在交流群中看见了一个空指针报错,想着哪里为空点过去看看为什么赋不上值就行,没想到啪啪打脸了,今天总结一下。 以下是他的RedisTempate注入和方法 可以看到,89行报错空指针。先分析一下, ①赋值…...

芯片杂谈 -- 常聊的内核包含哪些模块

目录 1. R52内核速览 2. 处理器模块详解 3.内核的功能安全测什么? 4.小结 最开始接触到汽车MCU大都来自NXP、Infineon、Renesas,例如MPC5748、TC275、RH850 P1X等等; 而各大OEM、供应商等等发布的JD通常都会要求熟悉AURIX、PowerPC、G3K…...

运维问题0002:SAP多模块问题-SAP系统程序在执行时,跳出“加急快件”窗口,提示:快件文档“更新已终止”从作者***收到

1、问题描述 近期收到2起业务报障,均反馈在SAP执行程序时,弹出“加急快件”窗口,导致操作的业务实际没有更新完成。 1)业务场景一:设备管理部门在操作事务代码:AS02进行资产信息变更时,保存正常…...

深度解析RAG:你必须要了解的RAG优化方法

RAG(Retrieval-Augmented Generation)是一种结合检索和生成能力的技术框架,旨在通过从外部知识库中检索相关信息来增强生成模型的输出。其基本思想是利用大型语言模型(LLM)的生成能力,同时通过检索机制获取…...

深度学习驱动下的字符识别:挑战与创新

一、引言 1.1 研究背景 深度学习在字符识别领域具有至关重要的地位。随着信息技术的飞速发展,对字符识别的准确性和效率要求越来越高。字符识别作为计算机视觉领域的一个重要研究方向,其主要目的是将各种形式的字符转换成计算机可识别的文本信息。近年…...

使用 JAXB 将内嵌的JAVA对象转换为 xml文件

使用 JAXB 将内嵌的JAVA对象转换为 xml文件 1. 需求2. 实现(1)FileDesc类(2)MetaFileXml类(3)生成对应的xml文件 1. 需求 获取一个目录下所有文件的元数据信息(文件名、大小、后缀等&#xff0…...

若依项目后台启动报错: [网关异常处理]、503

拉取代码启动项目,网关控制台报错: 21:31:59.981 [boundedElastic-7] WARN o.s.c.l.c.RoundRobinLoadBalancer - [getInstanceResponse,98] - No servers available for service: ruoyi-system 21:31:59.981 [boundedElastic-7] ERROR c.r.g.h.Gateway…...

【C++ Qt day10】

2、 完善对话框,点击登录对话框,如果账号和密码匹配,则弹出信息对话框,给出提示”登录成功“,提供一个Ok按钮,用户点击Ok后,关闭登录界面,跳转到其他界面 如果账号和密码不匹配&am…...

GO HTTP库使用

Go的 net/http 包是一个强大且易于使用的库,用于构建HTTP服务器和客户端。通过它,你可以轻松实现HTTP请求的处理、路由、静态文件服务等功能。下面重点以及一个简单的Demo示例。 文章目录 1. **基础HTTP服务器**2. **处理请求与响应**3. **路由与处理器*…...

数据结构 - 顺序表

0.线性表 1.定义 线性表就是零个或多个相同数据元素的有限序列。 2.线性表的存储结构 ①.顺序结构 ②.链式结构 3.线性表的表示方法 例如: 一.线性表的基本运算 二.线性表的复杂运算 1.线性表的合并运算 2.线性表的去重运算 三.顺序表 1.定义 顺序表,就…...

企业如何组建安全稳定的跨国通信网络?

组建一个安全稳定的跨国通信网络对于现代企业来说至关重要,尤其是当企业在全球范围内运营时。以下是一些关键步骤和考虑因素: 需求分析: 确定企业的具体通信需求,包括带宽要求、延迟敏感度、数据类型(如语音、视频、文…...

TDengine 快速体验(Docker 镜像方式)

简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能,本节首先介绍如何通过 Docker 快速体验 TDengine,然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker,请使用 安装包的方式快…...

关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案

问题描述:iview使用table 中type: "index",分页之后 ,索引还是从1开始,试过绑定后台返回数据的id, 这种方法可行,就是后台返回数据的每个页面id都不完全是按照从1开始的升序,因此百度了下,找到了…...

STM32标准库-DMA直接存储器存取

文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA(Direct Memory Access)直接存储器存取 DMA可以提供外设…...

如何将联系人从 iPhone 转移到 Android

从 iPhone 换到 Android 手机时,你可能需要保留重要的数据,例如通讯录。好在,将通讯录从 iPhone 转移到 Android 手机非常简单,你可以从本文中学习 6 种可靠的方法,确保随时保持连接,不错过任何信息。 第 1…...

C++ 基础特性深度解析

目录 引言 一、命名空间(namespace) C 中的命名空间​ 与 C 语言的对比​ 二、缺省参数​ C 中的缺省参数​ 与 C 语言的对比​ 三、引用(reference)​ C 中的引用​ 与 C 语言的对比​ 四、inline(内联函数…...

NLP学习路线图(二十三):长短期记忆网络(LSTM)

在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...

Android15默认授权浮窗权限

我们经常有那种需求,客户需要定制的apk集成在ROM中,并且默认授予其【显示在其他应用的上层】权限,也就是我们常说的浮窗权限,那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...

MySQL用户和授权

开放MySQL白名单 可以通过iptables-save命令确认对应客户端ip是否可以访问MySQL服务: test: # iptables-save | grep 3306 -A mp_srv_whitelist -s 172.16.14.102/32 -p tcp -m tcp --dport 3306 -j ACCEPT -A mp_srv_whitelist -s 172.16.4.16/32 -p tcp -m tcp -…...

ABAP设计模式之---“简单设计原则(Simple Design)”

“Simple Design”(简单设计)是软件开发中的一个重要理念,倡导以最简单的方式实现软件功能,以确保代码清晰易懂、易维护,并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计,遵循“让事情保…...

iOS性能调优实战:借助克魔(KeyMob)与常用工具深度洞察App瓶颈

在日常iOS开发过程中,性能问题往往是最令人头疼的一类Bug。尤其是在App上线前的压测阶段或是处理用户反馈的高发期,开发者往往需要面对卡顿、崩溃、能耗异常、日志混乱等一系列问题。这些问题表面上看似偶发,但背后往往隐藏着系统资源调度不当…...