PyTorch示例——MLP图像分类-手写数字

39 篇文章 2 订阅
12 篇文章 0 订阅

版本信息

  • PyTorch: 1.12.1
  • Python: 3.7.13

导包

import torch
from torch import nn
from torch.utils.data import DataLoader
from torchvision import datasets
from torchvision.transforms import ToTensor, Normalize, Compose

数据集 MNIST

  • 探索一下数据
explore_data = datasets.MNIST(
    root="./data",
    train=True,
    download=True
)
# 取第0张图片
explore_data[0]
  • 输出信息
(<PIL.Image.Image image mode=L size=28x28 at 0x7F9E30058FD0>, 5)
  • 图像展示
explore_data[0][0]

image.png

  • 标签
explore_data[0][1]
5
  • 多遍历几张图片看看(下面这个方法在PyTorch的图像数据中都很通用)
import matplotlib.pyplot as plt

def show_images(n_rows, n_cols, x_data):
    assert n_rows * n_cols < len(x_data)
    
    plt.figure(figsize=(n_cols * 1.5, n_rows * 1.5))
    for row in range(n_rows):
        for col in range(n_cols):
            index = row * n_cols + col
            plt.subplot(n_rows, n_cols, index + 1)
            plt.imshow(x_data[index][0], cmap="binary", interpolation="nearest")  # 图像
            plt.axis("off")
            plt.title(x_data[index][1])  # 标签
    plt.show()

show_images(3, 5, explore_data)

手写数据图片

  • 正式处理数据
transform_funcs = Compose([
    ToTensor(),
    Normalize((0.1307, ), (0.3081, ))  # 标准化,手写数字数据集的通用参数
])

train_data = datasets.MNIST(
    root="./data",
    train=True,
    download=True,
    transform=transform_funcs
)
test_data = datasets.MNIST(
    root="./data",
    train=False,
    download=True,
    transform=transform_funcs
)

print(train_data.data.shape)
print(test_data.data.shape)
  • 输出信息
torch.Size([60000, 28, 28])
torch.Size([10000, 28, 28])

构建模型 MLP

class MLPModel(nn.Module):
    
  def __init__(self):
    super(MLPModel, self).__init__()
    self.flatten = nn.Flatten()  # 将二维图像展开为一维
    self.linear1 = nn.Linear(28 * 28, 512)
    self.relu = nn.ReLU()
    self.linear2 = nn.Linear(512, 256)
    self.linear3 = nn.Linear(256, 10)
    
  def forward(self, x):
    out = self.flatten(x)
    out = self.linear1(out)
    out = self.relu(out)
    out = self.linear2(out)
    out = self.relu(out)
    out = self.linear3(out)
    return out

开始训练

# 参数配置
epoch_num = 10
batch_size = 64
learning_rate = 0.0005

device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

# 数据加载器
train_loader = DataLoader(train_data, batch_size=batch_size, shuffle=True)

# 模型、损失函数、优化器
model = MLPModel().to(device)
# 交叉熵损失的计算包含了softmax,模型中不需要做softmax
loss = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)


# 训练
loss_list = []
for epoch in range(epoch_num):
    for i, (X_train, y_train) in enumerate(train_loader):
        X_train = X_train.to(device)
        pred = model(X_train)
        y_train = y_train.to(device)
        l = loss(pred, y_train)
        
        optimizer.zero_grad()
        l.backward()
        optimizer.step()
        
        if (i + 1) % 100 == 0:
            print(f"Train... [epoch {epoch + 1}/{epoch_num}, step {i + 1}/{len(train_loader)}]\t[loss {l.item()}]")
    
    loss_list.append(l.item())
