CNN实现对手写字体的迭代

news2024/11/15 19:25:37

导入库

import torchvision
import torch
from torchvision.transforms import ToTensor
from torch import nn
import matplotlib.pyplot as plt

导入手写字体数据

train_ds=torchvision.datasets.MNIST('data/',train=True,transform=ToTensor(),download=True)
test_ds=torchvision.datasets.MNIST('data/',train=False,transform=ToTensor(),download=True)
train_dl=torch.utils.data.DataLoader(train_ds,batch_size=64,shuffle=True)
test_dl=torch.utils.data.DataLoader(test_ds,batch_size=46)
imgs,labels=next(iter(train_dl))
print(imgs.shape)
print(labels.shape)

从上述代码中可以看到,train_dl返回的图片数据是四维的,4个维度分别代表批次、通道数、高度和宽度(batch,channel,height,width),这正是PyTorch下卷积模型所需要的图片输入格式

创建卷积模型并训练

下面创建卷积模型来识别MNIST手写数据集。我们所创建的卷积模型先试用两个卷积层和两个池化层,然后将最后一个池化的输出展平为二维数据形式连接到全连接层,最后是输出层,中间的每一层都是用ReLU函数激活,输出层的输出张量长度为10,与类别数一致。代码如下

class Model(nn.Module):
    def __init__(self):
        super().__init__()
        self.conv1=nn.Conv2d(1,6,5)   #初始化第一个卷积层
        self.conv2=nn.Conv2d(6,16,5)  #初始化第二个卷积层
        self.liner_1=nn.Linear(16*4*4,256)  #初始化全连接层16*4*4为输入的特征,256为输出的特征
        #就是将一个大小为16×4×4的输入特征映射到一个大小为256的输出特征空间中
        self.liner_2=nn.Linear(256,10)  #初始化输出层
    
    def forward(self,input):
        #调用第一个卷积层和池化层
        x=torch.max_pool2d(torch.relu(self.conv1(input)),2)
        #调用第二个卷积层和池化层
        x=torch.max_pool2d(torch.relu(self.conv2(x)),2)
        # view()方法将数据展平为二维形式
        # torch.Size([64,16,4,4])->torch.Size([64,16*4*4])
        x=x.view(-1,16*4*4)
        x=torch.relu(self.liner_1(x))  # 全连接层
        x=self.liner_2(x)  #输出层
        return x

#判断当前可用的device,如果显卡可用,就设置为cuda,否则设置为cpu
device="cuda" if torch.cuda.is_available() else "cpu"
print("Using {} device".format(device))

#初始化模型,并使用.to()方法将其上传到device
#如果GPU可以用,会上传到显存,如果device是CPU,依保留在内存
model=Model().to(device)  # 初始化模型并设置设备
print(model)

loss_fn=nn.CrossEntropyLoss() # 初始化交叉熵损失函数

optimizer=torch.optim.SGD(model.parameters(),lr=0.001) # 初始化优化器


def train(dataloader,model,loss_fn,optimizer):
    size=len(dataloader.dataset)  # 获取当前数据集样本总数量
    num_batches=len(dataloader)  #获得当前dataloader总批次数
    # train_loss用于累计所有批次的损失之和,correct用于累计预测正确的样本总数
    train_loss,correct=0,0
    for X,y in dataloader:  #对dataloader进行迭代
        X,y=X.to(device),y.to(device)  #每一批次的数据设置为使用当前device进行预测,并计算一个批次的损失
        pred=model(X)
        loss=loss_fn(pred,y)  # 返回的是平均损失
        #使用反向传播算法,根据损失优化模型参数
        optimizer.zero_grad()  #将模型参数的梯度全部归零
        loss.backward()  # 损失反向传播,计算模型参数梯度
        optimizer.step()  # 根据梯度优化参数
        with torch.no_grad():
            # correct 用于累计预测正确的样本总数
            correct+=(pred.argmax(1)==y).type(torch.float).sum().item()
            #train_loss用于累计所有批次的损失之和
            train_loss+=loss.item()
    #train_loss是所有批次的损失之和,所以计算全部样本的平均损失时需要处于总批次数
    train_loss/=num_batches
    #correct是预测正确的样本总是,若计算整个epoch总体正确率,需除以样本总数量
    correct/=size
    return train_loss,correct

def test(dataloader,model):
    size=len(dataloader.dataset)
    num_batches=len(dataloader)
    test_loss,correct=0,0
    with torch.no_grad():
        for X,y in dataloader:
            X,y=X.to(device),y.to(device)
            pred=model(X)
            test_loss+=loss_fn(pred,y).item()
            correct+=(pred.argmax(1)==y).type(torch.float).sum().item()
    test_loss/=num_batches
    correct/=size
    return test_loss,correct


epochs=50  #一个epoch代表对全部数据训练一遍

train_loss=[]  #每个epoch训练中训练数据集的平均损失被添加到此列表
train_acc=[] #每个epoch训练中训练数据集的平均正确率被添加到此列表
test_loss=[]  #每个epoch训练中测试数据集的平均损失被添加到此列表
test_acc=[] #每个epoch训练中测试数据集的平均正确率被添加到此列表

