pytorch入门之三(用简单神经网络对mnist进行训练、测试、plot损失)

本文详细介绍使用PyTorch框架构建、训练和测试一个简单的神经网络的过程。通过MNIST手写数字数据集,演示了数据预处理、模型定义、训练流程、评估指标以及结果可视化等关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

pytorch用简单神经网络对模型进行训练、测试、plot过程

导入一些相应的模块

# -*- coding: utf-8 -*-
"""
Created on Fri Jul 27 17:47:03 2018

@author: dj
"""
import numpy as np
import torch
from torchvision.datasets import mnist # 导入 pytorch 内置的 mnist 数据
from torch import nn#从torch模块中导出nn模块
from torch.autograd import Variable#导出Variable

对数据进行处理

def data_tf(x):
    x = np.array(x, dtype='float32') / 255
    x = (x - 0.5) / 0.5 # 标准化,
    x = x.reshape((-1,)) # 拉平
    x = torch.from_numpy(x)
    return x

准备数据制作训练集,测试集

train_set = mnist.MNIST('./data', train=True, transform=data_tf, download=True) # 重新载入数据集即数据集路径,申明定义的数据变换,即对数据的处理导入,download=True时没找到数据集将会对其进行下载
test_set = mnist.MNIST('./data', train=False, transform=data_tf, download=True)#制作测试集
a, a_label = train_set[0]#读取测试集中第一个数据
print(a.shape)#数据的大小
print(a_label)#数据的标签

使用 pytorch 自带的 DataLoader 定义一个数据迭代器

from torch.utils.data import DataLoader#导入DataLoader,在torch中需要dataloader进行迭代
train_data = DataLoader(train_set, batch_size=64, shuffle=True)#训练集,,shuffle为True时打乱数据,让数据更有选择随机性
test_data = DataLoader(test_set, batch_size=128, shuffle=False)#对测试集进行迭代器编号

一个迭代器中的内容

a, a_label = next(iter(train_data))#一个迭代器中的内容
print(a.shape)# 打印出一个批次的数据大小
print(a_label.shape)

使用 Sequential 定义 4 层神经网络,也就是简单的bp

net = nn.Sequential(
    nn.Linear(784, 400),
    nn.ReLU(),
    nn.Linear(400, 200),
    nn.ReLU(),
    nn.Linear(200, 100),
    nn.ReLU(),
    nn.Linear(100, 10)
)
#net
# 定义 loss 函数
criterion = nn.CrossEntropyLoss()#交叉熵损失函数
optimizer = torch.optim.SGD(net.parameters(), 1e-1) # 使用随机梯度下降优化器,学习率 0.1

开始训练

#定义一些空列表来添加训练得到的一些值
losses = []
acces = []
eval_losses = []
eval_acces = []

for e in range(20):
    train_loss = 0
    train_acc = 0
    net.train()#网络开始训练
    for im, label in train_data:
        im = Variable(im)#首先将数据打包成Variable
        label = Variable(label)#得到标签
        # 前向传播
        out = net(im)
        loss = criterion(out, label)
        # 反向传播
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        # 记录误差
        train_loss += loss.item()
        # 计算分类的准确率
        _, pred = out.max(1)#挑选出输出时值最大的位置
        num_correct = (pred == label).sum().item()#记录正确的个数
        acc = num_correct / im.shape[0]#计算精确率
        train_acc += acc
        
    losses.append(train_loss / len(train_data))
    acces.append(train_acc / len(train_data))

在测试集上检验效果

    eval_loss = 0
    eval_acc = 0
    net.eval() # 将模型改为预测模式
    for im, label in test_data:
        im = Variable(im)
        label = Variable(label)
        out = net(im)
        loss = criterion(out, label)
        # 记录误差
        eval_loss += loss.item()
        # 记录准确率
        _, pred = out.max(1)
        num_correct = (pred == label).sum().item()
        acc = num_correct / im.shape[0]
        eval_acc += acc
        
    eval_losses.append(eval_loss / len(test_data))
    eval_acces.append(eval_acc / len(test_data))
    print('epoch: {}, Train Loss: {:.6f}, Train Acc: {:.6f}, Eval Loss: {:.6f}, Eval Acc: {:.6f}'
          .format(e, train_loss / len(train_data), train_acc / len(train_data), 
                     eval_loss / len(test_data), eval_acc / len(test_data)))

对训练的数据进行绘图