Train... [epoch 1/10, step 100/938]	[loss 0.3897044062614441]
Train... [epoch 1/10, step 200/938]	[loss 0.4615764319896698]
Train... [epoch 1/10, step 300/938]	[loss 0.09734677523374557]
Train... [epoch 1/10, step 400/938]	[loss 0.07513687759637833]
Train... [epoch 1/10, step 500/938]	[loss 0.14482976496219635]
Train... [epoch 1/10, step 600/938]	[loss 0.13744832575321198]
Train... [epoch 1/10, step 700/938]	[loss 0.05915261059999466]
Train... [epoch 1/10, step 800/938]	[loss 0.15903039276599884]
Train... [epoch 1/10, step 900/938]	[loss 0.08145355433225632]
Train... [epoch 2/10, step 100/938]	[loss 0.09195274114608765]
Train... [epoch 2/10, step 200/938]	[loss 0.021573053672909737]
Train... [epoch 2/10, step 300/938]	[loss 0.12080539762973785]
Train... [epoch 2/10, step 400/938]	[loss 0.04143274948000908]
Train... [epoch 2/10, step 500/938]	[loss 0.06194964796304703]
Train... [epoch 2/10, step 600/938]	[loss 0.00492143863812089]
Train... [epoch 2/10, step 700/938]	[loss 0.03946655988693237]
Train... [epoch 2/10, step 800/938]	[loss 0.06333575397729874]
Train... [epoch 2/10, step 900/938]	[loss 0.1421077400445938]
......
Train... [epoch 10/10, step 100/938]	[loss 0.0019266537856310606]
Train... [epoch 10/10, step 200/938]	[loss 0.010688461363315582]
Train... [epoch 10/10, step 300/938]	[loss 0.006648594979196787]
Train... [epoch 10/10, step 400/938]	[loss 0.009121301583945751]
Train... [epoch 10/10, step 500/938]	[loss 0.0005547187756747007]
Train... [epoch 10/10, step 600/938]	[loss 0.04679783061146736]
Train... [epoch 10/10, step 700/938]	[loss 0.002314511453732848]
Train... [epoch 10/10, step 800/938]	[loss 0.02470582351088524]
Train... [epoch 10/10, step 900/938]	[loss 0.010127813555300236]

绘制训练曲线

import matplotlib.pyplot as plt

plt.plot(range(epoch_num), loss_list)
plt.xlabel("epoch")
plt.ylabel("loss")
plt.show()

image.png

测试

test_loader = DataLoader(test_data, batch_size=batch_size, shuffle=True)
with torch.no_grad():
    correct = 0
    total = 0
    for X_test, y_test in test_loader:
        X_test = X_test.to(device)
        y_test = y_test.to(device)
        output = model(X_test)
        _, pred = torch.max(output, 1)
        total += y_test.size(0)  # 总数
        correct += (pred == y_test).sum().item()  # 预测对的数量

    print(f'total = {total}, acurrcy = {100 * correct / total}%')
total = 10000, acurrcy = 97.75%
  • 4
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 13
    评论
PyTorch-MNIST-MLP是一个使用PyTorch库和多层感知器(MLP)来训练和测试MNIST手写数字数据集的项目。 MNIST是一个经典的手写数字识别数据集,包含了大量的手写数字图片和对应的标签。通过训练一个模型,我们可以实现自动识别手写数字的功能。 MLP是一种基本的人工神经网络模型,包含了多个全连接的神经网络层,并且每个神经元都与相邻层的所有神经元连接。通过多层的非线性变换和权重调整,MLP可以处理复杂的分类和回归任务。 PyTorch是一个开源的机器学习框架,提供了丰富的工具和函数来简化神经网络模型的构建和训练过程。通过PyTorch,我们可以轻松地搭建和训练MLP模型,并在MNIST数据集上进行实验。 在PyTorch-MNIST-MLP项目中,我们首先加载MNIST数据集,并将其转换成适合MLP模型的格式。然后,我们定义MLP模型的结构,包括输入层、隐藏层和输出层,并使用PyTorch提供的函数来定义损失函数和优化器。 接下来,我们使用训练数据集对MLP模型进行训练,通过反向传播算法和优化器来逐步调整模型的权重和偏置。在训练过程中,我们可以监控模型的精确度和损失值,以评估模型的性能。 最后,我们使用测试数据集对训练好的模型进行测试,并计算模型在测试集上的准确率。通过比较预测结果和真实标签,我们可以评估模型在手写数字识别任务上的表现。 总之,PyTorch-MNIST-MLP是一个基于PyTorch库和MLP模型的项目,用于训练和测试MNIST手写数字数据集。通过该项目,我们可以学习和掌握使用PyTorch构建神经网络模型的基本方法,并实现手写数字识别的功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值