【实验记录】动手实现一个简单的神经网络实验(一)

embedded/2024/12/28 10:55:05/

最近上了“神经网络深度学习”这门课,有一个自己动手实现调整神经网络模型的实验感觉还挺有记录意义,可以帮我巩固之前学习到的理论知识,所以就打算记录一下。

实验大概是使用LeNet(卷积神经网络)对MINIST数据集做图像分类任务,然后自己调整模型和参数感受一下各方面给模型带来的影响。

本来老师是给了代码让我们只要调整模型就好,但我还是想自己动手写一下。

老师给的完整代码:

import torch
from torch import nn
import torch.nn.functional as F
import torch.optim as optim
from torch.utils.data import DataLoader, TensorDataset# 加载包含多个张量的字典的pt文件
loaded_dict = torch.load(r'data\MNIST\processed\training.pt')
loaded_dict_test = torch.load(r'data\MNIST\processed\test.pt')
images, label = loaded_dict # 将图像和标签分开images_test, label_test = loaded_dict_test
images_test = images_test.unsqueeze(1)
X_test = images_test.to(torch.float32)
y_test = label_testnet = nn.Sequential(nn.Conv2d(1, 6, kernel_size=5, padding=2),nn.Sigmoid(),nn.AvgPool2d(kernel_size=2, stride=2),nn.Conv2d(6,16, kernel_size=5),nn.Sigmoid(),nn.AvgPool2d(kernel_size=2, stride=2),nn.Flatten(),nn.Linear(16 * 5 * 5, 120),nn.Sigmoid(),nn.Linear(120, 84),nn.Sigmoid(),nn.Linear(84, 10)
)images = images.unsqueeze(1)
X_train = images.to(torch.float32)
y_train = label
""""""
# 取X的前100个数据
X_train = X_train[:10000]
y_train = y_train[:10000]
X_test = X_test[:1000]
y_test = y_test[:1000]class LeNet(nn.Module):def __init__(self, net):super().__init__()self.net = netdef forward(self,X):out = F.log_softmax(net(X),dim=1)return outdef train(model, device, train_ , optimizer, epoch):model.train()for i, (X, y) in enumerate(train_):X.to(device)y.to(device)optimizer.zero_grad()predict_y = model(X)loss = F.nll_loss(predict_y, y)loss.backward()optimizer.step()if(i+1)%100 == 0:print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(epoch, i * len(X), len(train_.dataset),100. * i / len(train_), loss.item()))def test(model, device, test_):model.eval()test_loss = 0correct = 0with torch.no_grad():for i, (X, y) in enumerate(test_):X.to(device)y.to(device)predict_y = model(X)test_loss += F.nll_loss(predict_y, y, reduction='sum').item()pred = predict_y.max(1, keepdim = True)[1]correct += y.eq(pred.view_as(y)).sum().item()test_loss /= len(test_loader.dataset)print('\nTest set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(test_loss, correct, len(test_.dataset),100. * correct / len(test_.dataset)))batch_size = 10train_dataset = TensorDataset(X_train, y_train)
train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)test_dataset = TensorDataset(X_test, y_test)
test_loader = DataLoader(test_dataset, batch_size=batch_size, shuffle=False)Net = LeNet(net)
optimizer = optim.Adam(Net.parameters())
for epoch in range(5):train(Net, 'cpu', train_loader, optimizer = optimizer, epoch = epoch)test(Net, 'cpu', test_loader)

我自己也写了一个,还是参考了很多老师写的qwq

import torch
from torch import nn
import torch.nn.functional as F
import torch.optim as optim
from torch.utils.data import DataLoader, TensorDataset# 加载包含多个张量的字典的pt文件
loaded_dict = torch.load(r'data\MNIST\processed\training.pt')
loaded_dict_test = torch.load(r'data\MNIST\processed\test.pt')
images, label = loaded_dict # 将图像和标签分开images_test, label_test = loaded_dict_test
images_test = images_test.unsqueeze(1)
X_test = images_test.to(torch.float32)
y_test = label_testnet = nn.Sequential(nn.Conv2d(1, 6, kernel_size=5, padding=2),nn.Sigmoid(),nn.AvgPool2d(kernel_size=2, stride=2),nn.Conv2d(6,16, kernel_size=5),nn.Sigmoid(),nn.AvgPool2d(kernel_size=2, stride=2),nn.Flatten(),nn.Linear(16 * 5 * 5, 120),nn.Sigmoid(),nn.Linear(120, 84),nn.Sigmoid(),nn.Linear(84, 10)
)images = images.unsqueeze(1)
X_train = images.to(torch.float32)
y_train = label
""""""
# 取X的前100个数据
X_train = X_train[:10000]
y_train = y_train[:10000]
X_test = X_test[:1000]
y_test = y_test[:1000]class LeNet(nn.Module):def __init__(self, net):super().__init__()self.net = netdef forward(self,X):out = F.log_softmax(net(X),dim=1)return outdef train(model, device, train_ , optimizer, epoch):model.train()for i, (X, y) in enumerate(train_):X.to(device)y.to(device)optimizer.zero_grad()predict_y = model(X)loss = F.nll_loss(predict_y, y)loss.backward()optimizer.step()if(i+1)%100 == 0:print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(epoch, i * len(X), len(train_.dataset),100. * i / len(train_), loss.item()))def test(model, device, test_):model.eval()test_loss = 0correct = 0with torch.no_grad():for i, (X, y) in enumerate(test_):X.to(device)y.to(device)predict_y = model(X)test_loss += F.nll_loss(predict_y, y, reduction='sum').item()pred = predict_y.max(1, keepdim = True)[1]correct += y.eq(pred.view_as(y)).sum().item()test_loss /= len(test_loader.dataset)print('\nTest set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(test_loss, correct, len(test_.dataset),100. * correct / len(test_.dataset)))batch_size = 10train_dataset = TensorDataset(X_train, y_train)
train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)test_dataset = TensorDataset(X_test, y_test)
test_loader = DataLoader(test_dataset, batch_size=batch_size, shuffle=False)Net = LeNet(net)
optimizer = optim.Adam(Net.parameters())
for epoch in range(5):train(Net, 'cpu', train_loader, optimizer = optimizer, epoch = epoch)test(Net, 'cpu', test_loader)

