minist手写数字识别实现

跟着视频敲的代码,记录学习过程。

完整程序:

import matplotlib.pyplot as plt
import torch
import os
import torchvision
import numpy as np
import torch.nn.functional as F
from torch.utils.data import DataLoader
from torch import nn
from PIL import Image
import warnings
warnings.filterwarnings("ignore")

train_batch_size = 64
test_batch_size = 1000
img_size = 28

#----------------------------------------------------------------------------#
# 创建一个数据加载器,用于从数据集中获取一批次的数据。
# 可以帮助在训练神经网络时进行小批量梯度下降优化,提高模型的训练效果。
#----------------------------------------------------------------------------#
def get_dataloader(train = True):
    # -------------------------------------------------------------------------#
    # /data:数据集的存储路径。你可以将其更改为你想要的任何路径。
    # train=train:指定是否要加载训练集或测试集的数据。
    # download=True:如果数据集不存在,会自动下载并存储在指定路径中。
    # transform:转换操作列表,用于对数据进行预处理。这里的操作包括将图像转换为
    # 张量(ToTensor())和对图像进行标准化(Normalize())。
    #batch_size 根据是否是训练数据加载器还是测试数据加载器进行不同的设置。
    # 使用 torch.utils.data.DataLoader 创建数据加载器对象。
    # 其中的参数包括数据集对象、批次大小、以及是否对数据进行洗牌。
    #--------------------------------------------------------------------------#
    dataset = torchvision.datasets.MNIST("/data",train=train,download = True,
        transform = torchvision.transforms.Compose([
        torchvision.transforms.ToTensor(),
        torchvision.transforms.Normalize((0.1307,),(0.3081)),
        ]))
    batch_size = train_batch_size if train else test_batch_size
    dataloader = torch.utils.data.DataLoader(dataset,batch_size=batch_size,shuffle=True)
    return dataloader

class MnistNet(nn.Module):
    def __init__(self):
        super(MnistNet,self).__init__()
        self.fc1 = nn.Linear(784,256)
        self.fc2 = nn.Linear(256,64)
        self.fc3 = nn.Linear(64,10)

    def forward(self,x):
        x = x.view(-1,784)
        x = self.fc1(x)
        x = F.relu(x)
        x = self.fc2(x)
        x = F.relu(x)
        x = self.fc3(x)
        return F.log_softmax(x,dim=-1)

mnist_net = MnistNet()
#----------------#
# 交叉熵损失函数
# Adam优化器
#----------------#
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(mnist_net.parameters(),lr=0.001)
train_loss_list = []
train_count_list = []

def train(epoch):
#-------------------------------------------------------------------------------------#
# 通过调用 train() 方法将神经网络模型设置为训练模式
#调用 get_dataloader() 函数创建一个训练数据加载器
#使用 enumerate() 函数遍历训练数据加载器,获取每个批次的数据和对应的标签。
# data 是输入数据(图像),target 是对应的真实标签(类别)。
#optimizer.zero_grad():用于清空优化器中之前批次的梯度信息(梯度清零)
#将输入数据 data 传入神经网络模型 mnist_net 进行前向传播,得到模型的输出结果 output。
#使用损失函数计算模型预测结果 output 和真实标签 target 之间的损失值。
#进行反向传播,自动计算梯度,并将梯度信息保存在参数的 .grad 属性中
#根据梯度信息更新模型的参数。优化器会利用参数的梯度调整参数的数值,以减小损失。
#train_loss_list.append(loss.item()):将当前批次的损失值存储到 train_loss_list 列表中。
# 这样可以记录每个批次的损失值,方便后续绘制损失曲线或进行其他分析。
#train_count_list.append(index*train_batch_size+(epoch-1)*len(train_dataloader)):
#将当前批次的累计样本数加上之前所有训练样本数量存储到 train_count_list 列表中。
# 这样可以记录每个批次之前已经训练过的样本数,用于可视化训练过程中的样本数量。
#------------------------------------------------------------------------------------#
    mnist_net.train(True)
    train_dataloader = get_dataloader(True)
    for index,(data,target) in enumerate(train_dataloader):
        optimizer.zero_grad()
        output = mnist_net(data)
        loss = F.nll_loss(output,target)
        loss.backward()
        optimizer.step()
        if index % 100 == 0:
            print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(
                epoch, index * len(data), len(train_dataloader.dataset),
                       100. * index / len(train_dataloader), loss.item()))
            train_loss_list.append(loss.item())
            train_count_list.append(index*train_batch_size+(epoch-1)*len(train_dataloader))

