PyTorch识别验证码

## 一、生成测试集数据

pip install captcha

common.py

import random
import time
captcha_array = list("0123456789abcdefghijklmnopqrstuvwxyz")
captcha_size = 4from captcha.image import ImageCaptchaif __name__ == '__main__':for i in range(10):image = ImageCaptcha()image_text = "".join(random.sample(captcha_array, captcha_size))image_path = "./datasets/train/{}_{}.png".format(image_text, int(time.time()))image.write(image_text, image_path)

生成验证码
在这里插入图片描述

二、one-hot编码将类别变量转换为机器学习算法易于利用的一种形式的过程。

one_hot.py

import common
import torch
import torch.nn.functional as Fdef text2vec(text):# 将文本转换为变量vectors = torch.zeros((common.captcha_size, common.captcha_array.__len__()))# vectors[0,0] = 1# vectors[1,3] = 1# vectors[2,4] = 1# vectors[3, 1] = 1for i in range(len(text)):vectors[i, common.captcha_array.index(text[i])] = 1return vectorsdef vectotext(vec):vec=torch.argmax(vec, dim=1)text_label=""for v in vec:text_label+=common.captcha_array[v]return  text_labelif __name__ == '__main__':vec=text2vec("aab1")print(vec, vec.shape)print(vectotext(vec))

在这里插入图片描述

三、 然后继续添加

my_datasets.py

import osfrom PIL import Image
from torch.utils.data import Dataset
from torchvision import transforms
from torch.utils.tensorboard import SummaryWriter
import one_hotclass mydatasets(Dataset):def __init__(self,root_dir):super(mydatasets, self).__init__()self.list_image_path=[ os.path.join(root_dir,image_name) for image_name in os.listdir(root_dir)]self.transforms=transforms.Compose([transforms.Resize((60,160)),transforms.ToTensor(),transforms.Grayscale()])def __getitem__(self, index):image_path = self.list_image_path[index]img_ = Image.open(image_path)image_name=image_path.split("\\")[-1]img_tesor=self.transforms(img_)img_lable=image_name.split("_")[0]img_lable=one_hot.text2vec(img_lable)img_lable=img_lable.view(1,-1)[0]return img_tesor,img_labledef __len__(self):return self.list_image_path.__len__()if __name__ == '__main__':d=mydatasets("datasets/train")img,label=d[0]writer=SummaryWriter("logs")writer.add_image("img",img,1)print(img.shape)writer.close()

dataLoader 加载dataset
就是数据加载器,结合了数据集和取样器,并且可以提供多个线程处理数据集。在训练模型时使用到此函数,用来把训练数据分成多个小组,此函数每次抛出一组数据。直至把所有的数据都抛出,就是做一个数据的初始化。

四、训练

五、CNN卷积神经网络
在这里插入图片描述
model.py