for epoch in range(epochs):
    #调用train()函数训练
    epoch_loss,epoch_acc=train(train_dl,model,loss_fn,optimizer)
    #调用test()函数测试
    epoch_test_loss,epoch_test_acc=test(test_dl,model)
    train_loss.append(epoch_loss)
    train_acc.append(epoch_acc)
    test_loss.append(epoch_test_loss)
    test_acc.append(epoch_test_acc)
    #定义一个打印模版
    template=("epoch:{:2d},train_loss:{:.5f},train_acc:{:.1f}%,test_loss:{:.5f},test_acc:{:.1f}%")
    #输出当前的epoch的训练集损失、训练集正确率、测试集损失、测试集正确率
    print(template.format(epoch,epoch_loss,epoch_acc*100,epoch_test_loss,epoch_test_acc*100))
    
print("Done!")


plt.plot(range(1,epochs+1),train_loss,label="train_loss")
plt.plot(range(1,epochs+1),test_loss,label='test_loss',ls="--")
plt.xlabel('epoch')
plt.legend()
plt.show()


plt.plot(range(1, epochs + 1), train_acc, label="train_acc")
plt.plot(range(1, epochs + 1), test_acc, label='test_acc', ls="--")
plt.xlabel('acc')
plt.legend()
plt.show()

函数式API

import torch.nn.functional as F

class Model(nn.Module):
    def __init__(self):
        super().__init__()
        self.conv1=nn.Conv2d(1,6,5)   #初始化第一个卷积层
        self.conv2=nn.Conv2d(6,16,5)  #初始化第二个卷积层
        self.liner_1=nn.Linear(16*4*4,256)  #初始化全连接层16*4*4为输入的特征,256为输出的特征
        #就是将一个大小为16×4×4的输入特征映射到一个大小为256的输出特征空间中
        self.liner_2=nn.Linear(256,10)  #初始化输出层
    
    def forward(self,input):
        #调用第一个卷积层和池化层
        x=F.max_pool2d(F.relu(self.conv1(input)),2)
        #调用第二个卷积层和池化层
        x=F.max_pool2d(F.relu(self.conv2(x)),2)
        # view()方法将数据展平为二维形式
        # torch.Size([64,16,4,4])->torch.Size([64,16*4*4])
        x=x.view(-1,16*4*4)
        x=F.relu(self.liner_1(x))  # 全连接层
        x=self.liner_2(x)  #输出层
        return x

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

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

相关文章

Hive实战:统计总分与平均分

文章目录 一、实战概述二、提出任务三、完成任务(一)准备数据文件1、在虚拟机上创建文本文件2、将文本文件上传到HDFS指定目录 (二)实现步骤1、启动Hive Metastore服务2、启动Hive客户端3、创建Hive表,加载HDFS数据文件…

websocket 介绍

目录 1,前端如何实现即时通讯短轮询长轮询 2,websocket2.1,握手2.2,握手过程举例2.3,socket.io 3,websocket 对比 http 的优势 1,前端如何实现即时通讯 在 websocket 协议出现之前,…

Tuxera NTFS for Mac2024免费Mac读写软件下载教程

在日常生活中,我们使用Mac时经常会遇到外部设备不能正常使用的情况,如:U盘、硬盘、软盘等等一系列存储设备,而这些设备的格式大多为NTFS,Mac系统对NTFS格式分区存在一定的兼容性问题,不能正常读写。 那么什…

Flask 与微信小程序对接

Flask 与微信小程序的对接 在 web/controllers/api中增建py文件,主要是给微信小程序使用的。 web/controllers/init.py # -*- coding: utf-8 -*- from flask import Blueprint route_api Blueprint( api_page,__name__ )route_api.route("/") def ind…

c++输入输出流和文件操作总结

