• PyTorch学习-总结篇(3)——最实用部分


    PyTorch学习-总结篇(3)——最实用部分

    经过(1)和(2)的学习,相信对基础知识有一定的了解,其实如果想快速进行代码书写与项目调试及运行,仅看(3)应该可以让你快速掌握项目的编写规则。

    一、每个项目代码应该有五个部分(大同小异)

    • 首先,一个项目的代码应该是导包及定义我们的超参数

    • 然后,将本次项目所需数据集读入,一般包括训练集和测试集两个部分

    • 其次,开始搭建我们的网络模型主体框架

    • 再然后,是进行模型的损失函数、优化器及可视化操作

    • 最后,是进行我们模型的训练及测试

    二、以一个项目示例来进行讲解(MNIST手写数据集)

    1.导包及定义超参数(这步往往是最后才能完成的,因为只有写完了下面,才能知道你要定义什么及用什么包)

    # -*- coding: utf-8 -*-
    # -代码界的小菜鸟-

    import os
    import torch
    import torch.untils.data as Data
    import torch.nn as nn
    import torch.nn.functional as F
    import torch.optim as optim
    from tensorboardX import SummaryWriter
    from torchvision import datasets,transforms

    batch_size = 64
    epochs = 10
    checkpoints_dir = './checkpoints'
    event_dir = './event_file'
    model_name = None  # 如果需要加载模型继续训练,则’/10.pth‘
    lr = 1e-4

    #检测GPU是否可以使用
    print('GPU是否可用:', torch.cuda.is_available())  # 可用为True
    device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

    2.数据集读入

    # 实例化数据集Dataset
    train_dataset = datasets.MNIST(root='./dataset/', train=True, download=True,transform=transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.1307,), (0.3081,))]))
    test_dataset = datasets.MNIST(root='./dataset/', train=False, transform=transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.1307,), (0.3081,))]))

    # 数据加载器
    train_loader = Data.DataLoader(train_dataset, batch_size=batch_size, shuffle=True)  # shuffle是否随机打乱顺序
    test_loader = Data.DataLoader(test_dataset, batch_size=batch_size, shuffle=True)

    # 保存检查点的地址
    if not os.path.exists(checkpoints_dir):
       os.makedirs(checkpoints_dir)

    3.模型的搭建

    # 模型搭建(pytorch框架定义的的神经网络模型都需要继承nn.Module类)
    class Net(nn.Module):

      # 初始化函数,定义了该神经网络的基本结构
      def __init__(self):
          super(Net, self).__init__()  # 复制并使用Net的父类的初始化方法,即先运行nn.Module的初始化函数
          self.conv1 = nn.Conv2d(in_channels=1, out_channels=20, kernel_size=5, stride=1)  # 输入为图像(1),即灰度图,输出为20张特征图,卷积和为5*5的正方形
          self.conv2 = nn.Conv2d(in_channels=20, out_channels=20, kernel_size=5, stride=1)
          self.fc1 = nn.Linear(in_features=4*4*20, out_features=300)  # 定义全连接线性函数:y=Wx+b,并将4*4*20个节点连接到300个节点上
          self.fc2 = nn.Linear(in_features=300, out_features=10)

      # 定义神经网络的前向传播函数
      def forward(self, x):
          x = F.relu(self.conv1(x))  # 输入x经过卷积conv1后,再经过一个激活函数更新x
          x = F.max_pool2d(x, kernel_size=2, stride=2)  # 经过激活函数后,使用2*2的窗口进行最大池化,更新x
          x = F.relu(self.conv2(x))
          x = F.max_pool2d(x, 2, 2)
          x = x.view(-1, 4 * 4 * 20)  # 利用view函数将张量x变成一维向量的形式,总特征个数不变
          x = F.relu(self.fc1(x))  # 更新后的x经过全连接函数,再经过激活函数,更新x
          x = self.fc2(x)
          return x
     
    # 模型实例化
    model = Net().to(device)

    4.损失函数、优化器、可视化及继续训练

    # 定义损失函数
    criterion = nn.CrossEntropyLoss()  # 交叉熵损失函数

    # 定义优化器
    optimzer = optim.SGD(model.parameters(), lr=lr)

    # 可视化处理
    writer = SummaryWriter(event_dir)

    # 继续训练
    start_epoch = 0
    if model_name:
       print('加载模型:',checkpoints_dir + model_name)
       checkpoint = torch.load(checkpoints_dir + model_name)
       model.load_state_dict(checkpoint['model_state_dict'])
       optimzer.load_state_dict(checkpoint['optimizer_state_dict'])
       start_epoch = checkpoint['epoch']

    5.模型的训练

    # 开始训练
    for epoch in range(start_epoch, epochs):
       model.train()  # 模型训练的标志
       for batch_idx, (data, target) in enumerate(train_loader):
           data = data.to(device)  # 训练数据,放到GPU上
           target = target.to(device)  # 训练标签,放到GPU上

           # 前向传播
           output = model(data)
           loss = criterion(output, target)  # 计算损失函数

           # 反向传播
           optimzer.zero_grad()  # 首先进行梯度清零
           loss.backward()  # 反向传播
           optimzer.step()  # 更新参数

       print('Train Epoch: {} Loss:{{:,6f}}'.format(epoch+1, loss.item()))

       # 可视化
       writer.add_scalar(tag='train_loss', scalar_value=loss.item(), global_step=epoch + 1)
       writer.flush()


       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)
               pred = output.argmax(dim=1, keepdim=True)  # 获取最大的对数概率的索引
               correct += pred.eq(target.view_as(pred)).sum().item()
               test_loss += criterion(output, target).item()

       test_loss /= len(test_loader.dataset)
       print('测试集:损失:{:.4f},精度:{:.2f}%'.format(test_loss, 100. * correct / len(test_loader.dataset)))

       # 可视化
       writer.add_scalar(tag='val_loss', scalar_value=test_loss, global_step=epoch + 1)
       writer.flush()


       # 保存模型
       if (epoch + 1) % 10 ==0:
           checkpoint = {'model_state_dict':model.state_dict(), 'optimizer_state_dict': optimzer.state_dict(), 'epoch': epoch + 1}
           torch.save(checkpoint, '%s/%d.pth' % (checkpoints_dir, epochs))
           
    #结果显示
    GPU是否可用: True
    Train Epoch: 1 Loss:2.264611
    测试集:损失:0.0358,精度:20.98%
    Train Epoch: 2 Loss:2.253827
    测试集:损失:0.0354,精度:28.34%
    Train Epoch: 3 Loss:2.217229
    测试集:损失:0.0349,精度:39.88%
    Train Epoch: 4 Loss:2.233548
    测试集:损失:0.0343,精度:50.97%
    Train Epoch: 5 Loss:2.144451
    测试集:损失:0.0335,精度:58.34%
    Train Epoch: 6 Loss:2.111312
    测试集:损失:0.0325,精度:64.29%
    Train Epoch: 7 Loss:1.988998
    测试集:损失:0.0310,精度:68.26%
    Train Epoch: 8 Loss:1.837759
    测试集:损失:0.0290,精度:71.13%
    Train Epoch: 9 Loss:1.635040
    测试集:损失:0.0264,精度:72.52%
    Train Epoch: 10 Loss:1.344689
    测试集:损失:0.0232,精度:75.39%

    可视化步骤:

    1.打开event_file文件夹,在当前文件夹打开cmd,然后输入tensorboard --logdir "./",就可以看到:

    2.打开浏览器在 浏览器中输入https://localhost:6006/ 即可显示 :

     

    torch.utils.data
  • 相关阅读:
    怎么查看当前进程?怎么执行退出?怎么查看当前路径?
    简述正则表达式及其用途?
    Java 中,抽象类与接口之间有什么不同?
    哪个命令专门用来查看后台任务?
    什么是线程池?有哪几种创建方式?
    什么是多线程的上下文切换?
    WebApplicationContext?
    synchronized、volatile、CAS 比较?
    使用 Spring 有哪些方式?
    线程池的优点?
  • 原文地址:https://www.cnblogs.com/minyuan/p/13969547.html
Copyright © 2020-2023  润新知