def test():
#--------------------------------------------------------------------------------------------#
#test_loss = 0:初始化测试损失为0。该变量将用于累加每个样本的损失值。
#correct = 0:初始化正确预测的样本数为0。该变量将用于统计模型在测试集上的准确率。
#mnist_net.eval():通过调用 eval() 方法将神经网络模型设置为评估模式。
#test_dataloader = get_dataloader(train=False):调用 get_dataloader() 函数创建一个测试数据加载器
#with torch.no_grad():使用 torch.no_grad() 上下文管理器,确保在评估过程中不会记录计算图,从而节省内存空间
#for data, target in test_dataloader::遍历测试数据加载器,获取每个样本的数据和对应的标签
#将输入数据 data 传入神经网络模型 mnist_net 进行前向传播,得到模型的输出结果 output
#计算当前样本的损失值,并累加到测试损失test_loss上。reduction参数设置为 'sum',表示将每个样本的损失值进行累加。
#pred = output.data.max(1, keepdim=True)[1]:
# 根据模型的输出结果 output ,找到每个样本预测的最大概率对应的类别索引
#correct += pred.eq(target.data.view_as(pred)).sum():
# 统计预测正确的样本数。将预测结果 pred 与真实标签 target 进行比较,并将预测正确的样本数进行累加
#test_loss /= len(test_dataloader.dataset):将测试损失除以测试集样本数量,得到平均损失
#打印输出测试集的评估结果。包括平均损失和准确率。
#--------------------------------------------------------------------------------------------#
    test_loss = 0
    correct = 0
    mnist_net.eval()
    test_dataloader = get_dataloader(train=False)
    with torch.no_grad():
        for data, target in test_dataloader:
            output = mnist_net(data)
            test_loss += F.nll_loss(output, target, reduction='sum').item()
            pred = output.data.max(1, keepdim=True)[1]
            correct += pred.eq(target.data.view_as(pred)).sum()
    test_loss /= len(test_dataloader.dataset)
    print('\nTest set: Avg. loss: {:.4f}, Accuracy: {}/{} ({:.2f}%)\n'.format(
        test_loss, correct, len(test_dataloader.dataset),
        100. * correct / len(test_dataloader.dataset)))

if __name__ == '__main__':

    test()
    for i in range(5):
        train(i)
        test()

下载数据集结果:

 运行结果:

Test set: Avg. loss: 2.3212, Accuracy: 1206/10000 (12.06%)

Train Epoch: 0 [0/60000 (0%)]    Loss: 2.321229
Train Epoch: 0 [6400/60000 (11%)]    Loss: 0.550573
Train Epoch: 0 [12800/60000 (21%)]    Loss: 0.175103
Train Epoch: 0 [19200/60000 (32%)]    Loss: 0.254183
Train Epoch: 0 [25600/60000 (43%)]    Loss: 0.121522
Train Epoch: 0 [32000/60000 (53%)]    Loss: 0.280531
Train Epoch: 0 [38400/60000 (64%)]    Loss: 0.205788
Train Epoch: 0 [44800/60000 (75%)]    Loss: 0.034362
Train Epoch: 0 [51200/60000 (85%)]    Loss: 0.125562
Train Epoch: 0 [57600/60000 (96%)]    Loss: 0.093930

