东方耀AI技术分享

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
热搜: 活动 交友 discuz
查看: 2863|回复: 0
打印 上一主题 下一主题

[PyTorch] 06、使用PyTorch在Mnist数据集上训练与验证的所有流程实现

[复制链接]

1365

主题

1856

帖子

1万

积分

管理员

Rank: 10Rank: 10Rank: 10

积分
14435
QQ
跳转到指定楼层
楼主
发表于 2020-4-13 18:40:48 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
06、使用PyTorch在Mnist数据集上训练与验证的所有流程实现




  1. # -*- coding: utf-8 -*-
  2. __author__ = u'东方耀 微信:dfy_88888'
  3. __date__ = '2020/4/13 下午5:11'
  4. __product__ = 'PyCharm'
  5. __filename__ = 'dfy03_mnist'

  6. import torch
  7. import torch.nn as nn
  8. import torch.nn.functional as F
  9. import torch.optim as optim
  10. from torchvision import datasets, transforms

  11. print(torch.__version__)

  12. BATCH_SIZE = 512  # 大概需要2G的显存
  13. EPOCHS = 10  # 总共训练批次
  14. DEVICE = torch.device("cuda" if torch.cuda.is_available() else "cpu")  # 让torch判断是否使用GPU,建议使用GPU环境,因为会快很多

  15. # 对图片数据进行预处理
  16. transform = transforms.Compose([
  17.     transforms.ToTensor(),
  18.     transforms.Normalize(mean=(0.1307,), std=(0.3081,))
  19. ])

  20. trainset = datasets.MNIST(root='./data', train=True, download=True, transform=transform)
  21. testset = datasets.MNIST(root='./data', train=False, download=True, transform=transform)

  22. print(type(trainset))
  23. # pytorch中的数据加载器DataLoader
  24. train_loader = torch.utils.data.DataLoader(trainset, batch_size=BATCH_SIZE, shuffle=True)
  25. test_loader = torch.utils.data.DataLoader(testset, batch_size=BATCH_SIZE, shuffle=True)
  26. print(type(train_loader))

  27. minist01 = iter(train_loader)   # 迭代器 方便按批次取数据
  28. imgs, labels = minist01.next()
  29. print(type(imgs), imgs.numpy().shape, imgs.size())
  30. print(type(labels), labels.size())


  31. class ConvNet(nn.Module):
  32.     def __init__(self):
  33.         super().__init__()
  34.         # 1,28x28
  35.         self.conv1 = nn.Conv2d(1, 10, 5)  # 10, 24x24
  36.         self.conv2 = nn.Conv2d(10, 20, 3)  # 20, 10x10
  37.         self.fc1 = nn.Linear(20 * 10 * 10, 500)
  38.         self.fc2 = nn.Linear(500, 10)

  39.     def forward(self, x):
  40.         in_size = x.size(0)
  41.         # in_size = batch_size
  42.         out = self.conv1(x)  # 24
  43.         out = F.relu(out)
  44.         out = F.max_pool2d(out, 2, 2)  # 12
  45.         out = self.conv2(out)  # 10
  46.         out = F.relu(out)
  47.         # reshape flatten
  48.         out = out.view(in_size, -1)  # [None, 2000]
  49.         out = self.fc1(out)
  50.         out = F.relu(out)
  51.         out = self.fc2(out)
  52.         out = F.log_softmax(out, dim=1)
  53.         return out


  54. model = ConvNet().to(DEVICE)
  55. for i, (name, param) in enumerate(model.named_parameters()):
  56.     print('名字是:%s, 第%d个的权重参数的size=' % (name, i), param.size())
  57. optimizer = optim.Adam(model.parameters(), lr=1e-3)


  58. # 下面定义一下训练的函数,我们将训练的所有操作都封装到这个函数中
  59. def train(model, device, train_loader, optimizer, epoch):
  60.     # 设置模型的训练模式
  61.     model.train()
  62.     for batch_idx, (data, target) in enumerate(train_loader):
  63.         data, target = data.to(device), target.to(device)
  64.         # 梯度归0
  65.         optimizer.zero_grad()
  66.         # 模型前向计算
  67.         output = model(data)
  68.         # 这是什么loss? The negative log likelihood loss
  69.         # loss = F.nll_loss(output, target)
  70.         loss = F.cross_entropy(output, target)
  71.         loss.backward()  # 反向传播算梯度
  72.         optimizer.step()  # 更新权重参数
  73.         if (batch_idx + 1) % 30 == 0:
  74.             print('第{}轮Train [{}/共{}个训练样本 ({:.0f}%)]\tLoss: {:.6f}'.format(
  75.                 epoch, batch_idx * len(data), len(train_loader.dataset),
  76.                        100. * batch_idx / len(train_loader), loss.item()))


  77. # 测试的操作也一样封装成一个函数
  78. def test(model, device, test_loader):
  79.     model.eval()
  80.     test_loss = 0
  81.     correct = 0
  82.     with torch.no_grad():
  83.         for data, target in test_loader:
  84.             data, target = data.to(device), target.to(device)
  85.             output = model(data)
  86.             # test_loss += F.nll_loss(output, target, reduction='sum').item()  # 将一批的损失相加
  87.             test_loss += F.cross_entropy(output, target, reduction='sum').item()
  88.             pred = output.max(1, keepdim=True)[1]  # 找到概率最大的下标
  89.             correct += pred.eq(target.view_as(pred)).sum().item()

  90.     test_loss /= len(test_loader.dataset)
  91.     print('\nTest set: Average loss: {:.4f}, Accuracy: {}/共{}个验证样本 ({:.0f}%)\n'.format(
  92.         test_loss, correct, len(test_loader.dataset),
  93.         100. * correct / len(test_loader.dataset)))


  94. # 下面开始训练,这里就体现出封装起来的好处了,只要写两行就可以了
  95. for epoch in range(1, EPOCHS + 1):
  96.     train(model, DEVICE, train_loader, optimizer, epoch)
  97.     test(model, DEVICE, test_loader)

  98. # MNIST是一个很简单的数据集,由于它的局限性只能作为研究用途,对实际应用带来的价值非常有限。
  99. # 但是通过这个例子,我们可以完全了解一个实际项目的工作流程
  100. #
  101. # 我们找到数据集,对数据做预处理,定义我们的模型,调整超参数,测试训练,
  102. # 再通过训练结果对超参数进行调整或者对模型进行调整。
  103. #
  104. # 并且通过这个实战我们已经有了一个很好的模板,以后的项目都可以以这个模板为样例
复制代码


让天下人人学会人工智能!人工智能的前景一片大好!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|人工智能工程师的摇篮 ( 湘ICP备2020019608号-1 )

GMT+8, 2024-4-29 14:49 , Processed in 0.175920 second(s), 18 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表