pytorch手写数字识别

声明:仅自己自学时跟哔站大佬走过程,学习记录而已。

过程步骤总览:

#1.加载必要的库

#2.定义超参数

#3.构建pipeline,对图像做处理

#4.下载、加载数据

#5.构建网络模型

#6.定义优化器

#7.定义训练方法

#8.定义测试方法

#9.调用方法(7、8)

#1.加载必要的库
import numpy as np
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torchvision import datasets,transforms

参数:模型f(x,teta)中的teta称为模型的优化参数,可以通过优化算法进行学习

超参数:用来定义模型结构或优化策略

#2.定义超参数
BATCH_SIZE=16  #每批处理的数据
DEVICE=torch.device("cuda" if torch.cuda.is_available() else "cpu")            #决定cpu训练还是gpu训练
EPOCHS=10                #训练数据集的轮次
#3.构建pipeline,对图像做处理
pipeline=transforms.Compose([
    transforms.ToTensor(),        #将图片转换成tensor
    transforms.Normalize((0.1307,),(0.3081,))  #正则化 模型出现过拟合现象时,降低模型复杂度。
])
#4.下载、加载数据
from torch.utils.data import DataLoader
#下载数据集
train_set=datasets.MNIST("data",train=True,download=True,transform=pipeline)
test_set=datasets.MNIST("data",train=False,download=True,transform=pipeline)
#加载数据
train_loader=DataLoader(train_set,batch_size=BATCH_SIZE,shuffle=True)
test_loader=DataLoader(test_set,batch_size=BATCH_SIZE,shuffle=True)
#插入代码显示MINST中的图片
with open("./data/MNIST/raw/train-images-idx3-ubyte","rb")as f:
    file=f.read()
image1=[int(str(item).encode('ascii'),16)for item in file[16:16+784]]
#print(image1)
import cv2
import numpy as np
image1_np=np.array(image1,dtype=np.uint8).reshape(28,28,1)
print(image1_np.shape)
cv2.imwrite("digit.jpg",image1_np)
#5.构建网络模型
class Digit(nn.Module):
    def __init__(self):
        super().__init__()
        self.conv1=nn.Conv2d(1,10,5) #1:灰度图片的通道 ,10:输出通道 ,5:卷积核
        self.conv2=nn.Conv2d(10,20,3) #10:输入通道 ,20:输出通道 ,3:卷积核Kernel
        self.fc1 =nn.Linear(20*10*10,500) #20*10*10:输入通道; 500:输出通道   全连接层
        self.fc2=nn.Linear(500,10)  #500:输入通道,10:输出通道

    def forward(self,x):
        input_size=x.size(0) #batch_size x 1 x 28 x 28
        x=self.conv1(x) #输入:batch*1*28*28,输出:batch*10*24*24     24=28-5+1
        x=F.relu(x)    #激活函数保持shape不变   输出:batch*10*24*24
        x=F.max_pool2d(x,2,2)  #池化(对图片进行压缩的方法)降采样  输入:batch*10*24*24  输出:batch*10*12*12

        x=self.conv2(x)  #输入:batch*10*12*12 输出:batch*20*10*10  10=12-3+1
        x=F.relu(x)

        x=x.view(input_size,-1) #拉平,-1自动计算维度,20*10*10=2000

        x=self.fc1(x)  #输入:batch*2000  输出:batch*500
        x=F.relu(x)  #激活保持shape不变
        x=self.fc2(x)    #输入:batch*500   输出:batch*10

        output=F.log_softmax(x,dim=1)  #计算分类后,每个数字的概率值

        return output
#6.定义优化器
model=Digit().to(DEVICE)
optimizer=optim.Adam(model.parameters())  #优化器的作用是用来更新模型的参数
#7.定义训练方法
def train_model(model,device,train_loader,optimizer,epoch):
    #模型训练
    model.train()
    for batch_index,(data,target) in enumerate(train_loader):
        #部署到DEVICE上去
        data,target=data.to(device),target.to(device)
        #梯度初始化为0
        optimizer.zero_grad()
        #训练后的结果
        output=model(data)
        #计算损失
        loss=F.cross_entropy(output,target)
        #找到概率值最大的下标
        pred=output.max(1,keepdim=True) #pred=output.argmax(dim=1)
        #反向传播
        loss.backward()
        #参数优化
        optimizer.step()
        if batch_index %3000 ==0:
            print("Train Epoch : {}\t loss : {:.6f}".format(epoch,loss.item()))
#8.定义测试方法
def test_model(model,device,test_loader):
    #模型验证
    model.eval()
    #统计正确率
    correct=0.0
    #测试损失
    test_loss =0.0
    with torch.no_grad():   #不会计算梯度,也不会进行反向传播
        for data,target in test_loader:
            #部署到device上
            data,target=data.to(device),target.to(device)
            #测试数据
            output=model(data)
            #计算测试损失
            test_loss+=F.cross_entropy(output,target).item()
            #找到概率值最大的下标
            pred=output.max(1,keepdim=True)[1]  #值,索引
            #累计正确率
            correct+=pred.eq(target.view_as(pred)).sum().item()
        test_loss /= len(test_loader.dataset)
        print("Test——Average loss:{:.4f},Accuracy: {:.3f}\n".format(test_loss,100.0*correct/len(test_loader.dataset)))
#9.调用方法(7、8)
for epoch in range(1,EPOCHS+1):
    train_model(model,DEVICE,train_loader,optimizer,epoch)
    test_model(model,DEVICE,test_loader)

运行结果展示:

:\miniconda3\python.exe E:/pythonProject2/Exercises/NumbRw.py
(28, 28, 1)
Train Epoch : 1     loss : 2.315663
Train Epoch : 1     loss : 0.009913
Test——Average loss:0.0026,Accuracy: 98.680

Train Epoch : 2     loss : 0.005025
Train Epoch : 2     loss : 0.001901
Test——Average loss:0.0032,Accuracy: 98.460

Train Epoch : 3     loss : 0.001177
Train Epoch : 3     loss : 0.006544
Test——Average loss:0.0022,Accuracy: 99.010

Train Epoch : 4     loss : 0.000113
Train Epoch : 4     loss : 0.000051
Test——Average loss:0.0023,Accuracy: 98.960

Train Epoch : 5     loss : 0.195514
Train Epoch : 5     loss : 0.006552
Test——Average loss:0.0023,Accuracy: 99.060

Train Epoch : 6     loss : 0.000456
Train Epoch : 6     loss : 0.000025
Test——Average loss:0.0032,Accuracy: 98.840

Train Epoch : 7     loss : 0.028158
Train Epoch : 7     loss : 0.000004
Test——Average loss:0.0035,Accuracy: 98.750

Train Epoch : 8     loss : 0.000035
Train Epoch : 8     loss : 0.000030
Test——Average loss:0.0032,Accuracy: 99.000

Train Epoch : 9     loss : 0.001589
Train Epoch : 9     loss : 0.000337
Test——Average loss:0.0040,Accuracy: 98.960

Train Epoch : 10     loss : 0.001058
Train Epoch : 10     loss : 0.000000
Test——Average loss:0.0039,Accuracy: 98.850


进程已结束,退出代码为 0

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

XINYU W

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值