温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

如何使用PyTorch实现MNIST手写体识别

发布时间:2021-05-24 13:52:40 阅读:268 作者:小新 栏目:开发技术
开发者测试专用服务器限时活动,0元免费领,库存有限,领完即止! 点击查看>>

这篇文章将为大家详细讲解有关如何使用PyTorch实现MNIST手写体识别,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

实验环境

win10 + anaconda + jupyter notebook

Pytorch2.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, 22) 
    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 Epoch1 [14848/60000 (25%)]	Loss0.375058
Train Epoch1 [30208/60000 (50%)]	Loss0.255248
Train Epoch1 [45568/60000 (75%)]	Loss0.128060

Test setAverage loss0.0992Accuracy9690/10000 (97%)

Train Epoch2 [14848/60000 (25%)]	Loss0.093066
Train Epoch2 [30208/60000 (50%)]	Loss0.087888
Train Epoch2 [45568/60000 (75%)]	Loss0.068078

Test setAverage loss0.0599Accuracy9816/10000 (98%)

Train Epoch3 [14848/60000 (25%)]	Loss0.043926
Train Epoch3 [30208/60000 (50%)]	Loss0.037321
Train Epoch3 [45568/60000 (75%)]	Loss0.068404

Test setAverage loss0.0416Accuracy9859/10000 (99%)

Train Epoch4 [14848/60000 (25%)]	Loss0.031654
Train Epoch4 [30208/60000 (50%)]	Loss0.041341
Train Epoch4 [45568/60000 (75%)]	Loss0.036493

Test setAverage loss0.0361Accuracy9873/10000 (99%)

Train Epoch5 [14848/60000 (25%)]	Loss0.027688
Train Epoch5 [30208/60000 (50%)]	Loss0.019488
Train Epoch5 [45568/60000 (75%)]	Loss0.018023

Test setAverage loss0.0344Accuracy9875/10000 (99%)

Train Epoch6 [14848/60000 (25%)]	Loss0.024212
Train Epoch6 [30208/60000 (50%)]	Loss0.018689
Train Epoch6 [45568/60000 (75%)]	Loss0.040412

Test setAverage loss0.0350Accuracy9879/10000 (99%)

Train Epoch7 [14848/60000 (25%)]	Loss0.030426
Train Epoch7 [30208/60000 (50%)]	Loss0.026939
Train Epoch7 [45568/60000 (75%)]	Loss0.010722

Test setAverage loss0.0287Accuracy9892/10000 (99%)

Train Epoch8 [14848/60000 (25%)]	Loss0.021109
Train Epoch8 [30208/60000 (50%)]	Loss0.034845
Train Epoch8 [45568/60000 (75%)]	Loss0.011223

Test setAverage loss0.0299Accuracy9904/10000 (99%)

Train Epoch9 [14848/60000 (25%)]	Loss0.011391
Train Epoch9 [30208/60000 (50%)]	Loss0.008091
Train Epoch9 [45568/60000 (75%)]	Loss0.039870

Test setAverage loss0.0341Accuracy9890/10000 (99%)

Train Epoch10 [14848/60000 (25%)]	Loss0.026813
Train Epoch10 [30208/60000 (50%)]	Loss0.011159
Train Epoch10 [45568/60000 (75%)]	Loss0.024884

Test setAverage loss0.0286Accuracy9901/10000 (99%)

Train Epoch11 [14848/60000 (25%)]	Loss0.006420
Train Epoch11 [30208/60000 (50%)]	Loss0.003641
Train Epoch11 [45568/60000 (75%)]	Loss0.003402

Test setAverage loss0.0377Accuracy9894/10000 (99%)

Train Epoch12 [14848/60000 (25%)]	Loss0.006866
Train Epoch12 [30208/60000 (50%)]	Loss0.012617
Train Epoch12 [45568/60000 (75%)]	Loss0.008548

Test setAverage loss0.0311Accuracy9908/10000 (99%)

Train Epoch13 [14848/60000 (25%)]	Loss0.010539
Train Epoch13 [30208/60000 (50%)]	Loss0.002952
Train Epoch13 [45568/60000 (75%)]	Loss0.002313

Test setAverage loss0.0293Accuracy9905/10000 (99%)

Train Epoch14 [14848/60000 (25%)]	Loss0.002100
Train Epoch14 [30208/60000 (50%)]	Loss0.000779
Train Epoch14 [45568/60000 (75%)]	Loss0.005952

Test setAverage loss0.0335Accuracy9897/10000 (99%)

Train Epoch15 [14848/60000 (25%)]	Loss0.006053
Train Epoch15 [30208/60000 (50%)]	Loss0.002559
Train Epoch15 [45568/60000 (75%)]	Loss0.002555

Test setAverage loss0.0357Accuracy9894/10000 (99%)

Train Epoch16 [14848/60000 (25%)]	Loss0.000895
Train Epoch16 [30208/60000 (50%)]	Loss0.004923
Train Epoch16 [45568/60000 (75%)]	Loss0.002339

Test setAverage loss0.0400Accuracy9893/10000 (99%)

Train Epoch17 [14848/60000 (25%)]	Loss0.004136
Train Epoch17 [30208/60000 (50%)]	Loss0.000927
Train Epoch17 [45568/60000 (75%)]	Loss0.002084

Test setAverage loss0.0353Accuracy9895/10000 (99%)

Train Epoch18 [14848/60000 (25%)]	Loss0.004508
Train Epoch18 [30208/60000 (50%)]	Loss0.001272
Train Epoch18 [45568/60000 (75%)]	Loss0.000543

Test setAverage loss0.0380Accuracy9894/10000 (99%)

Train Epoch19 [14848/60000 (25%)]	Loss0.001699
Train Epoch19 [30208/60000 (50%)]	Loss0.000661
Train Epoch19 [45568/60000 (75%)]	Loss0.000275

Test setAverage loss0.0339Accuracy9905/10000 (99%)

Train Epoch20 [14848/60000 (25%)]	Loss0.000441
Train Epoch20 [30208/60000 (50%)]	Loss0.000695
Train Epoch20 [45568/60000 (75%)]	Loss0.000467

Test setAverage loss0.0396Accuracy9894/10000 (99%)

pytorch的优点

1.PyTorch是相当简洁且高效快速的框架;2.设计追求最少的封装;3.设计符合人类思维,它让用户尽可能地专注于实现自己的想法;4.与google的Tensorflow类似,FAIR的支持足以确保PyTorch获得持续的开发更新;5.PyTorch作者亲自维护的论坛 供用户交流和求教问题6.入门简单

关于“如何使用PyTorch实现MNIST手写体识别”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI

开发者交流群×