山大软院ai导论实验之采用BP神经网络分类MNIST数据集

目录

实验代码

实验内容


实验代码

python 复制代码
import matplotlib.pyplot as plt
from matplotlib import font_manager
import torch
from torch.utils.data import DataLoader
import torchvision
from torchvision import transforms

# 数据预处理
transform = transforms.Compose([
    transforms.ToTensor(),
    transforms.Normalize((0.5,), (0.5,))
])


train_data_path = 'E:\\小刘的桌面\\人工智能导论实验\\expr2_trainset'
train_dataset = torchvision.datasets.MNIST(root=train_data_path, train=True, download=True, transform=transform)
test_dataset = torchvision.datasets.MNIST(root=train_data_path, train=False, download=True, transform=transform)

# 使用DataLoader加载数据集
train_loader = DataLoader(dataset=train_dataset, shuffle=True, batch_size=100)
test_loader = DataLoader(dataset=test_dataset, shuffle=False, batch_size=100)

# 定义BP神经网络结构
class BPNetwork(torch.nn.Module):
    def __init__(self):
        super(BPNetwork, self).__init__()

        # # 4层
        # self.fc1 = torch.nn.Linear(784, 256)
        # self.activation1 = torch.nn.ReLU()
        # self.fc2 = torch.nn.Linear(256, 128)
        # self.activation2 = torch.nn.ReLU()
        # self.fc3 = torch.nn.Linear(128, 64)
        # self.activation3 = torch.nn.ReLU()
        # self.fc4 = torch.nn.Linear(64, 32)
        # self.activation4 = torch.nn.ReLU()
        # self.fc5 = torch.nn.Linear(32, 10)


        # #2层
        # self.fc1 = torch.nn.Linear(784,64)
        # self.activation1 = torch.nn.ReLU()
        # self.fc2 = torch.nn.Linear(64, 32)
        # self.activation2 = torch.nn.ReLU()
        # self.fc3 = torch.nn.Linear(32, 10)




        # self.softmax = torch.nn.LogSoftmax(dim=1)

    # def forward(self, x):
    #     x = x.view(x.size(0), -1)
    #     x = self.activation1(self.fc1(x))
    #     x = self.activation2(self.fc2(x))
    #     # x = self.activation3(self.fc3(x))
    #     x = self.softmax(self.fc3(x))
    #     return x
    # def forward(self, x):
    #     x = x.view(x.size(0), -1)
    #     x = self.activation1(self.fc1(x))
    #     x = self.activation2(self.fc2(x))
    #     x = self.activation3(self.fc3(x))
    #     x = self.activation4(self.fc4(x))
    #     x = self.softmax(self.fc5(x))  # 修改为使用fc5
    #     return x
        # 3个隐藏层
        self.fc1 = torch.nn.Linear(784, 128)
        self.activation1 = torch.nn.ReLU()
        self.fc2 = torch.nn.Linear(128, 64)
        self.activation2 = torch.nn.ReLU()
        self.fc3 = torch.nn.Linear(64, 32)
        self.activation3 = torch.nn.ReLU()
        self.fc4 = torch.nn.Linear(32, 10)

        self.softmax = torch.nn.LogSoftmax(dim=1)


    def forward(self, x):
        x = x.view(x.size(0), -1)
        x = self.activation1(self.fc1(x))
        x = self.activation2(self.fc2(x))
        x = self.activation3(self.fc3(x))
        x = self.softmax(self.fc4(x))  # 使用fc4作为输出层
        return x

    #     # 5个隐藏层
    #     self.fc1 = torch.nn.Linear(784, 512)
    #     self.activation1 = torch.nn.ReLU()
    #     self.fc2 = torch.nn.Linear(512, 256)
    #     self.activation2 = torch.nn.ReLU()
    #     self.fc3 = torch.nn.Linear(256, 128)
    #     self.activation3 = torch.nn.ReLU()
    #     self.fc4 = torch.nn.Linear(128, 64)
    #     self.activation4 = torch.nn.ReLU()
    #     self.fc5 = torch.nn.Linear(64, 32)
    #     self.activation5 = torch.nn.ReLU()
    #     self.fc6 = torch.nn.Linear(32, 10)
    #
    #     self.softmax = torch.nn.LogSoftmax(dim=1)
    #
    #
    # def forward(self, x):
    #     x = x.view(x.size(0), -1)
    #     x = self.activation1(self.fc1(x))
    #     x = self.activation2(self.fc2(x))
    #     x = self.activation3(self.fc3(x))
    #     x = self.activation4(self.fc4(x))
    #     x = self.activation5(self.fc5(x))
    #     x = self.softmax(self.fc6(x))  # 使用fc6作为输出层
    #     return x


# 创建网络模型
model = BPNetwork()
# 定义损失函数与优化器
criterion = torch.nn.NLLLoss()
optimizer = torch.optim.SGD(model.parameters(), lr=0.009, momentum=0.9)
num_epochs = 1
total_batches = 0

