使用PyTorch实现MNIST手写体识别代码


Posted in Python onJanuary 18, 2020

实验环境

win10 + anaconda + jupyter notebook

Pytorch1.1.0

Python3.7

gpu环境(可选)

MNIST数据集介绍

MNIST 包括6万张28x28的训练样本,1万张测试样本,可以说是CV里的“Hello Word”。本文使用的CNN网络将MNIST数据的识别率提高到了99%。下面我们就开始进行实战。

导入包

import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torchvision import datasets, transforms
torch.__version__

定义超参数

BATCH_SIZE=512
EPOCHS=20 
DEVICE = torch.device("cuda" if torch.cuda.is_available() else "cpu")

数据集

我们直接使用PyTorch中自带的dataset,并使用DataLoader对训练数据和测试数据分别进行读取。如果下载过数据集这里download可选择False

train_loader = torch.utils.data.DataLoader(
    datasets.MNIST('data', train=True, download=True, 
            transform=transforms.Compose([
              transforms.ToTensor(),
              transforms.Normalize((0.1307,), (0.3081,))
            ])),
    batch_size=BATCH_SIZE, shuffle=True)

test_loader = torch.utils.data.DataLoader(
    datasets.MNIST('data', train=False, transform=transforms.Compose([
              transforms.ToTensor(),
              transforms.Normalize((0.1307,), (0.3081,))
            ])),
    batch_size=BATCH_SIZE, shuffle=True)

定义网络

该网络包括两个卷积层和两个线性层,最后输出10个维度,即代表0-9十个数字。

class ConvNet(nn.Module):
  def __init__(self):
    super().__init__()
    self.conv1=nn.Conv2d(1,10,5) # input:(1,28,28) output:(10,24,24) 
    self.conv2=nn.Conv2d(10,20,3) # input:(10,12,12) output:(20,10,10)
    self.fc1 = nn.Linear(20*10*10,500)
    self.fc2 = nn.Linear(500,10)
  def forward(self,x):
    in_size = x.size(0)
    out = self.conv1(x)
    out = F.relu(out)
    out = F.max_pool2d(out, 2, 2) 
    out = self.conv2(out)
    out = F.relu(out)
    out = out.view(in_size,-1)
    out = self.fc1(out)
    out = F.relu(out)
    out = self.fc2(out)
    out = F.log_softmax(out,dim=1)
    return out

实例化网络

model = ConvNet().to(DEVICE) # 将网络移动到gpu上
optimizer = optim.Adam(model.parameters()) # 使用Adam优化器

定义训练函数

def train(model, device, train_loader, optimizer, epoch):
  model.train()
  for batch_idx, (data, target) in enumerate(train_loader):
    data, target = data.to(device), target.to(device)
    optimizer.zero_grad()
    output = model(data)
    loss = F.nll_loss(output, target)
    loss.backward()
    optimizer.step()
    if(batch_idx+1)%30 == 0: 
      print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(
        epoch, batch_idx * len(data), len(train_loader.dataset),
        100. * batch_idx / len(train_loader), loss.item()))

定义测试函数

def test(model, device, test_loader):
  model.eval()
  test_loss = 0
  correct = 0
  with torch.no_grad():
    for data, target in test_loader:
      data, target = data.to(device), target.to(device)
      output = model(data)
      test_loss += F.nll_loss(output, target, reduction='sum').item() # 将一批的损失相加
      pred = output.max(1, keepdim=True)[1] # 找到概率最大的下标
      correct += pred.eq(target.view_as(pred)).sum().item()

  test_loss /= len(test_loader.dataset)
  print('\nTest set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(
    test_loss, correct, len(test_loader.dataset),
    100. * correct / len(test_loader.dataset)))

开始训练

for epoch in range(1, EPOCHS + 1):
  train(model, DEVICE, train_loader, optimizer, epoch)
  test(model, DEVICE, test_loader)

实验结果

Train Epoch: 1 [14848/60000 (25%)]	Loss: 0.375058
Train Epoch: 1 [30208/60000 (50%)]	Loss: 0.255248
Train Epoch: 1 [45568/60000 (75%)]	Loss: 0.128060

Test set: Average loss: 0.0992, Accuracy: 9690/10000 (97%)

Train Epoch: 2 [14848/60000 (25%)]	Loss: 0.093066
Train Epoch: 2 [30208/60000 (50%)]	Loss: 0.087888
Train Epoch: 2 [45568/60000 (75%)]	Loss: 0.068078

Test set: Average loss: 0.0599, Accuracy: 9816/10000 (98%)

Train Epoch: 3 [14848/60000 (25%)]	Loss: 0.043926
Train Epoch: 3 [30208/60000 (50%)]	Loss: 0.037321
Train Epoch: 3 [45568/60000 (75%)]	Loss: 0.068404

Test set: Average loss: 0.0416, Accuracy: 9859/10000 (99%)