import matplotlib.pyplot as plt
plt.title('train loss')
plt.plot(np.arange(len(losses)), losses)
plt.plot(np.arange(len(acces)), acces)
plt.title('train acc')
plt.plot(np.arange(len(eval_losses)), eval_losses)
plt.title('test loss')
plt.plot(np.arange(len(eval_acces)), eval_acces)
plt.title('test acc')

一个简单的神经网络的训练结果
在这里插入图片描述

<think>嗯,用户想要用PyTorch搭建一个神经网络来分类MNIST数据集,要求包括参数优化、对比图绘制、结果解释和样本测试说明。首先,我需要确认用户的需求是否明确。他们提到示例代码,所以代码结构要清晰,注释详细。参数调优可能涉及学习率、优化器选择、批次大小等。可视化对比图可能需要训练过程中的准确率或损失变化,可能还需要展示样本图片和预测结果。结果解释应该包括模型在测试集的表现,分析不同参数的影响。单独样本测试需要从数据集中选取例子,显示预测和实际标签。 接下来,我得检查引用内容是否有帮助。引用2提到MNIST数据集的下载方法,引用4有关于Fashion-MNIST的数据处理,可能可以借鉴。引用3中的GAN网络可能不相关,但参数设置部分可能有参考价值。用户可能希望代码中使用类似的结构,比如数据加载、模型定义、训练循环等。 然后,模型结构方面,MNIST是28x28的灰度图像,所以全连接网络或CNN都可以。考虑到效果,CNN可能更优,但用户可能需要对比不同模型的性能,所以或许应该实现两种结构。不过用户的问题中只提到一个示例代码,可能需要先展示一个基础模型,再讨论优化。例如,先使用全连接网络,再优化成CNN,并比较两者的准确率。 参数调优部分,需要说明如何调整学习率、优化器(如Adam vs SGD)、批次大小,或者增加正则化如Dropout。可能需要设置不同的参数组合,运行实验并记录结果,然后通过图表展示不同参数下的准确率变化。 可视化对比图方面,可能需要绘制训练和验证的损失曲线、准确率曲线,或者在调优时不同学习率的效果对比。此外,测试样本的图像展示,比如选取几个测试样本,显示预测结果和真实标签,帮助直观理解模型表现。 代码注释需要详细,每个部分的功能都要解释清楚,比如数据预处理、模型定义、训练过程、评估步骤等。单独样本测试可能需要从测试集中提取一些图像,输入模型得到预测结果,并可视化比较。 用户还可能希望了解如何保存和加载模型,以便进行后续的测试或部署。此外,错误分析也是重要的一环,比如哪些数字容易被误分类,模型在哪些情况下表现不佳。 现在需要考虑如何组织代码结构。首先导入必要的库,加载数据集,进行数据预处理(如归一化),定义数据加载器。然后定义模型结构,选择损失函数和优化器。编写训练循环,记录损失和准确率。在测试阶段评估模型,绘制图表。最后进行单独样本测试,并展示结果。 在参数调优部分,可能需要使用PyTorch的网格搜索或手动调整超参数,比如尝试不同的学习率(0.1, 0.01, 0.001),不同的优化器,或者不同的网络层结构(隐藏层大小、激活函数)。然后通过绘制对比图来展示不同参数对模型性能的影响。 另外,用户可能需要了解如何防止过拟合,比如使用Dropout层或早停法。在训练过程中监控验证集的表现,当验证损失不再下降时停止训练。 最后,确保代码示例正确无误,注释清晰,结果解释到位。可能需要参考引用中的代码结构,比如数据集的加载方式,模型训练的基本框架,然后在此基础上添加参数调优和可视化的部分。</think>以下是一个使用PyTorch实现MNIST分类的完整示例,包含参数调优、可视化对比和样本测试说明: ```python import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms import matplotlib.pyplot as plt from sklearn.metrics import confusion_matrix import seaborn as sns # 数据预处理 transform = transforms.Compose([ transforms.ToTensor(), transforms.Normalize((0.1307,), (0.3081,)) # MNIST标准化参数 ]) # 加载数据集 train_dataset = datasets.MNIST(root=&#39;./data&#39;, train=True, download=True, transform=transform) test_dataset = datasets.MNIST(root=&#39;./data&#39;, train=False, transform=transform) # 创建数据加载器 batch_size = 64 train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=batch_size, shuffle=True) test_loader = torch.utils.data.DataLoader(test_dataset, batch_size=1000, shuffle=False) # 定义神经网络模型 class MNISTClassifier(nn.Module): def __init__(self): super(MNISTClassifier, self).__init__() self.fc1 = nn.Linear(28*28, 512) self.fc2 = nn.Linear(512, 256) self.fc3 = nn.Linear(256, 10) self.dropout = nn.Dropout(0.2) # 添加Dropout防止过拟合 def forward(self, x): x = x.view(-1, 28*28) # 展平图像 x = torch.relu(self.fc1(x)) x = self.dropout(x) x = torch.relu(self.fc2(x)) x = self.dropout(x) x = self.fc3(x) return x model = MNISTClassifier() # 定义优化器和损失函数 optimizer = optim.Adam(model.parameters(), lr=0.001, weight_decay=1e-5) # 添加L2正则化 criterion = nn.CrossEntropyLoss() # 训练参数 epochs = 15 train_losses = [] test_accuracies = [] # 训练循环 for epoch in range(epochs): model.train() running_loss = 0.0 for images, labels in train_loader: optimizer.zero_grad() outputs = model(images) loss = criterion(outputs, labels) loss.backward() optimizer.step() running_loss += loss.item() # 记录训练损失 train_loss = running_loss/len(train_loader) train_losses.append(train_loss) # 测试集评估 model.eval() correct = 0 total = 0 with torch.no_grad(): for images, labels in test_loader: outputs = model(images) _, predicted = torch.max(outputs.data, 1) total += labels.size(0) correct += (predicted == labels).sum().item() accuracy = 100 * correct / total test_accuracies.append(accuracy) print(f&#39;Epoch [{epoch+1}/{epochs}], Loss: {train_loss:.4f}, Accuracy: {accuracy:.2f}%&#39;) # 绘制训练曲线 plt.figure(figsize=(12, 5)) plt.subplot(1, 2, 1) plt.plot(train_losses, label=&#39;Training Loss&#39;) plt.title(&#39;Training Loss Curve&#39;) plt.xlabel(&#39;Epoch&#39;) plt.ylabel(&#39;Loss&#39;) plt.legend() plt.subplot(1, 2, 2) plt.plot(test_accuracies, label=&#39;Test Accuracy&#39;) plt.title(&#39;Test Accuracy Curve&#39;) plt.xlabel(&#39;Epoch&#39;) plt.ylabel(&#39;Accuracy (%)&#39;) plt.legend() plt.tight_layout() plt.show() # 混淆矩阵 model.eval() all_preds = [] all_labels = [] with torch.no_grad(): for images, labels in test_loader: outputs = model(images) _, predicted = torch.max(outputs, 1) all_preds.extend(predicted.numpy()) all_labels.extend(labels.numpy()) cm = confusion_matrix(all_labels, all_preds) plt.figure(figsize=(10,8)) sns.heatmap(cm, annot=True, fmt=&#39;d&#39;, cmap=&#39;Blues&#39;) plt.xlabel(&#39;Predicted&#39;) plt.ylabel(&#39;True&#39;) plt.title(&#39;Confusion Matrix&#39;) plt.show() # 单个样本测试 sample_idx = 42 # 可修改测试样本索引 sample_image, sample_label = test_dataset[sample_idx] with torch.no_grad(): output = model(sample_image.unsqueeze(0)) predicted = torch.argmax(output).item() plt.imshow(sample_image.squeeze(), cmap=&#39;gray&#39;) plt.title(f&#39;True: {sample_label}, Predicted: {predicted}&#39;) plt.axis(&#39;off&#39;) plt.show() ``` **代码解析与说明**: 1. **参数调优**: - 使用Adam优化器(学习率0.001)并添加L2正则化(weight_decay) - 引入Dropout层(比例0.2)防止过拟合 - 批量大小设置为64,平衡训练速度和内存消耗[^2] 2. **可视化对比**: - 训练损失曲线反映模型收敛情况 - 测试准确率曲线展示泛化能力提升 - 混淆矩阵直观显示各类别分类效果 3. **结果解释**: - 典型训练测试准确率可达98%左右 - 混淆矩阵对角线值越大表示分类效果越好 - 常见错误分类多发生在形近数字(如3/8、4/9等) 4. **样本测试说明**: - 通过修改`sample_idx`可测试任意样本 - 输出包含原始图像、真实标签和预测结果 - 错误案例可帮助分析模型改进方向 **性能优化建议**: 1. 尝试卷积神经网络(CNN)架构提升准确率 2. 使用学习率调度器(如StepLR)优化收敛速度 3. 增加数据增强(旋转、平移)提升泛化能力 4. 对比不同优化器(SGD/Adam)的性能差异
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值