PyTorch识别验证码

news2025/2/4 22:36:26
## 一、生成测试集数据

pip install captcha

common.py

import random
import time
captcha_array = list("0123456789abcdefghijklmnopqrstuvwxyz")
captcha_size = 4

from captcha.image import ImageCaptcha

if __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 F

def 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] = 1

    for i in range(len(text)):
        vectors[i, common.captcha_array.index(text[i])] = 1
    return vectors


def vectotext(vec):

    vec=torch.argmax(vec, dim=1)

    text_label=""
    for v in vec:
        text_label+=common.captcha_array[v]
    return  text_label

if __name__ == '__main__':
    vec=text2vec("aab1")
    print(vec, vec.shape)
    print(vectotext(vec))

在这里插入图片描述

三、 然后继续添加

my_datasets.py

import os

from PIL import Image
from torch.utils.data import Dataset
from torchvision import transforms
from torch.utils.tensorboard import SummaryWriter
import one_hot

class 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_lable
    def __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 mymodel

if __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()    没有GPU
    m = mymodel()
    # MultiLabelSoftMarginLoss 多标签交叉熵损失函数
    # 优化器 Adam 一般要求学习率比较小
    # 先将梯度归零 zero_grad
    # 反向传播计算 backward
    # loss_fn = nn.MultiLabelSoftMarginLoss().cuda()   没有GPU
    loss_fn = nn.MultiLabelSoftMarginLoss()
    optimizer = torch.optim.Adam(m.parameters(), lr=0.001)
    w = SummaryWriter("logs")
    total_step = 0

