PyTorch识别验证码

## 一、生成测试集数据

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")
   

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

leetcode209长度最小的子数组|滑动窗口算法详细讲解学习

滑动窗口是一种基于双指针的一种思想,两个指针指向的元素之间形成一个窗口。 分类:窗口有两类,一种是固定大小类的窗口,一类是大小动态变化的窗口。 简而言之,滑动窗口算法在一个特定大小的字符串或数组上进行操作&…

如何使用Cloudreve搭建私有云盘并发布公网访问无需购买域名服务器

文章目录 1、前言2、本地网站搭建2.1 环境使用2.2 支持组件选择2.3 网页安装2.4 测试和使用2.5 问题解决 3、本地网页发布3.1 cpolar云端设置3.2 cpolar本地设置 4、公网访问测试5、结语 1、前言 自云存储概念兴起已经有段时间了,各互联网大厂也纷纷加入战局&#…

飞轮储能系统的建模与MATLAB仿真(永磁同步电机作为飞轮驱动电机)

目录 1 主要内容 电网侧控制系统 电机侧模型 模型二 2 结果分析 3 下载链接 1 主要内容 该仿真为飞轮储能系统的建模,包括电网侧和电机侧两部分模型,仿真采用永磁同步电机作为飞轮驱动电机,通过矢量控制的方式对其发电和电动的工况进行控…

基于单片机温度控制系统的研究

摘 要:笔者基于单片机的温度控制系统,从单片机选择、传感器选择、系统框架设计等方面概述了单片机的温度控制系统内涵,分析了其运行原理,列举了单片机温度控制系统设计的实操方法,从硬件系统、软件系统、温度检测方法…

Python武器库开发-武器库篇之zip文件暴力破解(五十一)

Python武器库开发-武器库篇之zip文件暴力破解(五十一) Zip文件是一种常用的存档文件格式,用于将多个文件和文件夹压缩成一个单独的文件。它是一种广泛接受和支持的文件格式,几乎所有操作系统和计算机都能够处理Zip文件。Zip文件使用一种压缩算法来减小文…

sqli-labs靶场第一关详解

目录 sqlilabs靶场第一关 0. sql注入解释 0.1什么是sql注入 0.2sql注入的原理 0.3sql注入方法 0.3.1 数字型注入 0.3.2 字符型注入 1.注入第一步判断请求方式、类型 1.1打开我自己本地的靶场http://sql.com/Less-1/ (上一期靶场搭建:http://t.…

nodejs+vue+ElementUi电商购物个性化商城推荐系统gqfe

电本电商个性化推荐系统是为了提高用户查阅信息的效率和管理人员管理信息的工作效率,可以快速存储大量数据,还有信息检索功能,这大大的满足了用户和管理员这二者的需求。操作简单易懂,合理分析各个模块的功能,尽可能优…

git将项目的某次签入遴选(Cherry-Pick)另一个项目

需求&#xff1a;将项目Product&#xff0c;分支feature/platform&#xff0c;签入959294ce6b75ee48c5cb22c46d7398654628a896&#xff0c;遴选到项目BRP&#xff0c;分支dev 第一步&#xff1a;使用原签入生成patch文件&#xff08;git format-patch -1 <commit_hash>&a…

MySQL原理(一)架构组成之物理文件组成

目录 一、日志文件 1、错误日志 Error Log 1.1、作用&#xff1a; 1.2、开启关闭&#xff1a; 1.3、使用 2、二进制日志 Binary Log & Binary Log Index 2.1、作用&#xff1a; 2.2、开启关闭&#xff1a; 2.3、Binlog还有一些附加选项参数 &#xff08;1&#x…

Linux系统-学习

文章目录 Linux系统-学习 1、自由开源 Linux操作系统完全免费且可用作开源软件&#xff0c;通过开源方式&#xff0c;您可以轻松查看用于创建Linux内核的可用代码&#xff0c;还可以修改代码以修复任何错误等。它提供有许多编程接口&#xff0c;您甚至可以开发自己的程序并将其…