目录 一、c的输入输出流——> 指的是字节流的数据传送;具有类型安全和可扩展性。 二、流的出入路径 三、c流类库 ①概览 ②标准输出流: ③标准输入流: 四、文件操作(ascii文件和二进制文件) 五、字符串流(或称…

Amazon CodeWhisperer 免费 AI 代码生成助手体验分享

今年上半年,亚马逊云科技正式推出了实时AI编程助手 Amazon CodeWhisperer,还提供了供所有开发人员免费使用的个人版版本。经过一段时间的体验,我觉得 CodeWhisperer 可以处理编程工作中遇到的很多问题,并且帮助开发人员提高编程效…

opencv和gdal的读写图片波段顺序问题

最近处理遥感影像总是不时听到 图片的波段错了,一开始不明就里,都是图片怎么就判断错了。 1、图像RGB波段顺序判断 后面和大家交流,基本上知道了一个判断标准。 一般来说,进入人眼的自然画面在计算机视觉中一般是rgb波段顺序表示…

【Java EE初阶三 】线程的状态与安全(上)

1. join方法与多线程 1.1 初识多线程 为了提高cpu得利用率,因此就引入了多个线程的概念;即每个线程负责完成整个程序的一部分工作即可。 写一个代码,让主线程,创建一个新的线程,由新线程负责完成运算(12。…

Baumer工业相机堡盟工业相机如何通过BGAPI SDK实现Raw格式的图像保存(C++)

Baumer工业相机堡盟工业相机如何通过BGAPI SDK实现Raw格式的图像保存(C) Baumer工业相机Baumer工业相机通过SDK实现Raw格式的图像保存的技术背景通过SDK获取相机信息的代码分析Baumer工业相机回调函数里保存原始图像数据Baumer保存Raw图像格式重要核心代…

时尚男童穿搭 I 棒球服穿搭永不过时

华棉刷毛复合牛奶丝面料 优质的华棉材质,轻柔中带着韧劲拥有卓越的软糯触感 平整的布面复合细腻的绒毛,增加挺阔感基础的佰搭款,利用率真的高 因为版型宽松,不挑身材,怎么搭都好看绣花是hen时尚的字母类绣花 韩范十…

用编程解决习题【计算机图像处理】

用编程解决习题【计算机图像处理】 前言版权第三章 03采样量化与像素间关系三种距离计算编程 第六章 06图像的直方图变换均衡化直方图编程规定化直方图编程 第七章 07图像的噪声抑制均值滤波 中值滤波计算编程knn滤波计算编程 第十章 10二值图像的分析贴标签 膨胀 腐蚀编程 最后…

网络隔离后,怎样建立高效安全的数据安全交换通道?

数据安全对企业生存发展有着举足轻重的影响,数据资产的外泄、破坏都会导致企业无可挽回的经济损失和核心竞争力缺失。数据流动才能让其释放价值,想要保护企业核心资产,就要实现数据安全交换。 很多企业为了防止知识产权、商业机密数据泄露&am…

python嵌套异常处理器

1 python嵌套异常处理器 python的异常处理器支持嵌套。 1.1 嵌套的try/except处理器 用法 def f1():raise E def f2():try:f1()except E:pass try:f2() except E:pass描述 嵌套的try/except处理器,发生异常时,控制权会跳回具有相符的except分句、最近…

钉钉机器人接入定时器(钉钉API+XXL-JOB)

钉钉机器人接入定时器(钉钉APIXXL-JOB) 首先需要创建钉钉内部群 在群设置中找到机器人选项 选择“自定义”机器人 通过Webhook接入自定义服务 创建完成后会生成一个send URL和一个加签码 下面就是干货 代码部分了 DingDingUtil.sendMessageByText(webho…

相机内参标定理论篇------相机模型选择

相机种类&#xff1a; 当拿到一款需要标定内参的相机时&#xff0c;第一个问题就是选择那种的相机模型。工程上相机类型的划分并不是十分严格&#xff0c;一般来说根据相机FOV可以把相机大概分为以下几类&#xff1a; 长焦相机&#xff1a;< 标准相机&#xff1a;~&…

gin框架使用系列之六——自定义中间件

系列目录 《gin框架使用系列之一——快速启动和url分组》《gin框架使用系列之二——uri占位符和占位符变量的获取》《gin框架使用系列之三——获取表单数据》《gin框架使用系列之四——json和protobuf的渲染》《gin框架使用系列之五——表单校验》 一、gin中间件概述 gin中将…

开源项目推荐:Frooodle/Stirling-PDF

简介一个本地的处理 PDF 的工具&#xff0c;界面是 Web UI&#xff0c;可以支持 Docker 部署。各种主要的 PDF 操作都可以支持。比如拆分、合并、转换格式、重新排列、添加图片、旋转、压缩等等。这个本地托管的网络应用最初完全由 ChatGPT 制作&#xff0c;后来逐渐发展&#…

数据结构学习 Leetcode322 零钱兑换

关键词&#xff1a;动态规划 完全背包 记忆化搜索 一个套路&#xff1a; 01背包&#xff1a;空间优化之后dp【target1】&#xff0c;遍历的时候要逆序遍历完全背包&#xff1a;空间优化之后dp【target1】&#xff0c;遍历的时候要正序遍历 题目&#xff1a; 方法一&#xff…

【Docker-Dev】Mac M2 搭建docker mysql

Mac M2 搭建Mysql 1、前言2、前置说明-Docker的代理访问3、前置说明-Mysql的镜像访问3.1、提取信息3.1.1、开启Mysql的实例3.1.2、Dokcer连接Mysql3.1.3、官方简易版的docker-compose3.1.4、如何登录mysql bash3.1.5、自定义my.cnf文件3.1.6、如何知道其他自定义配置项 4、M2安…

【算法题】矩阵顺时针旋转90° (js)

力扣链接&#xff1a;https://leetcode.cn/problems/rotate-matrix-lcci/description/ 本人题解&#xff1a; /*** param {number[][]} matrix* return {void} Do not return anything, modify matrix in-place instead.*/ var rotate function (matrix) {const x matrix.le…