font = font_manager.FontProperties()


batch_steps = []
train_accuracies = []
test_accuracies = []

# 训练网络
for epoch in range(num_epochs):
    for images, labels in train_loader:
        total_batches += 1
        optimizer.zero_grad()  # 清空梯度
        outputs = model(images)  # 前向传播
        loss = criterion(outputs, labels)  # 计算损失
        loss.backward()  # 反向传播
        optimizer.step()  # 更新参数

        # 每50批次计算并记录准确率
        if total_batches % 50 == 0:
            # 计算训练集准确率
            train_correct = (outputs.argmax(dim=1) == labels).sum().item()
            train_accuracy = train_correct / len(images)

            # 计算测试集准确率
            test_correct = 0
            with torch.no_grad():
                for test_images, test_labels in test_loader:
                    test_outputs = model(test_images)
                    test_correct += (test_outputs.argmax(dim=1) == test_labels).sum().item()
            test_accuracy = test_correct / len(test_dataset)

            # 存储结果
            batch_steps.append(total_batches)
            train_accuracies.append(train_accuracy)
            test_accuracies.append(test_accuracy)

            print(f"Step {total_batches}, Training Accuracy: {train_accuracy:.2f}, Test Accuracy: {test_accuracy:.4f}")

# 绘制曲线
plt.figure(figsize=(10, 5))
plt.plot(batch_steps, train_accuracies, label='Training Accuracy', marker='o')
plt.plot(batch_steps, test_accuracies, label='Test Accuracy', marker='x')
plt.title('Training and Test Accuracy Over Time', fontproperties=font, fontsize=18)
plt.xlabel('Batch Steps', fontproperties=font, fontsize=12)
plt.ylabel('Accuracy', fontproperties=font, fontsize=12)
plt.legend()
plt.show()

实验内容

1.下载数据集:

MNIST数据集来自美国国家标准与技术研究所(NIST),包含手写数字图片及其标签。数据集分为训练集和测试集,详细信息如下:

训练集:包含60000张图片及其标签,每张图片是一个28 x 28的灰度图像。

测试集:包含10000张图片及其标签,图片格式与训练集相同。

每个样本代表一个手写数字(0-9),图片中像素值已归一化到[0, 1]范围。

进行数据集的下载:

2.数据预处理:使用torchvision加载MNIST数据集并进行标准化。将训练集和测试集的每个像素点归一化到[-1, 1]范围,以适应神经网络的输入。

  1. 定义BP神经网络结构:构建一个多层感知器网络,在本次实验分别采用了2、3、4、5层隐藏层,用以来观察各个的准确率。其中三层隐藏层中,每层隐藏层分别包含128、64、32个神经元,2层和34层分别递减或者递增即可,另外激活函数为ReLU,输出层采用LogSoftmax。

3个隐藏层:

  1. 训练:设置学习率为0.009,并采用交叉熵损失函数和SGD优化器进行训练。训练集中每批包含100个样本,总共训练1个epoch,每50个批次计算一次训练集和测试集的准确率。最终在训练完所有样本后,记录模型在测试集上的最终准确率。
  1. 为使训练和测试的准确率更为直观,使用matplotlib绘制训练和测试准确率随批次数变化的折线图,以便观察模型的训练过程。
相关推荐
2501_94811424几秒前
Claude Sonnet 4.6 深度评测:性能逼近 Opus、成本打骨折,附接入方案与选型指南
大数据·网络·人工智能·安全·架构
angleboy85 分钟前
【原创】如何WIN 10/11系统下解决YOLOv13训练异常的安装指南
人工智能·深度学习·yolo
kobesdu7 分钟前
ROS导航调参指南:机器人模型、TEB/DWA与Costmap全解析
人工智能·机器人·ros
沫儿笙7 分钟前
库卡焊接机器人混合气节气装置
人工智能·机器人
ZhuNian的学习乐园12 分钟前
LLM智能体调度:从ReAct到多智能体调度
人工智能·python·深度学习
沫儿笙12 分钟前
弧焊机器人节气装置
人工智能·机器人
小超同学你好12 分钟前
LangGraph 25. 实战:Agent资源优化怎么做?用 State 与条件边管理预算、取证与模型档位(附 SRE 分诊 demo)
人工智能·深度学习·语言模型
大公产经晚间消息22 分钟前
美团医药健康与鱼跃、海氏海诺等头部医疗器械品牌深化合作,开拓即时零售新主场
人工智能
xianluohuanxiang25 分钟前
高精度气象:极端天气一来,零售最先出问题的不是客流,而是补货体系和损失控制
开发语言·人工智能·深度学习·机器学习·零售
科威舟的代码笔记33 分钟前
中国专供AI社区腾讯SkillHub来了!
人工智能·ai大模型·skillhub