PyTorch中的神经网络 Mnist 分类任务

PyTorch是深度学习领域最受欢迎的框架之一,它不仅易于使用,而且还灵活高效。本文将详细讲解如何在PyTorch中实现MNIST分类任务,让您更加深入地了解PyTorch的使用。

准备工作

在实现MNIST分类任务之前,我们需要以下库:

  • PyTorch 用于构建神经网络模型
  • torchvision 用于获取MNIST数据集
  • matplotlib 用于可视化结果

需要确保电脑上已经安装好了以上三个库。可以使用以下命令来安装:

pip install torch
pip install torchvision
pip install matplotlib

获取数据集

在PyTorch中,可以很方便地获取MNIST数据集。代码如下:

import torch
import torchvision
import torchvision.transforms as transforms

transform = transforms.Compose(
    [transforms.ToTensor(),
     transforms.Normalize((0.5,), (0.5,))])

trainset = torchvision.datasets.MNIST(root='./data', train=True,
                                        download=True, transform=transform)
trainloader = torch.utils.data.DataLoader(trainset, batch_size=64,
                                          shuffle=True, num_workers=2)

testset = torchvision.datasets.MNIST(root='./data', train=False,
                                       download=True, transform=transform)
testloader = torch.utils.data.DataLoader(testset, batch_size=64,
                                         shuffle=False, num_workers=2)

我们首先定义了一个transform对象,用于将数据集转换为张量,并进行归一化处理。接着我们使用torchvision.datasets.MNIST()函数来获取训练集和测试集,其中包括了下载、转换等操作,并使用torch.utils.data.DataLoader()将数据集分成batch,方便模型训练时的批量处理。

构建神经网络

PyTorch中构建神经网络一般分为两个部分。首先需要定义一个继承自torch.nn.Module的类,该类提供了神经网络的整体结构。然后需要定义一个继承自torch.nn.Module的类,该类提供了神经网络的整体结构。

下面给出一个基本的MNIST分类模型例子,仅包含了一个全连接层:

import torch.nn as nn
import torch.nn.functional as F

class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.fc1 = nn.Linear(28 * 28, 10)

    def forward(self, x):
        x = x.view(x.size(0), -1)
        x = self.fc1(x)
        return F.log_softmax(x, dim=1)

在__init__()函数中定义了一个全连接层,其中输入是28*28的像素矢量,输出是10个类别,即0~9。在forward()函数中,我们将数据展开成一维,然后使用全连接层,最后使用log_softmax()进行输出。

训练神经网络

将前面的数据集和神经网络结构传入下面的代码来训练模型:

import torch.optim as optim

net = Net()

criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(net.parameters(), lr=0.01, momentum=0.5)

for epoch in range(10):
    running_loss = 0.0
    for i, data in enumerate(trainloader, 0):
        inputs, labels = data

        optimizer.zero_grad()

        outputs = net(inputs)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()

        running_loss += loss.item()
        if i % 100 == 99:
            print('[%d, %5d] loss: %.3f' %
                  (epoch + 1, i + 1, running_loss / 100))
            running_loss = 0.0

代码中,我们首先定义了一个网络对象net。然后定义了一个损失函数criterion和优化器optimizer,使用nn.CrossEntropyLoss()作为损失函数,使用optim.SGD()作为优化器。接着使用for循环来进行多次epoch的训练,每次训练时将数据分批处理,并通过.net(inputs)函数得到模型的输出,使用损失函数计算损失并进行反向传播和参数更新。

测试神经网络

我们可以使用以下代码来测试训练好的神经网络:

correct = 0
total = 0
with torch.no_grad():
    for data in testloader:
        images, labels = data
        outputs = net(images)
        _, predicted = torch.max(outputs.data, 1)
        total += labels.size(0)
        correct += (predicted == labels).sum().item()

print('Accuracy of the network on the 10000 test images: %d %%' % (
    100 * correct / total))

该代码通过遍历测试集,并将结果与真实标签进行比较,得出神经网络的准确率。

示例说明

下面我们通过两条示例说明MNIST分类任务的实现:

示例一

在上一篇博客《PyTorch中的神经网络FashionMNIST分类任务》中,我们讲解了如何使用这个框架实现FashionMNIST分类任务。在这个示例中,我们将很快理解很多东西是如何使用的。我们将使用一个全连接层来定义网络结构。以下代码展示了如何定义模型。

import torch.nn as nn
import torch.nn.functional as F

