pytorch学习笔记——mnist

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

@pytorch学习笔记第一天


前言

一、MNIST手写数字识别

看十遍不如手敲一遍。

二、使用步骤

模型结构

import torch
import torch.nn as nn
import torch.nn.functional as F
from torchvision import datasets as mnist
from torchvision import transforms
from torch.utils.data import DataLoader
import torch.optim as optim

class Mnist_NN(nn.Module):
    def __init__(self):
        super().__init__()
        self.hidden1 = nn.Linear(784,128)
        self.hidden2 = nn.Linear(128,256)
        self.hidden3 = nn.Linear(256,512)
        self.out = nn.Linear(512,10)
        self.dropout = nn.Dropout(0.5)

    def forward(self, x):
        # 展平4维输入为2维(batch_size, 784# x = x.view(x.size(0), -1)  # 或 x = torch.flatten(x, start_dim=1)
        x = F.relu(self.hidden1(x))
        x = self.dropout(x)
        x = F.relu(self.hidden2(x))
        x = self.dropout(x)
        x = F.relu(self.hidden3(x))
        x = self.out(x)
        return x

net = Mnist_NN()

2.读入数据

代码如下(示例):

train_batch = 128
test_batch =128

#下载数据集
transform = transforms.Compose([
    transforms.ToTensor(),  # 输出维度:(1, 28, 28)
    # 正确展平:保持batch_size在前,展平后维度为(batch_size, 784)
    transforms.Normalize([0.5], [0.5]),  # 对784个特征进行归一化
    transforms.Lambda(lambda x: x.view(-1))  # -1表示展平所有维度,得到(784,)

])
data_train = mnist.MNIST('D:/my/mnist/data',train=True, transform=transform, target_transform=None, download=True)
data_test = mnist.MNIST('D:/my/mnist/data',train=False, transform=transform, target_transform=None, download=True)

#加载数据集
train_loader = DataLoader(data_train, batch_size=train_batch,shuffle=True)
test_loader = DataLoader(data_test, batch_size=test_batch,shuffle=True)


3.设置模型参数

#设置训练次数
num_epochs = 10

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

#定义学习率
LR = 0.001
optimizer = optim.Adam(net.parameters(), LR)

#
train_losses = []
train_acces = []
#测试
eval_losses = []
eval_acces = []

4.模型训练

#模型训练
#模型训练
for epoch in range(num_epochs):
    #初始化统计量,每轮开始时重置损失和准确率。
    train_loss = 0
    train_acc = 0

    #设置训练模式
    net.train()

    for data, label in train_loader:
        # print('数据维度',data.shape)
        out = net(data)               # 前向传播
        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 / data.shape[0]           # 准确率

        train_acc += acc                            # 累加准确率

    train_losses.append(train_loss / len(train_loader))
    train_acces.append(train_acc / len(train_loader))

    # 测试阶段
    net.eval()
    eval_loss, eval_acc = 0.0, 0.0
    with torch.no_grad():
        for img, label in test_loader:
            out = net(img)
            loss = criterion(out, label)
            eval_loss += loss.item()
            _, pred = out.max(1)
            eval_acc += (pred == label).sum().item() / img.size(0)

    # 记录结果
    train_loss /= len(train_loader)
    train_acc /= len(train_loader)
    eval_loss /= len(test_loader)
    eval_acc /= len(test_loader)

    train_losses.append(train_loss)
    train_acces.append(train_acc)
    eval_losses.append(eval_loss)
    eval_acces.append(eval_acc)

    # 输出
    print(f"epoch:{epoch}, Train Loss:{train_loss:.4f}, Train Acc:{train_acc:.4f}, "
          f"Test Loss:{eval_loss:.4f}, Test Acc:{eval_acc:.4f}")

总结

完整源码

import torch
import torch.nn as nn
import torch.nn.functional as F
from torchvision import datasets as mnist
from torchvision import transforms
from torch.utils.data import DataLoader
import torch.optim as optim

class Mnist_NN(nn.Module):
    def __init__(self):
        super().__init__()
        self.hidden1 = nn.Linear(784,128)
        self.hidden2 = nn.Linear(128,256)
        self.hidden3 = nn.Linear(256,512)
        self.out = nn.Linear(512,10)
        self.dropout = nn.Dropout(0.5)

    def forward(self, x):
        # 展平4维输入为2维(batch_size, 784# x = x.view(x.size(0), -1)  # 或 x = torch.flatten(x, start_dim=1)
        x = F.relu(self.hidden1(x))
        x = self.dropout(x)
        x = F.relu(self.hidden2(x))
        x = self.dropout(x)
        x = F.relu(self.hidden3(x))
        x = self.out(x)
        return x

net = Mnist_NN()


train_batch = 128
test_batch =128

#下载数据集
# 修正数据预处理中的展平操作(关键修复点)
transform = transforms.Compose([
    transforms.ToTensor(),  # 输出维度:(1, 28, 28)
    # 正确展平:保持batch_size在前,展平后维度为(batch_size, 784)
    transforms.Normalize([0.5], [0.5]),  # 对784个特征进行归一化
    transforms.Lambda(lambda x: x.view(-1))  # -1表示展平所有维度,得到(784,)

])
data_train = mnist.MNIST('E:/code/map_code/data',train=True, transform=transform, target_transform=None, download=True)
data_test = mnist.MNIST('E:/code/map_code/data',train=False, transform=transform, target_transform=None, download=True)

#加载数据集
train_loader = DataLoader(data_train, batch_size=train_batch,shuffle=True)
test_loader = DataLoader(data_test, batch_size=test_batch,shuffle=True)


#设置训练次数
num_epochs = 10

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

#定义学习率
LR = 0.001
optimizer = optim.Adam(net.parameters(), LR)

#
train_losses = []
train_acces = []
#测试
eval_losses = []
eval_acces = []


#模型训练
for epoch in range(num_epochs):
    #初始化统计量,每轮开始时重置损失和准确率。
    train_loss = 0
    train_acc = 0

    #设置训练模式
    net.train()

    for data, label in train_loader:
        # print('数据维度',data.shape)
        out = net(data)               # 前向传播
        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 / data.shape[0]           # 准确率

        train_acc += acc                            # 累加准确率

    train_losses.append(train_loss / len(train_loader))
    train_acces.append(train_acc / len(train_loader))

    # 测试阶段
    net.eval()
    eval_loss, eval_acc = 0.0, 0.0
    with torch.no_grad():
        for img, label in test_loader:
            out = net(img)
            loss = criterion(out, label)
            eval_loss += loss.item()
            _, pred = out.max(1)
            eval_acc += (pred == label).sum().item() / img.size(0)

    # 记录结果
    train_loss /= len(train_loader)
    train_acc /= len(train_loader)
    eval_loss /= len(test_loader)
    eval_acc /= len(test_loader)

    train_losses.append(train_loss)
    train_acces.append(train_acc)
    eval_losses.append(eval_loss)
    eval_acces.append(eval_acc)

    # 输出
    print(f"epoch:{epoch}, Train Loss:{train_loss:.4f}, Train Acc:{train_acc:.4f}, "
          f"Test Loss:{eval_loss:.4f}, Test Acc:{eval_acc:.4f}"))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值