2.1总结

还是一样水更一天&#xff0c;就随便做了几个题&#xff0c;有一个周期有点长&#xff0c;后面更一篇长的 随手刷的一道水题&#xff0c;就不往今天的行程单添了 问题&#xff1a;最大公约数 题解&#xff1a;题目太水了&#xff0c;就是求三个数&#xff0c;其中两组的最大公…

rancher证书过期问题处理

问题 起初&#xff0c;打开rancher ui页面打不开&#xff0c;telnet rancher的服务端口也不通。查看rancher 控制节点&#xff0c;日志显示&#xff0c;X509&#xff1a;certificate has expired or is not ye valid。证书已过期 解决 现在网上大部分的解决方案都是针对的2…

基于51单片机的加油站计费系统

基于51单片机的加油站计费系统[proteus仿真] 计费检测系统这个题目算是课程设计和毕业设计中常见的题目了&#xff0c;本期是一个108基于51单片机的加油站计费系统 需要的源文件和程序的小伙伴可以关注公众号【阿目分享嵌入式】&#xff0c;赞赏任意文章 2&#xffe5;&#…

《C程序设计》上机实验报告(五)之一维数组二维数组与字符数组

实验内容&#xff1a; 1.运行程序 #include <stdio.h> void main( ) { int i,j,iRow0,iCol0,m; int x[3][4]{{1,11,22,33},{2,28,98,38},{3,85,20,89}}; mx[0][0]; for(i0;i<3;i) for(j0;j<4;j) if (x[i][j]>m) { mx[i][j]; iRowi…

Zabbix“专家坐诊”第225期问答汇总

来源&#xff1a;乐维社区 问题一 Q&#xff1a;当系统负荷顶不住时&#xff0c;比如4个cpu&#xff0c;load average 特别高&#xff0c;比如100。这时候这段时间zabbix的所有指标数据会丢失&#xff0c;不知道原因是什么&#xff0c;有没有办法去处理&#xff0c;保存这块指标…

2024年【危险化学品经营单位主要负责人】报名考试及危险化学品经营单位主要负责人免费试题

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 危险化学品经营单位主要负责人报名考试参考答案及危险化学品经营单位主要负责人考试试题解析是安全生产模拟考试一点通题库老师及危险化学品经营单位主要负责人操作证已考过的学员汇总&#xff0c;相对有效帮助危险化…

PostGIS空间数据库之空间数据融合实践

目录 前言 一、ST_Union()简介 1、方法说明 2、参数介绍 二、ST_Collect()简介 1、方法说明 2、参数介绍 3、两者区别 三、实际案例实践 1、不重叠融合 2、空间重叠融合 总结 前言 众所周知&#xff0c;熟悉GIS桌面软件的同学一定都知道&#xff0c;想要对空…

windows下postgresql的安装使用

一、安装 1、安装包安装 1.1 下载exe安装包 选择安装包&#xff1a;官网 或者点击下载&#xff1a;postgresql-12.12-1-windows-x64.exe Tip&#xff1a;此时若报错&#xff1a;There has been an error.An error occured executing the Microsoft VC runtime installer。 参…

(一)hadoop搭建之环境准备1

1.参考http://www.fogsvc.com/97.html文档设置三台虚拟机并固定ip 192.168.1.10 hadoop-master 192.168.1.11 hadoop-slave1 192.168.1.12 hadoop-slave2 2.配置hosts vi /etc/hosts 添加内容 192.168.1.10 hadoop-master 192.168.1.11 hadoop-slave1 192.1…

HIS预约挂号系统源码 看病挂号快人一步

提到去大型医院机构就诊时&#xff0c;许多人都感到恐惧。有些人一旦走进医院的门诊大厅&#xff0c;就感到迷茫&#xff0c;既无法理解导医台医生的建议&#xff0c;也找不到应该去哪个科室进行检查。实际上&#xff0c;就医也是一门学问&#xff0c;如何优化时间分配&#xf…