class Net(nn.Module):
  def __init__(self):
    super(Net, self).__init__()
    self.fc1 = nn.Linear(28 * 28, 10)

  def forward(self, x):
    x = x.view(-1, 28 * 28)
    x = self.fc1(x)
    x = F.log_softmax(x, dim=1)
    return x

我们接下来需要使用数据加载器来导入FashionMNIST数据集。使用以下代码。

import torch
import torchvision
import torchvision.transforms as transforms

transform = transforms.Compose(
  [transforms.ToTensor(),
   transforms.Normalize((0.5,), (0.5,))])

trainset = torchvision.datasets.FashionMNIST(root='./data', train=True,
                                        download=True, transform=transform)
trainloader = torch.utils.data.DataLoader(trainset, batch_size=64,
                                          shuffle=True, num_workers=2)

testset = torchvision.datasets.FashionMNIST(root='./data', train=False,
                                       download=True, transform=transform)
testloader = torch.utils.data.DataLoader(testset, batch_size=64,
                                         shuffle=False, num_workers=2)
classes = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat',
           'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']

我们将使用SGD作为优化器和交叉熵损失函数。在PyTorch中,实现该任务非常容易。使用以下代码即可。

import torch.optim as optim

net = Net()
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(net.parameters(), lr=0.01, momentum=0.9)

if __name__ == '__main__':
  for epoch in range(10):
    running_loss = 0.0
    for i, data in enumerate(trainloader, 0):
      inputs, labels = data
      optimizer.zero_grad()
      outputs = net(inputs)
      loss = criterion(outputs, labels)
      loss.backward()
      optimizer.step()
      running_loss += loss.item()
      if i % 200 == 199:    
        print('[%d, %5d] loss: %.3f' %
              (epoch + 1, i + 1, running_loss / 200))
        running_loss = 0.0

使用以下代码来保存神经网络的模型参数:

PATH = './fashion_mnist_net.pth'
torch.save(net.state_dict(), PATH)

接下来,我们可以使用以下代码在测试集上测试训练好的神经网络:

correct = 0
total = 0
with torch.no_grad():
  for data in testloader:
    images, labels = data
    outputs = net(images)
    _, predicted = torch.max(outputs.data, 1)
    total += labels.size(0)
    correct += (predicted == labels).sum().item()

print('Accuracy of the network on the 10000 test images: %d %%' % (
  100 * correct / total))

示例二

在这个例子中,我们将使用卷积神经网络(CNN)来解决MNIST分类问题。在以下代码中,我们定义了一个简单的卷积神经网络,其中包括两个卷积层和两个全连接层:

import torch
import torch.nn as nn
import torch.nn.functional as F

class Net(nn.Module):
  def __init__(self):
    super(Net, self).__init__()
    self.conv1 = nn.Conv2d(1, 32, 3, 1)
    self.conv2 = nn.Conv2d(32, 64, 3, 1)
    self.dropout1 = nn.Dropout2d(0.25)
    self.dropout2 = nn.Dropout2d(0.5)
    self.fc1 = nn.Linear(9216, 128)
    self.fc2 = nn.Linear(128, 10)

  def forward(self, x):
    x = self.conv1(x)
    x = F.relu(x)
    x = self.conv2(x)
    x = F.relu(x)
    x = F.max_pool2d(x, 2)
    x = self.dropout1(x)
    x = torch.flatten(x, 1)
    x = self.fc1(x)
    x = F.relu(x)
    x = self.dropout2(x)
    x = self.fc2(x)
    output = F.log_softmax(x, dim=1)
    return output

我们使用以下代码定义损失函数和优化器:

import torch.optim as optim

net = Net()
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adadelta(net.parameters(), lr=1.0)

下面是训练代码:

if __name__ == '__main__':
  for epoch in range(1, 15):
    train_loss, correct, total = 0, 0, 0
    net.train()
    for batch_idx, (data, target) in enumerate(trainloader):
      optimizer.zero_grad()
      output = net(data)
      loss = criterion(output, target)
      loss.backward()
      optimizer.step()
      train_loss += loss.item()
      _, predicted = torch.max(output.data, 1)
      total += target.size(0)
      correct += (predicted == target).sum().item()
      if batch_idx % 100 == 0:
        print('Train Epoch: {} [{}/{} ({:.0f}%)] Loss: {:.6f} Acc: {:.6f}'.format(
          epoch, batch_idx * len(data), len(trainloader.dataset),
          100. * batch_idx / len(trainloader), train_loss/(batch_idx+1), 100.*correct/total))

使用以下代码在测试集上测试训练好的神经网络:

correct, total = 0, 0
net.eval()
with torch.no_grad():
    for batch_idx, (data, target) in enumerate(testloader):
        output = net(data)
        _, predicted = torch.max(output.data, 1)
        total += target.size(0)
        correct += (predicted == target).sum().item()
    print('Test Acc: {:.6f}'.format(100.*correct/total))

这里我们使用Adadelta作为优化器,并在训练中使用了torch.no_grad()函数,以便在计算准确率时不会计算梯度。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:PyTorch中的神经网络 Mnist 分类任务 - Python技术站

(0)
上一篇 2023年5月25日
下一篇 2023年5月25日

相关文章

  • OpenCV计算轮廓长度/周长和面积

    首先,计算轮廓长度/周长和面积需要使用到OpenCV库中的cv2.contourArea()和cv2.arcLength()函数。在计算前需要先检测出轮廓。 以下是计算轮廓长度/周长和面积的详细攻略: 1. 导入库 import cv2 import numpy as np 2. 读取并预处理图像 image = cv2.imread(‘test.jpg’)…

    人工智能概论 2023年5月25日
    00
  • PyTorch梯度下降反向传播

    PyTorch是一个基于Torch的Python开源深度学习库。它提供了计算图和自动微分等强大的功能,使得我们可以简单、高效地实现神经网络等深度学习模型。而梯度下降反向传播(Gradient Descent Backpropagation)是神经网络训练中最常用的优化算法,用于求解神经网络的参数。 下面,我将详细讲解PyTorch中梯度下降反向传播的完整攻略…

    人工智能概论 2023年5月25日
    00
  • 使用bandit对目标python代码进行安全函数扫描的案例分析

    使用bandit对目标Python代码进行安全函数扫描的攻略如下: 安装bandit 首先,需要安装bandit。可以通过pip命令安装,如下所示: pip install bandit 扫描代码 安装完成后,就可以对目标Python代码进行扫描了。使用以下命令可以进行扫描: bandit -r [目标代码文件夹名称] 其中,-r表示递归扫描该文件夹下的所有…

    人工智能概论 2023年5月25日
    00
  • 基于opencv+java实现简单图形识别程序

    基于OpenCV和Java实现简单图形识别程序的攻略分为以下几个步骤: 安装OpenCV 下载并安装OpenCV,在官网的下载页面(https://opencv.org/releases/)中选择适合自己操作系统的版本进行下载。 解压下载好的压缩包到本地。 将OpenCV添加到系统PATH环境变量中,在Windows操作系统中可在“环境变量”中设置。 配置J…

    人工智能概览 2023年5月25日
    00
  • 关于Django使用 django-celery-beat动态添加定时任务的方法

    关于Django使用django-celery-beat动态添加定时任务的方法 Django是一个开放源代码的高层次Python Web框架。开发人员可以利用Django的许多条款和模块来开发完整的Web应用程序。而celery是Python语言使用的一个异步任务队列,它轻量级、高效,可靠,非常适用于处理高并发的异步任务。而django-celery-bea…

    人工智能概览 2023年5月25日
    00
  • C/C++题解LeetCode1295统计位数为偶数的数字

    下面是详细讲解“C/C++题解LeetCode1295统计位数为偶数的数字”的完整攻略。 题目描述 给你一个整数数组 nums,请你返回其中位数为 偶数 的数字的个数。 示例 1: 输入:nums = [12,345,2,6,7896]输出:2解释:12 是 2 位数字(位数为偶数) 345 是 3 位数字(位数为奇数)  2 是 1 位数字(位数为奇数) …

    人工智能概论 2023年5月25日
    00
  • 编写每天定时切割Nginx日志的脚本

    编写每天定时切割Nginx日志的脚本可以有效的管理日志文件,避免日志文件过大导致服务器性能问题,同时还能提供更好的日志管理体验。下面介绍一下具体的步骤。 1. 安装 logrotate 工具 logrotate 是一个日志管理工具,可以用于指定日志目录,日志文件切割方式和周期等相关操作。在 CentOS 上,通过以下命令安装: yum install -y …

    人工智能概览 2023年5月25日
    00
  • 完美解决torch.cuda.is_available()一直返回False的玄学方法

    下面我将为你详细讲解如何完美解决torch.cuda.is_available()一直返回False的问题。 问题描述 在使用PyTorch进行深度学习时,我们通常会使用GPU加速训练,其中一个常用的判断是否可用的方法是使用torch.cuda.is_available()。然而,在某些情况下,这个函数会一直返回False,即使我们的机器上已经安装了CUDA…

    人工智能概论 2023年5月25日
    00
合作推广
合作推广
分享本页
返回顶部