Train Epoch: 4 [14848/60000 (25%)]	Loss: 0.031654
Train Epoch: 4 [30208/60000 (50%)]	Loss: 0.041341
Train Epoch: 4 [45568/60000 (75%)]	Loss: 0.036493

Test set: Average loss: 0.0361, Accuracy: 9873/10000 (99%)

Train Epoch: 5 [14848/60000 (25%)]	Loss: 0.027688
Train Epoch: 5 [30208/60000 (50%)]	Loss: 0.019488
Train Epoch: 5 [45568/60000 (75%)]	Loss: 0.018023

Test set: Average loss: 0.0344, Accuracy: 9875/10000 (99%)

Train Epoch: 6 [14848/60000 (25%)]	Loss: 0.024212
Train Epoch: 6 [30208/60000 (50%)]	Loss: 0.018689
Train Epoch: 6 [45568/60000 (75%)]	Loss: 0.040412

Test set: Average loss: 0.0350, Accuracy: 9879/10000 (99%)

Train Epoch: 7 [14848/60000 (25%)]	Loss: 0.030426
Train Epoch: 7 [30208/60000 (50%)]	Loss: 0.026939
Train Epoch: 7 [45568/60000 (75%)]	Loss: 0.010722

Test set: Average loss: 0.0287, Accuracy: 9892/10000 (99%)

Train Epoch: 8 [14848/60000 (25%)]	Loss: 0.021109
Train Epoch: 8 [30208/60000 (50%)]	Loss: 0.034845
Train Epoch: 8 [45568/60000 (75%)]	Loss: 0.011223

Test set: Average loss: 0.0299, Accuracy: 9904/10000 (99%)

Train Epoch: 9 [14848/60000 (25%)]	Loss: 0.011391
Train Epoch: 9 [30208/60000 (50%)]	Loss: 0.008091
Train Epoch: 9 [45568/60000 (75%)]	Loss: 0.039870

Test set: Average loss: 0.0341, Accuracy: 9890/10000 (99%)

Train Epoch: 10 [14848/60000 (25%)]	Loss: 0.026813
Train Epoch: 10 [30208/60000 (50%)]	Loss: 0.011159
Train Epoch: 10 [45568/60000 (75%)]	Loss: 0.024884

Test set: Average loss: 0.0286, Accuracy: 9901/10000 (99%)

Train Epoch: 11 [14848/60000 (25%)]	Loss: 0.006420
Train Epoch: 11 [30208/60000 (50%)]	Loss: 0.003641
Train Epoch: 11 [45568/60000 (75%)]	Loss: 0.003402

Test set: Average loss: 0.0377, Accuracy: 9894/10000 (99%)

Train Epoch: 12 [14848/60000 (25%)]	Loss: 0.006866
Train Epoch: 12 [30208/60000 (50%)]	Loss: 0.012617
Train Epoch: 12 [45568/60000 (75%)]	Loss: 0.008548

Test set: Average loss: 0.0311, Accuracy: 9908/10000 (99%)

Train Epoch: 13 [14848/60000 (25%)]	Loss: 0.010539
Train Epoch: 13 [30208/60000 (50%)]	Loss: 0.002952
Train Epoch: 13 [45568/60000 (75%)]	Loss: 0.002313

Test set: Average loss: 0.0293, Accuracy: 9905/10000 (99%)

Train Epoch: 14 [14848/60000 (25%)]	Loss: 0.002100
Train Epoch: 14 [30208/60000 (50%)]	Loss: 0.000779
Train Epoch: 14 [45568/60000 (75%)]	Loss: 0.005952

Test set: Average loss: 0.0335, Accuracy: 9897/10000 (99%)

Train Epoch: 15 [14848/60000 (25%)]	Loss: 0.006053
Train Epoch: 15 [30208/60000 (50%)]	Loss: 0.002559
Train Epoch: 15 [45568/60000 (75%)]	Loss: 0.002555

Test set: Average loss: 0.0357, Accuracy: 9894/10000 (99%)

Train Epoch: 16 [14848/60000 (25%)]	Loss: 0.000895
Train Epoch: 16 [30208/60000 (50%)]	Loss: 0.004923
Train Epoch: 16 [45568/60000 (75%)]	Loss: 0.002339

Test set: Average loss: 0.0400, Accuracy: 9893/10000 (99%)

Train Epoch: 17 [14848/60000 (25%)]	Loss: 0.004136
Train Epoch: 17 [30208/60000 (50%)]	Loss: 0.000927
Train Epoch: 17 [45568/60000 (75%)]	Loss: 0.002084

Test set: Average loss: 0.0353, Accuracy: 9895/10000 (99%)

Train Epoch: 18 [14848/60000 (25%)]	Loss: 0.004508
Train Epoch: 18 [30208/60000 (50%)]	Loss: 0.001272
Train Epoch: 18 [45568/60000 (75%)]	Loss: 0.000543

Test set: Average loss: 0.0380, Accuracy: 9894/10000 (99%)