Test set: Avg. loss: 0.1192, Accuracy: 9627/10000 (96.27%)

Train Epoch: 1 [0/60000 (0%)]    Loss: 0.089502
Train Epoch: 1 [6400/60000 (11%)]    Loss: 0.131700
Train Epoch: 1 [12800/60000 (21%)]    Loss: 0.128198
Train Epoch: 1 [19200/60000 (32%)]    Loss: 0.053703
Train Epoch: 1 [25600/60000 (43%)]    Loss: 0.051744
Train Epoch: 1 [32000/60000 (53%)]    Loss: 0.057353
Train Epoch: 1 [38400/60000 (64%)]    Loss: 0.293683
Train Epoch: 1 [44800/60000 (75%)]    Loss: 0.069954
Train Epoch: 1 [51200/60000 (85%)]    Loss: 0.291764
Train Epoch: 1 [57600/60000 (96%)]    Loss: 0.066690

Test set: Avg. loss: 0.1065, Accuracy: 9669/10000 (96.69%)

Train Epoch: 2 [0/60000 (0%)]    Loss: 0.157847
Train Epoch: 2 [6400/60000 (11%)]    Loss: 0.021395
Train Epoch: 2 [12800/60000 (21%)]    Loss: 0.085961
Train Epoch: 2 [19200/60000 (32%)]    Loss: 0.211282
Train Epoch: 2 [25600/60000 (43%)]    Loss: 0.029853
Train Epoch: 2 [32000/60000 (53%)]    Loss: 0.031299
Train Epoch: 2 [38400/60000 (64%)]    Loss: 0.019096
Train Epoch: 2 [44800/60000 (75%)]    Loss: 0.064281
Train Epoch: 2 [51200/60000 (85%)]    Loss: 0.111029
Train Epoch: 2 [57600/60000 (96%)]    Loss: 0.075113

Test set: Avg. loss: 0.0832, Accuracy: 9746/10000 (97.46%)

Train Epoch: 3 [0/60000 (0%)]    Loss: 0.034858
Train Epoch: 3 [6400/60000 (11%)]    Loss: 0.065938
Train Epoch: 3 [12800/60000 (21%)]    Loss: 0.020054
Train Epoch: 3 [19200/60000 (32%)]    Loss: 0.010132
Train Epoch: 3 [25600/60000 (43%)]    Loss: 0.051468
Train Epoch: 3 [32000/60000 (53%)]    Loss: 0.042442
Train Epoch: 3 [38400/60000 (64%)]    Loss: 0.068702
Train Epoch: 3 [44800/60000 (75%)]    Loss: 0.093545
Train Epoch: 3 [51200/60000 (85%)]    Loss: 0.011688
Train Epoch: 3 [57600/60000 (96%)]    Loss: 0.015226

Test set: Avg. loss: 0.0780, Accuracy: 9755/10000 (97.55%)

Train Epoch: 4 [0/60000 (0%)]    Loss: 0.075244
Train Epoch: 4 [6400/60000 (11%)]    Loss: 0.024666
Train Epoch: 4 [12800/60000 (21%)]    Loss: 0.031698
Train Epoch: 4 [19200/60000 (32%)]    Loss: 0.098030
Train Epoch: 4 [25600/60000 (43%)]    Loss: 0.020235
Train Epoch: 4 [32000/60000 (53%)]    Loss: 0.002573
Train Epoch: 4 [38400/60000 (64%)]    Loss: 0.051085
Train Epoch: 4 [44800/60000 (75%)]    Loss: 0.014662
Train Epoch: 4 [51200/60000 (85%)]    Loss: 0.023142
Train Epoch: 4 [57600/60000 (96%)]    Loss: 0.047781

Test set: Avg. loss: 0.0777, Accuracy: 9772/10000 (97.72%)
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

彭毓众

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

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

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

打赏作者

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

抵扣说明:

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

余额充值