当前位置:   article > 正文

pytorch之mnist(手写数字识别)任务_用pycharm 来完成knn识别手写数字并且使用mnist集实验报告

用pycharm 来完成knn识别手写数字并且使用mnist集实验报告

MNIST任务是作为初学者来说, 是一个不错的起点。掌握MNIST任务的实现,以此为后续的CV(计算机视觉)和DL(深度学习)打下良好基础的基础。

目录

1.任务背景

2.任务流程

3.代码实现


1.任务背景

MNIST(Modified National Institute of Standards and Technology)数据集是一个广泛使用的手写数字识别数据集。它包含了从0到9的数字的灰度图像,通常用于训练和测试图像识别算法。MNIST数据集是由纽约大学的Yann LeCun教授及其同事创建的,它是对原始的NIST数据集进行修改和整理后的版本。

MNIST数据集包含60,000个训练样本和10,000个测试样本。每个样本都是一个28x28像素的灰度图像,代表了0到9中的一个数字。这些图像是从不同的手写体、不同的书写风格和不同的字体中提取的,因此包含了大量的变异性。

2.任务流程

为了让大家更能理解mnist的任务实现,这里绘制了流程图:

3.代码实现

为了源码的可读性,给出了每行源码及其注释。

代码已在pytorch框架调试(NVIDIA RTX 3060 12G,anaconda+pycharm),大家可直接拿来使用,正确率可以达到99%以上,如果达不到,可以根据硬件条件,固定随机种子,修改模型超参数,以达到最优。

  1. '''1.加载必要的库'''
  2. import torch
  3. import torch.nn as nn
  4. import torch.nn.functional as F
  5. import torch.optim as optim
  6. from torchvision import datasets,transforms
  7. from torch.utils.data import DataLoader
  8. '''2.定义超参数'''
  9. BATCH_SIZE=64 # 每个批次处理的图像
  10. EPOCH=10 # 训练数据集的轮次:数据集的循环运行几轮
  11. DEVICE=torch.device('cuda' if torch.cuda.is_available() else 'cpu') # 判断是否用GPU还是CPU训练
  12. '''3.构建pipeline,对图像做预处理(transform)'''
  13. pipeline=transforms.Compose([
  14. transforms.ToTensor(), # 将图片转换成tensor
  15. transforms.Normalize((0.1307,),(0.3081,)) # 正则化,降低模型复杂度
  16. ])
  17. '''4.下载、加载数据集'''
  18. torch.manual_seed(0) #固定随机种子,大家可以尝试不同的种子测试,择选最好的一次
  19. train_set=datasets.MNIST('data',train=True,download=True,transform=pipeline) # 下载训练集
  20. test_set=datasets.MNIST('data',train=False,download=True,transform=pipeline) # 下载测试集
  21. train_loader=DataLoader(train_set,batch_size=BATCH_SIZE,shuffle=True) # 加载训练集
  22. test_loader=DataLoader(test_set,batch_size=BATCH_SIZE,shuffle=True) # 加载测试集 (这里顺序可以不打乱)
  23. '''5.定义网络模型'''
  24. class mnist(nn.Module): # 构建mnist模型,并继承module类
  25. def __init__(self): # 初始化mnist方法
  26. super().__init__() # 继承父类的方法
  27. self.conv1=nn.Conv2d(1,10,5) # 创建一个卷积模型,1:灰度图通道,10:输出通道,5:卷积核(kernel)大小
  28. self.conv2=nn.Conv2d(10,20,3) # 创建一个卷积模型,10:输入通道,20:输出通道,3:kernel大小
  29. self.drop_out=nn.Dropout2d(0.25)
  30. self.fc1=nn.Linear(20*10*10,500) # 20*10*10:输入通道,500:输出通道
  31. self.fc2=nn.Linear(500,10) # # 500:输入通道,10:输出通道
  32. def forward(self,x):
  33. input_size=x.size(0) # 取到第0维:batch_size
  34. x=self.conv1(x) # 输入:batch_size*1*28*28,输出:batch_size*10*24*24(24=28-5+1,padding=0,stride=1)
  35. x=F.relu(x) # 保持shape不变,表达能力更强
  36. x=F.max_pool2d(x,2,2) #最大池化层,步长是2,24/2=12,结果:batch_size*10*12*12
  37. x=self.conv2(x) # 输入:batch_size*10*12*12,输出:batch_size*20*10*10
  38. x=F.relu(x)
  39. x=x.reshape(input_size, -1) # 计算其维度 2000=20*10*10,并将其打平
  40. x=self.fc1(x) # 输入:batch_size=2000, 输出:batch_size*500
  41. x = F.relu(x)
  42. x=self.fc2(x) # 输入:batch_size=500, 输出:batch_size*10
  43. x = F.relu(x)
  44. output=F.log_softmax(x,dim=1) #计算分类后,每个数字的概率值
  45. return output
  46. '''6.定义优化器'''
  47. model=mnist().to(DEVICE) # 创建模型,并部署到设备上
  48. optimizer=optim.Adam(model.parameters()) # 优化模型的参数
  49. '''7.定义训练方法'''
  50. def train_model(model,device,train_loader,optimizer,epoch): # 定义训练方法
  51. model.train() #训练模型
  52. loss_total=0
  53. for batch_index,(data,target) in enumerate(train_loader):
  54. data,target=data.to(device),target.to(device) # 把数据部署到设备上
  55. optimizer.zero_grad() # 梯度初始化为0
  56. output=model(data) # 前向传播,得到训练后的结果
  57. loss=F.cross_entropy(output,target) # 计算损失值
  58. loss.backward() # 将损失值进行反向传播
  59. optimizer.step() # 参数的优化更新
  60. loss_total+=loss.item() # 累加一个epoch所有损失值
  61. loss_epoch=loss_total/len(train_loader) # 计算机每一个epoch的平均损失值
  62. print(f'Train epoch:{epoch} \t loss_epoch:{loss_epoch:0.6f}') # 打印epoch及平均损失值
  63. '''8.定义测试方法'''
  64. def test_model(model,device,test_loader):
  65. model.eval() # 设置模型的评估模式
  66. correct=0.0 # 初始化正确率
  67. loss_test=0.0 # 初始化损失值
  68. with torch.no_grad(): # 测试环境,不计算梯度,也不进行反向传播
  69. for data,target in test_loader:
  70. data,target=data.to(device),target.to(device) # 将数据移动到设备上
  71. output=model(data) # 前向传播
  72. loss_test+=F.cross_entropy(output,target).item() # 累加当前批次的损失值之和
  73. pred = output.max(1, keepdim=True)[1] # 找到概率值最大的下标
  74. correct+=pred.eq(target.view_as(pred)).sum().item() # 计算正确的样本数量
  75. loss_test/=len(test_loader.dataset) # 计算测试集平均的损失
  76. Accuracy=100*correct/len(test_loader.dataset)
  77. print(f'Test_loss:{loss_test:.4f} \t Accuracy:{Accuracy:.3f}\n')
  78. '''9.调用训练和测试的方法'''
  79. for epoch in range(EPOCH):
  80. train_model(model,DEVICE,train_loader,optimizer,epoch)
  81. test_model(model,DEVICE,test_loader)

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/喵喵爱编程/article/detail/790496
推荐阅读
相关标签
  

闽ICP备14008679号