import torch
from torch import nn
import common
class mymodel(nn.Module):def __init__(self):super(mymodel, self).__init__()self.layer1 = nn.Sequential(# 卷积层nn.Conv2d(in_channels=1, out_channels=64, kernel_size=3, padding=1),# 激活层nn.ReLU(),# 池化层nn.MaxPool2d(kernel_size=2)   #[6, 64, 30, 80])self.layer2 = nn.Sequential(# 卷积层nn.Conv2d(in_channels=64, out_channels=128, kernel_size=3, padding=1),# 激活层nn.ReLU(),# 池化层nn.MaxPool2d(2)     #[6, 128, 15, 40])self.layer3 = nn.Sequential(# 卷积层nn.Conv2d(in_channels=128, out_channels=256, kernel_size=3, padding=1),# 激活层nn.ReLU(),# 池化层nn.MaxPool2d(2)  # [6, 256, 7, 20])self.layer4 = nn.Sequential(# 卷积层nn.Conv2d(in_channels=256, out_channels=512, kernel_size=3, padding=1),# 激活层nn.ReLU(),# 池化层nn.MaxPool2d(2)  # [6, 512, 3, 10])# self.layer5 = nn.Sequential(#     nn.Conv2d(in_channels=512, out_channels=512, kernel_size=3, padding=1),#     nn.ReLU(),#     nn.MaxPool2d(2)  # [6, 512, 1, 5]# )self.layer6 = nn.Sequential(# 展平nn.Flatten(),    #[6, 2560] [64, 15360]# 线性层nn.Linear(in_features=15360, out_features=4096),# 防止过拟合nn.Dropout(0.2),  # drop 20% of the neuron# 激活曾nn.ReLU(),# 线性层nn.Linear(in_features=4096, out_features=common.captcha_size*common.captcha_array.__len__()))def forward(self,x):x = self.layer1(x)x = self.layer2(x)x = self.layer3(x)x = self.layer4(x)#x = x.view(1,-1)[0]#[983040]x = self.layer6(x)# x = x.view(x.size(0), -1)return x;if __name__ == '__main__':data = torch.ones(64, 1, 60, 160)model = mymodel()x = model(data)print(x.shape)

在这里插入图片描述

六、训练

train.py

import torch
from torch import nn
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
from my_datasets import mydatasets
from model import mymodelif __name__ == '__main__':train_datas = mydatasets("datasets/train")test_data = mydatasets("datasets/test")train_dataloader = DataLoader(train_datas, batch_size=64, shuffle=True)test_dataloader = DataLoader(test_data, batch_size=64, shuffle=True)# m = mymodel().cuda()    没有GPUm = mymodel()# MultiLabelSoftMarginLoss 多标签交叉熵损失函数# 优化器 Adam 一般要求学习率比较小# 先将梯度归零 zero_grad# 反向传播计算 backward# loss_fn = nn.MultiLabelSoftMarginLoss().cuda()   没有GPUloss_fn = nn.MultiLabelSoftMarginLoss()optimizer = torch.optim.Adam(m.parameters(), lr=0.001)w = SummaryWriter("logs")total_step = 0for i in range(10):# print("外层训练次数{}".format(i))for i,(imgs, targets) in enumerate(train_dataloader):# imgs = imgs.cuda()   没有GPU# targets = targets.cuda()   没有GPUoutputs = m(imgs)loss = loss_fn(outputs, targets)optimizer.zero_grad()loss.backward()optimizer.step()if i%10 == 0:total_step += 1print("训练{}次,loss:{}".format(total_step*10, loss.item()))w.add_scalar("loss", loss, total_step)w.close()torch.save(m, "model.pth")

在这里插入图片描述
tensorboard --logdir=logs
使用tensorboard 查看损失率,接近零了。
在这里插入图片描述

七、图片预测

model.train() 和 model.eval()一般在模型训练和评价的时候会加上这两句,主要是针对由于model在训练时和评价时Batch Normalization 和Dropout方法模式不同,例如model指定t因此,在使用PyTorch进行训练和测试时一定注意要把rain/eval
predict.py

from PIL import Image
from torch.utils.data import DataLoader
import one_hot
import model
import torch
import common
import my_datasets
from torchvision import transformsdef test_pred():#  m = torch.load("model.pth").cuda()  没有GPUm = torch.load("model.pth")m.eval()test_data = my_datasets.mydatasets("datasets/test")test_dataloader = DataLoader(test_data, batch_size=1, shuffle=False)test_length = test_data.__len__()correct = 0for i, (imgs, lables) in enumerate(test_dataloader):# imgs = imgs.cuda()   没有GPU# lables = lables.cuda()  没有GPUlables = lables.view(-1, common.captcha_array.__len__())lables_text = one_hot.vectotext(lables)predict_outputs = m(imgs)predict_outputs = predict_outputs.view(-1, common.captcha_array.__len__())predict_labels = one_hot.vectotext(predict_outputs)if predict_labels == lables_text:correct += 1print("预测正确:正确值:{},预测值:{}".format(lables_text, predict_labels))else:print("预测失败:正确值:{},预测值:{}".format(lables_text, predict_labels))# m(imgs)print("正确率{}".format(correct / test_length * 100))def pred_pic(pic_path):img = Image.open(pic_path)tersor_img = transforms.Compose([transforms.Grayscale(),transforms.Resize((60, 160)),transforms.ToTensor()])# img = tersor_img(img).cuda() 没有GPUimg = tersor_img(img)print(img.shape)img = torch.reshape(img, (-1, 1, 60, 160))print(img.shape)# m = torch.load("model.pth").cuda() 没有GPUm = torch.load("model.pth")outputs = m(img)outputs = outputs.view(-1, len(common.captcha_array))outputs_lable = one_hot.vectotext(outputs)print(outputs_lable)if __name__ == '__main__':# test_pred()pred_pic("./datasets/test/5ogl_1705418909.png")

在这里插入图片描述
预测值是一样的,需要找一些真实的验证码图片
在这里插入图片描述

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

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

相关文章

2024美赛数学建模C题思路源码

比赛当天第一时间更新! 赛题目的 赛题目的: 问题描述: 解题的关键: 问题一. 问题分析 问题解答 问题二. 问题分析 问题解答 问题三. 问题分析 问题解答 问题四. 问题分析 问题解答 问题五. 问题分析 问题解答

this.$store undefined

报错:vuex报错 this.$store显示undefined,可能存在的问题,从以下几个方向排查 1、查看store文件中的vuex实例对象是否暴漏 2、main.js中是否注入store 3、如果上边均没问题,打开package.json,查看vue与vuex的版本&am…

RT-Thread: STM32F103的DAC 操作、DAC驱动

说明:文档记录基于RT-Thread的STM32F103外设DAC操作。 1.DAC的GPIO配置 函数位于 drivers\stm32f1xx_hal_msp.c //DAC底层驱动,时钟配置,引脚 配置 //此函数会被HAL_DAC_Init()调用 //hdac:DAC句柄 void HAL_DAC_MspInit(DAC_HandleTypeDe…

el-upload子组件上传多张图片(上传为files或base64url)

场景: 在表单页,有图片需要上传,表单的操作行按钮中有上传按钮,点击上传按钮。 弹出el-dialog进行图片的上传,可以上传多张图片。 由于多个表单页都有上传多张图片的操作,因此将上传多图的el-upload定义…

Web中的转发与重定向

转发与重定向 一、转发和重定向的概念1.转发2.重定向 二、JavaWeb 中的转发和重定向三、SpringMVC 中的转发和重定向1.转发(1) 默认的方式(2) 完整的方式 2.重定向 四、总结 一、转发和重定向的概念 在 Web 应用中,转发和重定向都是用于将请求从一个页面传递到另一…

09-信息收集-APP及其他资产等

信息收集-APP及其他资产等 信息收集-APP及其他资产等一、APP提取季抓包及后续配合1、某APK一键提取反编译2、利用bp抓取更多URL 二、某IP无web框架下的第三方测试1、各种端口一顿乱扫 —— 思路2、各种接口一顿乱扫 —— 思路3、接口部分一顿测试 —— 思路 三、**案例演示**1、…

【Redis笔记】缓存——缓存分类、更新策略、缓存穿透、缓存雪崩、缓存击穿

缓存 缓存(Cache),就是数据交换的缓冲区,俗称的缓存就是缓冲区内的数据,一般从数据库中获取,存储于高速存储媒介上。 缓存的本质就是用空间换时间,牺牲数据的实时性,以服务器内存中的数据暂时代替从数据库读取最新的数据,减少数据库IO&#…

民事二审案件庭审应如何准备?

一、你要明确审理范围,固定上诉请求 首先,第二审人民法院围绕当事人的上诉请求进行审理。 其次,在第二审程序中,原审原告增加独立的诉讼请求或者原审被告提出反诉的,第二审人民法院可以根据当事人自愿的原则就新增加的…

技术革新与市场需求:探索亚信安慧AntDB的发展之路

在这个信息爆炸的时代,企业对数据处理的需求日益增长,而传统的数据库系统往往难以应对海量数据的存储和处理。亚信安慧AntDB的出现,为解决这一难题提供了有力的工具。它不仅具备高吞吐、高并发、高性能的特点,还拥有极佳的扩展性和…

HTML+JavaScript-05

DOM 什么是 DOM? DOM 是一项 W3C (World Wide Web Consortium) 标准。 DOM 定义了访问文档的标准: “W3C 文档对象模型(DOM)是中立于平台和语言的接口,它允许程序和脚本动态地访问、更新文档的内容、结构和样式。”…

AI绘画探索人工智能的未来

🌈个人主页: Aileen_0v0 🔥热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 ​💫个人格言:“没有罗马,那就自己创造罗马~” #mermaid-svg-8fL64RHWVzwpzR6m {font-family:"trebuchet ms",verdana,arial,sans-serif;font-siz…

SouthLeetCode-打卡24年01月第5周

SouthLeetCode-打卡24年01月第5周 // Date : 2024/01/39 ~ 2024/01/31 031.删除链表的倒数第 N 个结点 (1) 题目描述 031#LeetCode.19.#北岸计划2024/01/29 (2) 题解代码 Version1.0 class Solution {public ListNode removeNthFromEnd(ListNode head, int n) {if(head …

【知识图谱--第一讲概论】

深度学习–连接主义 知识图谱–符号主义 表示 有属性图和RDF图两种 RDF由三元组表示:Subject - Predicate - Object 存储 图数据库 抽取 融合 推理 问答 图算法

Seata下载与配置、启动

目录 Seata下载Seata配置启动Seata Seata下载 首先,我们需要知道我们要使用哪个版本的seata,这就要查看spring-cloud-alibaba版本说明,找到我们对应的seata。 spring-cloud-alibaba版本说明: 地址链接 下面是部分版本说明: s…

【MyBatis】MyBatis是什么?作用?怎么实现?

一、MyBatis是什么 MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain …

【Java】小白友好的JDBC基础学习笔记

目录 JDBC简介 JDBC使用基本步骤 DriverManager Connection Statement PreparedStatement ResultSet JDBC简介 JDBC(Java Database Connectivity)是 Java 提供的一种用于与关系型数据库进行交互的 API(应用程序接口)。它允…

感染了后缀为.pings勒索病毒如何应对?数据能够恢复吗?

导言: 近期,一种名为.pings的勒索病毒悄然出现,给用户的数据安全带来了极大的威胁。该病毒以强力的加密手段对用户文件进行锁定,并勒索赎金。在本文中,91数据恢复将深入介绍.pings勒索病毒的特点,提供被感…

代码随想录二刷——字符串day9

文章目录 前言字符串知识点 一、 28. 找出字符串中第一个匹配项的下标二、459. 重复的子字符串总结 前言 一个本硕双非的小菜鸡,备战24年秋招,计划二刷完卡子哥的刷题计划,加油! 二刷决定精刷了,于是参加了卡子哥的刷…

虚拟机扩容后黑屏卡死解决方法

亲测有效,首先一般是在扩容后黑屏的,现象为开机后看到个横线光标不闪,黑屏,进入不了桌面。原因是硬盘已经满了,所以解决方法就是清理硬盘。所以首先还是要解决登录问题。 开机时按 esc 键进入 GNU GRUB,选择…

详解SpringCloud微服务技术栈:深入ElasticSearch(4)——ES集群

👨‍🎓作者简介:一位大四、研0学生,正在努力准备大四暑假的实习 🌌上期文章:详解SpringCloud微服务技术栈:深入ElasticSearch(3)——数据同步(酒店管理项目&a…