在MINST图像分类数据集上训练一个简单的多层神经网络

基本流程:

数据预处理和加载器->模型定义->损失函数和优化器->训练->推理->训练和评估模型

代码:

import torch
from torch import nn, optim
from torchvision import datasets, transforms
from torch.utils.data import DataLoader

# 数据预处理和加载器
#transform 定义了一系列的数据预处理步骤,包括将图像转换为张量(ToTensor)和标准化(Normalize)
transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.5,), (0.5,))])
#加载了训练集
train_dataset = datasets.MNIST(root='./data', train=True, download=True, transform=transform)
test_dataset = datasets.MNIST(root='./data', train=False, download=True, transform=transform)
#批量的方式加载数据,并在训练时打乱数据(shuffle=True)
train_loader = DataLoader(dataset=train_dataset, batch_size=32, shuffle=True)
test_loader = DataLoader(dataset=test_dataset, batch_size=32, shuffle=False)

# 模型定义
class SimpleNN(nn.Module):
    def __init__(self):
        #继承nn.Module的属性
        super(SimpleNN, self).__init__()
        #第一层全连接,第一个参数为输入层,第二参数为输出层
        #输入层接收外部数据输入的神经元集合,输入层的神经元数目通常与输入数据的特征数目相同。
        #输出层生成最终预测结果的神经元集合
        self.fc1 = nn.Linear(28*28, 128)
        self.fc2 = nn.Linear(128, 64)
        self.fc3 = nn.Linear(64, 10)

    def forward(self, x):
        x = x.view(-1, 28*28)  # 将图像展平成一维向量
        #激活函数将负输入映射为 0,正输入不变
        x = torch.relu(self.fc1(x))
        x = torch.relu(self.fc2(x))
        x = self.fc3(x)
        return x
#实例化模型
model = SimpleNN()


#损失函数:衡量神经网络预测输出与实际目标之间差异的函数。
#CrossEntropyLoss 交叉熵损失
criterion = nn.CrossEntropyLoss()
#优化器:用于调整神经网络权重和偏置的算法,以最小化损失函数
optimizer = optim.Adam(model.parameters(), lr=0.001)

# 训练
def train(model, train_loader, criterion, optimizer, epochs=10):
    for epoch in range(epochs):
        running_loss = 0.0
        for images, labels in train_loader:
            #调用 optimizer.zero_grad() 来清空过往的梯度。这是必须的
            optimizer.zero_grad()
            #一批图像数据传递给模型,模型执行前向传播
            outputs = model(images)
            #使用定义好的损失函数 criterion 来计算预测结果 outputs 和真实标签 labels 之间的损失
            loss = criterion(outputs, labels)
            #来执行反向传播。在这个过程中,PyTorch 计算每个参数相对于损失的梯度
            loss.backward()
            #根据计算出的梯度更新模型的参数
            optimizer.step()
            #running_loss 用于记录每个epoch的总损失。
            running_loss += loss.item()
        print(f'Epoch [{epoch+1}/{epochs}], Loss: {running_loss/len(train_loader):.4f}')

# 推理
def evaluate(model, test_loader):
    model.eval()
    correct = 0
    total = 0
    #关闭梯度计算(torch.no_grad()),遍历测试集,并计算模型预测的正确率。
    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
    print(f'Test Accuracy: {accuracy:.2f}%')

# 训练和评估模型
train(model, train_loader, criterion, optimizer, epochs=10)
evaluate(model, test_loader)

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值