Train Epoch: 19 [14848/60000 (25%)]	Loss: 0.001699
Train Epoch: 19 [30208/60000 (50%)]	Loss: 0.000661
Train Epoch: 19 [45568/60000 (75%)]	Loss: 0.000275

Test set: Average loss: 0.0339, Accuracy: 9905/10000 (99%)

Train Epoch: 20 [14848/60000 (25%)]	Loss: 0.000441
Train Epoch: 20 [30208/60000 (50%)]	Loss: 0.000695
Train Epoch: 20 [45568/60000 (75%)]	Loss: 0.000467

Test set: Average loss: 0.0396, Accuracy: 9894/10000 (99%)

总结

一个实际项目的工作流程:找到数据集,对数据做预处理,定义我们的模型,调整超参数,测试训练,再通过训练结果对超参数进行调整或者对模型进行调整。

以上这篇使用PyTorch实现MNIST手写体识别代码就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
在Python中使用HTMLParser解析HTML的教程
Apr 29 Python
python简单猜数游戏实例
Jul 09 Python
Python简明入门教程
Aug 04 Python
解析Python中while true的使用
Oct 13 Python
利用python打印出菱形、三角形以及矩形的方法实例
Aug 08 Python
python中装饰器级连的使用方法示例
Sep 29 Python
Python数据结构与算法之图的广度优先与深度优先搜索算法示例
Dec 14 Python
将字典转换为DataFrame并进行频次统计的方法
Apr 08 Python
python抓取京东小米8手机配置信息
Nov 13 Python
Python代码打开本地.mp4格式文件的方法
Jan 03 Python
python利用selenium进行浏览器爬虫
Apr 25 Python
如何让PyQt5中QWebEngineView与JavaScript交互
Oct 21 Python
Pytorch之finetune使用详解
Jan 18 #Python
pytorch 修改预训练model实例
Jan 18 #Python
Pytorch自己加载单通道图片用作数据集训练的实例
Jan 18 #Python
pyinstaller 3.6版本通过pip安装失败的解决办法(推荐)
Jan 18 #Python
Python实现点云投影到平面显示
Jan 18 #Python
Pytorch 实现计算分类器准确率(总分类及子分类)
Jan 18 #Python
在pytorch 中计算精度、回归率、F1 score等指标的实例
Jan 18 #Python
You might like
php桌面中心(三) 修改数据库
2007/03/11 PHP
Codeigniter的dom类用法实例
2015/06/26 PHP
Linux基于php-fpm模式的lamp搭建phpmyadmin的方法
2018/10/25 PHP
js程序中美元符号$是什么
2008/06/05 Javascript
javascript学习之闭包分析
2010/12/02 Javascript
jQuery如何取id有.的值一般的方法是取不到的
2014/04/18 Javascript
学习JavaScript设计模式(单例模式)
2015/11/26 Javascript
jQuery实现下拉框左右移动(全部移动,已选移动)
2016/04/15 Javascript
jQuery验证插件validate使用详解
2016/05/11 Javascript
浅析JavaScript中命名空间namespace模式
2016/06/22 Javascript
artDialog+plupload实现多文件上传
2016/07/19 Javascript
jQuery自定义多选下拉框效果
2017/06/19 jQuery
Vue表单及表单绑定方法
2018/09/04 Javascript
支付宝小程序实现省市区三级联动
2020/06/21 Javascript
jQuery+ajax实现文件上传功能
2020/12/22 jQuery
JavaScript实现原型封装轮播图
2020/12/27 Javascript
Python引用类型和值类型的区别与使用解析
2017/10/17 Python
详解python实现交叉验证法与留出法
2019/07/11 Python
Python3 A*寻路算法实现方式
2019/12/24 Python
使用python实现下载我们想听的歌曲,速度超快
2020/07/09 Python
python PyAUtoGUI库实现自动化控制鼠标键盘
2020/09/09 Python
HTML5之语义标签介绍
2016/07/07 HTML / CSS
荷兰之家英文站:Holland at Home
2016/10/26 全球购物
Bally巴利中国官网:经典瑞士鞋履、手袋及配饰奢侈品牌
2018/10/09 全球购物
什么是虚拟内存?虚拟内存有什么优势?
2012/02/19 面试题
机电专业求职信
2014/06/14 职场文书
义务教育学校标准化建设汇报材料
2014/08/16 职场文书
五五普法心得体会
2014/09/04 职场文书
机票销售员态度不好检讨书
2014/09/27 职场文书
2014年最新版离婚协议书范本
2014/11/25 职场文书
2016年大学生就业指导课心得体会
2015/10/09 职场文书
2016年世界人口日宣传活动总结
2016/04/05 职场文书
如何在向量化NumPy数组上进行移动窗口
2021/05/18 Python
攻击最高的10只幽灵系神奇宝贝,坚盾剑怪排第一,第五最为可怕
2022/03/18 日漫
Python中request的基本使用解决乱码问题
2022/04/12 Python
virtualenv隔离Python环境的问题解析
2022/06/21 Python