for i in range(10):
    # print("外层训练次数{}".format(i))
    for i,(imgs, targets) in enumerate(train_dataloader):
        # imgs = imgs.cuda()   没有GPU
        # targets = targets.cuda()   没有GPU
        outputs = m(imgs)
        loss = loss_fn(outputs, targets)
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()

        if i%10 == 0:
            total_step += 1
            print("训练{}次,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 transforms


def test_pred():
    #  m = torch.load("model.pth").cuda()  没有GPU
    m = 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 = 0
    for i, (imgs, lables) in enumerate(test_dataloader):
        # imgs = imgs.cuda()   没有GPU
        # lables = lables.cuda()  没有GPU
        lables = 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 += 1
            print("预测正确:正确值:{},预测值:{}".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() 没有GPU
    img = tersor_img(img)
    print(img.shape)
    img = torch.reshape(img, (-1, 1, 60, 160))
    print(img.shape)
    # m = torch.load("model.pth").cuda() 没有GPU
    m = 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.coloradmin.cn/o/1427134.html

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

相关文章

分布式事务(四)——TCC补偿模式解决方案

系列目录: 《分布式事务(一)—— 事务的基本概念》 《分布式事务(二)—— CAP和Base理论》 《分布式事务(三)—— 两阶段提交解决方案(2PC)》 一、常见分布式事务解决…

某航空网站promise异步定位js逆向解析

本次目标地址如下,使用base64解码获得 aHR0cHM6Ly9pbnQtZXQueGlhbWVuYWlyLmNvbS9mbGlnaHRzL3Jlc3VsdHM 打开网址,抓包分析后,发现响应结果在该请求中: 我们跟栈进去查找,从右边的堆栈调用过程中发现,这是典…

App ICP备案获取iOS和Android的公钥和证书指纹

依照《工业和信息化部关于开展移动互联网应用程序备案工作的通知》,向iOS和安卓平台提交App时需要先提交ICP备案信息。 iOS平台: 1、下载appuploader工具:Appuploader home -- A tool improve ios develop efficiency such as submit ipa to…

Docker 集群配置

1、配置 MySQL MySQL 简单安装 docker安装完MySQL并run出容器后,建议请先修改完字符集编码后再新建mysql库-表-插数据 docker run -d -p 2222:3306 --privilegedtrue -e MYSQL_ROOT_PASSWORD123456 \ -v /opt/mysql/log:/var/log/mysql \ -v /opt/mysql/data:/va…

通过18次止损,我终于领悟到交易的真谛

截断亏损让利润奔跑,这是操作的基础,也是操作的大体思路。了解并接受这个市场认识,基本上就把握住了市场的门道。至于市场走势,是无法准确预测的。 在交易的第一年,我处于一种懵懂的状态,对市场知之甚少。第…

2024美赛数学建模A题思路分析 - 资源可用性和性别比例

# 1 赛题 问题A:资源可用性和性别比例 虽然一些动物物种存在于通常的雄性或雌性性别之外,但大多数物种实质上是雄性或雌性。虽然许多物种在出生时的性别比例为1:1,但其他物种的性别比例并不均匀。这被称为适应性性别比例的变化。…

【以太网】VSC8512XJG-03、VSC8512XJG-02、VSC8514XMK-14、VSC8514XMK-11千兆以太网(GE)PHY

一、VSC8512 12 Port GbE Cu PHY with 4 Dual Media ports[12端口GBE Cu PHY,带4个双介质端口] 概述 VSC8512采用单一封装的12端口千兆以太网(GE)铜线PHY解决方案。VSC8512采用了Microchip最新的65纳米Simpliphy™技术,是业界最具…

猫什么时候发腮?猫咪发腮指南!这些生骨肉冻干发腮效果好

猫什么时候发腮是许多猫主人非常关心的问题。在猫咪的成长过程中,发腮是一项重要的体征,也是猫咪成熟的标志。主人需要在适龄的年龄段加强营养补给,可以让让猫咪拥有可爱的肉嘟嘟脸型,不要错失最佳发腮期。那么,什么时…

第八篇:node模版引擎Handlebars及他的高级用法(动态参数)

🎬 江城开朗的豌豆:个人主页 🔥 个人专栏 :《 VUE 》 《 javaScript 》 📝 个人网站 :《 江城开朗的豌豆🫛 》 ⛺️ 生活的理想,就是为了理想的生活 ! ​ 目录 📘 引言: &#x1f…

OpenCV学习记录——边缘检测

文章目录 前言一、边缘检测原理二、Canny边缘检测算法三、具体应用代码 前言 在做某些图像处理时,通常需要将识别到的物体边界提取出来,从而帮助我们实现目标检测,这就需要用到边缘检测,例如人脸识别和运动目标的检测都需要先进行…

Flutter 应用服务:主题、暗黑、国际化、本地化 - app_service库

Flutter应用服务 主题、暗黑、国际化、本地化 app_service库 作者:李俊才 (jcLee95):https://blog.csdn.net/qq_28550263 邮箱 :291148484163.com 本文地址:https://blog.csdn.net/qq_28550263/article/det…

Nginx 多项目部署,vue刷新404 解决方案

网上找的资料大多都解决不了,废话不多说直接告诉你解决方法。 环境是 TP6 VUE前端官网 VUE 后台管理 部署 两个项目 刷新 404 解决方案 Nginx 配置 直接贴图 如果解决了,给我顶起来,让更多人 快速的解决。

Arduino 推出基于乐鑫 ESP32-S3 的 STEM 教育机器人

Arduino Alvik 是 Arduino Education 推出的一款新型机器人,可作为一种跨学科工具,为当前教育和未来机器人世界筑起连接的桥梁。Hackster 的 Gareth Halfacree 表示:“Alvik 的设计灵感来自 Arduino 简化复杂技术的理念,同时它也 …

上海市事业编报名照不能成功上传的原因

2024年上海市事业编报名照需要根据以下要求生成: 1、近期6个月,免冠证件照。 2、照片背景白底或者蓝底或者红底背景。 3、照片文件jpg格式,大小在100KB以下 4、照片像素大小,宽度75至150像素内,高度为105至210像素内 5…

gRPC - Google远程过程调用(Google Remote Procedure Call,gRPC)

什么是gRPC? Google远程过程调用(Google Remote Procedure Call,gRPC)是基于HTTP 2.0传输层协议承载的高性能开源RPC软件框架,为管理和配置网络设备提供了一种API接口设计的方法。gRPC提供了多种编程语言,如…

Linux之系统安全与应用续章

目录 一. PAM认证 1.2 初识PAM 1.2.1 PAM及其作用 1.2.2 PAM认证原理 1.2.3 PAM认证的构成 1.2.4 PAM 认证类型 1.2.5 PAM 控制类型 二. limit 三. GRUB加密 /etc/grub.d目录 四. 暴力破解密码 五. 网络扫描--NMAP 六. 总结 一. PAM认证 1.2 初识PAM PAM是Linux系…

软件工程知识梳理4-详细设计

详细设计阶段的根本目标是确定应该怎样具体地实现所要求的系统,也就是说.经过这个阶段的设计工作.应该得出对目标系统的精确描述.从而在编码阶段可以把这个描述直接翻译成用某种程序设计语言书写的程序。 详细设计的的目标不仅仅是逻辑上正确地实现每个模块地功能&a…

查询、导入导出、统计性能优化的一些总结

目录 1、背景 2、优化实现 2.1查询数据表速度慢 2.2调别人接口速度慢 2.3导入速度慢、 2.4导出速度慢的做出介绍 2.5统计功能速度慢 3、总结 1、背景 系统上线后,被用户反应系统很多功能响应时长很慢。用户页面影响速度有要求,下面针对查询数据表…

红队打靶练习:INFOSEC PREP: OSCP

目录 信息收集 1、arp 2、nmap WEB 信息收集 wpscan dirsearch ssh登录 提权 信息收集 1、arp ┌──(root㉿ru)-[~/kali] └─# arp-scan -l Interface: eth0, type: EN10MB, MAC: 00:0c:29:69:c7:bf, IPv4: 192.168.110.128 Starting arp-scan 1.10.0 with 256 ho…

“与客户,共昂首”——Anzo Capital昂首资本尽释行业进取之姿

“以匠心,铸不凡” 活动的现场,Anzo Capital 作为演讲嘉宾分享“以匠心,铸不凡”的产品理念。Anzo Capital积淀九载,匠心打造出“STP”和“ECN”两大核心账户,以光之速度将交易中的订单直达市场和流动性提供商&#…