pytorch实现mnist分类的示例讲解

1. 简介

PyTorch 是一个基于Torch的开源机器学习库,它能够实现动态计算图,使其在动态语言中实现静态计算图的能力。它由Facebook团队开发,可作为NumPy的替代品来使用,能够将计算移到GPU上获得更快的加速。在本篇文章中,我们将介绍如何使用 PyTorch 实现一个 MNIST 分类器。

2. MNIST 数据集

MNIST 是一个手写数字集,包含60,000张训练图像和10,000张测试图像。每个图像都是28x28像素,其中包含一个手写数字(0到9)。MNIST 作为一个样本数据集被广泛用于各种数据科学项目的测试和开源使用,也是用于机器学习的标准数据集之一。

2.1 下载和加载MNIST

我们可以使用 torchvision 来下载和加载 MNIST 数据集。它是 PyTorch 中的一个包,包含常见的数据集,图像变换器以及训练器等。我们可以使用以下代码来下载和加载MNIST数据集:

import torch 

import torchvision

import torchvision.transforms as transforms

# 进行数据预处理和增强

transform = transforms.Compose(

[transforms.ToTensor(),

transforms.Normalize((0.5,), (0.5,))])

# 加载MNIST数据集

trainset = torchvision.datasets.MNIST(root='./data',

train=True, download=True,

transform=transform)

trainloader = torch.utils.data.DataLoader(trainset, batch_size=32,

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=32,

shuffle=False, num_workers=2)

在这里,首先我们定义了一系列的转换,将数据集规范到 -1 到 +1 的值,并将其转换为 PyTorch 张量。接下来,我们使用 `torchvision.datasets.MNIST` 函数从指定目录 root 中加载 MNIST 数据集。

参数定义如下:

train 参数设置为 True,表示加载训练数据集,False 表示加载测试数据集。

download 参数设置为 True,表示如果数据集不存在,则从 Internet 下载数据集。

transform 参数指定数据变换器,它定义如何对每张图片进行转换,并对其进行处理。

3. 构建模型

通过使用 PyTorch,我们可以轻松地定义神经网络的架构。在这个示例中,我们将使用一个简单的全连接神经网络,该网络包括两个隐藏层(即输入层、两个隐藏层和输出层),并对其进行训练和推理。

3.1 定义模型

首先,我们需要定义神经网络模型。在此示例中,我们使用 PyTorch 中的 `nn.Module` 类来定义神经网络。我们定义一个类来包含我们的网络结构。

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, 512) # 输入层到隐藏层1

self.fc2 = nn.Linear(512, 256) # 隐藏层1到隐藏层2

self.fc3 = nn.Linear(256, 10) # 隐藏层2到输出层

def forward(self, x):

x = x.view(-1, 28 * 28)

x = F.relu(self.fc1(x)) # 使用ReLU激活函数

x = F.relu(self.fc2(x)) # 使用ReLU激活函数

x = F.log_softmax(self.fc3(x), dim=1) # output layer

return x

model = Net()

首先,我们继承了 nn.Module 类,它是所有神经网络模型的基类。然后,在构造函数中,我们定义了三个全连接层,每个层之间都有一个 ReLU 激活函数。第一个全连接层将输入张量(尺寸为 1x28x28)转换为 512 的特征表示。第二个层将其转换为大小为 256,最后一个层将其重新转换为输出类别。在 forward 函数中,我们定义了模型的前馈操作,即图像的流向网络

我们将其定义为对张量 x 进行操作的函数,并将结果张量返回。我们使用 `F.relu` 函数来应用 ReLU 激活函数。最后,我们使用 `F.log_softmax` 函数将输出转换为对数域,来得到更好的分数显示。在这里,我们使用 PyTorch 张量的 `view` 函数调整输入形状,使其适应我们的全连接层的输入要求。

3.2 定义优化器和损失函数

接下来,我们定义优化器和损失函数。在这个示例中,我们使用交叉熵损失和 Adam 优化器。在此示例中,我们使用 `nn.CrossEntropyLoss()` 函数来计算损失值,使用 `torch.optim.Adam()` 函数来优化模型。

import torch.optim as optim 

criterion = nn.CrossEntropyLoss()

optimizer = optim.Adam(model.parameters(), lr=0.001)

这里,我们使用 Adam 优化器来更新模型权重,学习率设置为0.001。

4. 训练模型

在创建模型和定义损失函数和优化器之后,我们可以开始训练我们的模型了。训练神经网络的过程通常需要耗费大量的时间和计算资源。在这个示例中,我们设置了 10 个 epoch,并使用 `trainloader` 来训练模型。

for epoch in range(10): 

running_loss = 0.0

for i, data in enumerate(trainloader, 0):

inputs, labels = data

optimizer.zero_grad()

outputs = model(inputs)

loss = criterion(outputs, labels)

loss.backward()

optimizer.step()

running_loss += loss.item()

# 打印训练结果

print('[%d, %5d] loss: %.3f' % (epoch + 1, i + 1, running_loss / 2000))

running_loss = 0.0

在这里,我们首先设置 10 个 epoch,一个 epoch 就是整个数据集在网络上训练一次。我们通过调用 enumerate 函数来获取 `trainloader` 中的批次数据。对于每个批次,我们定义了我们的优化程序(即 Adam),然后计算出了我们的输出和损失。然后将计算出来的梯度传递给了 `backward` 函数,该函数产生梯度。最后,我们使用 `optimizer.step()` 更新模型权重。

5. 测试模型

训练结束后,我们可以使用测试集来评估我们的模型。在进行测试之前,我们需要使用 `model.eval()` 函数将模型设置为评估模式,并使用 `torch.no_grad()` 函数禁用梯度计算,以避免在推理过程中浪费计算资源。

correct = 0 

total = 0

model.eval()

with torch.no_grad():

for data in testloader:

images, labels = data

outputs = model(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))

在这里,我们首先设置 `correct` 和 `total` 初始值为零。然后为模型设置为评估模式,以便在推理过程中使用。在进行测试时,我们使用 `torch.no_grad()`函数停止梯度计算,避免浪费计算资源。对于测试数据集,我们迭代所有图像并计算模型的输出。我们通过:`torch.max(outputs.data, 1)`来获取每个输出中得分最高的标签,并将其预测给 `predicted` 张量。最后,我们将 `predicted` 与原始标签比较,并计算模型在测试集上的准确率。

6. 总结

在这个示例中,我们学习了使用 PyTorch 实现一个简单的数字分类器的方法,并对其进行训练和推理。我们了解了如何使用 PyTorch 加载并进行预处理MNIST数据。并使用 PyTorch 定义了一个神经网络 With 3 layers,并创建了一个损失函数和优化器。在 $10$ epochs 的训练中,我们使用训练集进行模型训练,并使用测试集计算了模型的准确性。

免责声明:本文来自互联网,本站所有信息(包括但不限于文字、视频、音频、数据及图表),不保证该信息的准确性、真实性、完整性、有效性、及时性、原创性等,版权归属于原作者,如无意侵犯媒体或个人知识产权,请来电或致函告之,本站将在第一时间处理。猿码集站发布此文目的在于促进信息交流,此文观点与本站立场无关,不承担任何责任。

后端开发标签