ps:我写的这个运行前要下载数据集在指定位置,老师的可以自动下载。

总结了一下写train、test函数的步骤:

train函数:

输入:模型model, 设备device, 训练集迭代器train_loader, 优化器optimizer, 轮次epoch(仅打印结果时用)

流程:

  1. 将模型改为训练模式
  2. 循环遍历迭代器
  3. 将迭代器转移在设备device上
  4. 清空优化器梯度
  5. 代入模型计算模型预测结果
  6. 计算损失函数
  7. 进行梯度反向传播
  8. 使用优化器更新模型参数
  9. 打印此轮结果

test函数:

输入:

  1. 将模型改为评估模式
  2. 初始化总损失值、总正确个数
  3. 循环遍历迭代器
  4. 将迭代器转移在设备device上
  5. 计算损失函数
  6. 将损失值加在总损失中
  7. 将正确个数加在总计算个数中
  8. 总损失除以总个数计算平均损失
  9. 打印此轮结果

加载数据:

train_loader = torch.utils.data.DataLoader(datasets.MNIST('data', train=True, download=True,transform=transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.1307,), (0.3081,))])),batch_size=BATCH_SIZE, shuffle=True)test_loader = torch.utils.data.DataLoader(datasets.MNIST('data', train=False, transform=transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.1307,), (0.3081,))])),batch_size=BATCH_SIZE, shuffle=True)
train_dataset = TensorDataset(X_train, y_train)
train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)test_dataset = TensorDataset(X_test, y_test)
test_loader = DataLoader(test_dataset, batch_size=batch_size, shuffle=False)

DataLoader是划分迭代器的函数,传入dataset(所有数据),就可以划分出大小为batch_size的样本批量。shuffle是选择是否随机打乱的参数。


http://www.ppmy.cn/embedded/149421.html

相关文章

python实战案例笔记:统计出数据中路劲下没有文件的文件夹

数据样例:👇有如下excel数据 需求:有如下excel,a.xls,统计出路劲下没有文件的路劲 详细实现代码: import os from openpyxl import Workbook from datetime import datetimedef get_empty_dirs(paths):# …

小米加速AI布局,搭建GPU万卡集群,近屿智能带您走近AI大模型

小米公司近期宣布正在加速构建GPU万卡集群,这一举措标志着小米在AI大模型领域的战略升级。据内部人士透露,该计划已在雷军的领导下秘密推进数月。雷军指出,在AI硬件的发展中,手机才是核心,小米在这一领域的全面投入是战…

Git在软件开发中的核心作用:如何利用Git进行版本控制和团队协作?

在当今数字化时代,软件开发项目日益复杂,团队协作的紧密程度和效率对于项目的成功交付起着至关重要的作用。而Git,作为一款强大的分布式版本控制系统,已经成为软件开发领域不可或缺的工具。它不仅能够帮助开发者高效地管理代码版本…

【软件工程】十万字知识点梳理 | 期末复习专用

原创文章,禁止转载。 文章目录 图CRC卡片用例图类图状态图活动图泳道图软件质量因素自顶向下集成自底向上集成人员与工作量之间的关系时序图关键路径软件结构基本路径测试判定表数据流图(DFD)体系结构设计问题数据字典挣值分析等价划分程序流程图PAD | N-S燃尽图甘特图对象模…

MySQL Workbench菜单汉化为中文

默认情况下,安装完成的MySQL Workbench的菜单为英文,今天介绍一个简单易操作的方法,将MySQL Workbench菜单汉化为中文。 一、查找MySQL Workbench菜单标记文件main_menu.xml 1. 默认情况下,MySQL Workbench的安装路径为&#xff…

VSCode使用deepseek-v3

2024年12月27日,deekseep-v3发布了。顶级benchmark和实用体验,显著降低的训练成本,注册后免费送token额度。很诱人。 生成 deepseek-v3 API https://www.deepseek.com/ https://platform.deepseek.com/usage 创建一个新的 api key VSCo…

智能家居常用的无线通信协议及其特点

以下是智能家居常用的无线通信协议及其特点对比表: 无线协议主要特点优点缺点典型应用场景Wi-Fi使用无线局域网 (2.4GHz/5GHz),速度快,传输距离较远- 传输速率高- 网络覆盖广- 可直接与互联网连接- 功耗较高- 网络拥堵可能性大- 需要路由器支…

Centos7中使用yum命令时候报错 “Could not resolve host: mirrorlist.centos.org; 未知的错误“

2024.06.30之后,在Centos 7 中使用 yum 命令报错,如下: 已加载插件:fastestmirror Determining fastest mirrors Could not retrieve mirrorlist http://mirrorlist.centos.org/?release7&archx86_64&repoos&infras…