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

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

实验大概是使用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.mzph.cn/diannao/65241.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

c++编译过程初识

编译过程 预处理:主要是执行一些预处理指令,主要是#开头的代码,如#include 的头文件、#define 定义的宏常量、#ifdef #ifndef #endif等条件编译的代码,具体包括查找头文件、进行宏替换、根据条件编译等操作。 g -E example.cpp -…

Springboot高并发乐观锁

Spring Boot分布式锁的主要缺点包括但不限于以下几点: 性能开销:使用分布式锁通常涉及到网络通信,这会引入额外的延迟和性能开销。例如,当使用Redis或Zookeeper实现分布式锁时,每次获取或释放锁都需要与这些服务进行交…

揭秘 Fluss 架构组件

这是 Fluss 系列的第四篇文章了,我们先回顾一下前面三篇文章主要说了哪些内容。 Fluss 部署,带领大家部署Fluss 环境,体验一下 Fluss 的功能Fluss 整合数据湖的操作,体验Fluss 与数据湖的结合讲解了 Fluss、Kafka、Paimon 之间的…

leetcode82:删除链表中的重复元素II

原题地址:82. 删除排序链表中的重复元素 II - 力扣(LeetCode) 题目描述 给定一个已排序的链表的头 head , 删除原始链表中所有重复数字的节点,只留下不同的数字 。返回 已排序的链表 。 示例 1: 输入&…

【面试经典】多数元素

链接:169. 多数元素 - 力扣(LeetCode) 解题思路: 在本文中,“数组中出现次数超过一半的数字” 被称为 “众数” 。 需要注意的是,数学中众数的定义为 “数组中出现次数最多的数字” ,与本文定…

AT24C02学习笔记

看手册: AT24Cxx xx代表能写入xxK bit(xx K)/8 byte 内部写周期很关键,代表每一次页写或字节写结束后时间要大于5ms(延时5ms确保完成写周期),否则时序会出错。 页写:型不同号每一页可能写入不同大小的…

蓝牙BLE开发——解决iOS设备获取MAC方式

解决iOS设备获取MAC方式 uniapp 解决 iOS 获取 MAC地址,在Android、iOS不同端中互通,根据MAC 地址处理相关的业务场景; 文章目录 解决iOS设备获取MAC方式监听寻找到新设备的事件BLE工具效果图APP监听设备返回数据解决方式ArrayBuffer转16进制…

01 Oracle 基本操作

Oracle 基本操作 初使用步骤 1.创建表空间 2.创建用户、设置密码、指定表空间 3.给用户授权 4.切换用户登录 5.创建表 注意点:oracle中管理表的基本单位是用户 文章目录 了解Oracle体系结构 1.创建表空间**2.删除表空间**3.创建用户4.给用户授权5.切换用户登录6.表操…

【Linux命令】ps -a 和 ps -ef 的区别

ps -a 和 ps -ef 是 ps(process status)命令的不同选项,它们用于显示不同的进程信息。以下是这两个选项的主要区别: ps -a -a 选项表示显示所有拥有终端的进程,但不包括守护进程(daemon processes&#x…

独一无二,万字详谈——Linux之文件管理

Linux文件部分的学习,有这一篇的博客足矣! 目录 一、文件的命名规则 1、可以使用哪些字符? 2、文件名的长度 3、Linux文件名的大小写 4、Linux文件扩展名 二、文件管理命令 1、目录的创建/删除 (1)、目录的创建 ① mkdir…

rust windwos 两个edit框

use winapi::shared::minwindef::LOWORD; use windows::{core::*,Win32::{Foundation::*,Graphics::Gdi::{BeginPaint, EndPaint, PAINTSTRUCT},System::LibraryLoader::GetModuleHandleA,UI::WindowsAndMessaging::*,}, };// 两个全局静态变量,用于保存 Edit 控件的…

解锁成长密码:探寻刻意练习之道

刻意练习,真有那么神? 在生活中,你是否有过这样的困惑:每天苦练英语口语,可一到交流时还是支支吾吾;埋头苦学吉他,却总是卡在几个和弦转换上;工作多年,业务能力却似乎陷入…

WPS中如何为指定区域的表格添加行或者列,同时不影响其它表格?

大家好,我是小鱼。 日常工作中会遇到这种情况:在一个Excel工作表中有多个表格,因为后期数据量增加就需要为指定区域的表格添加行或者列,但是不能影响其它表格。这种情况下我们应该怎么操作呢? 为指定区域的表格添加行…

Gitlab17.7+Jenkins2.4.91实现Fastapi项目持续发布版本详细操作(亲测可用)

一、gitlab设置: 1、进入gitlab选择主页在左侧菜单的下面点击管理员按钮。 2、选择左侧菜单的设置,选择网络,在右侧选择出站请求后选择允许来自webhooks和集成对本地网络的请求 3、webhook设置 进入你自己的项目选择左侧菜单的设置&#xff…

模型工作流:自动化的模型内部三角面剔除

1. 关于自动减面 1.1 自动减面的重要性及现状 三维模型是游戏、三维家居设计、数字孪生、VR/AR等几乎所有三维软件的核心资产,模型的质量和性能从根本上决定了三维软件的画面效果和渲染性能。其中,模型减面工作是同时关乎质量和性能这两个要素的重要工…

Unity微信小游戏接入开放数据域

demo地址:https://github.com/wechat-miniprogram/minigame-unity-webgl-transform/tree/main/Demo/Ranking 官方说明: https://github.com/wechat-miniprogram/minigame-unity-webgl-transform/blob/main/Design/OpenData.md 准备一个Canvas&#xff0c…

如何实现 MySQL 的读写分离?

面试题 你们有没有做 MySQL 读写分离?如何实现 MySQL 的读写分离?MySQL 主从复制原理的是啥?如何解决 MySQL 主从同步的延时问题? 面试官心理分析 高并发这个阶段,肯定是需要做读写分离的,啥意思&#x…

go window安装protoc protoc生成protobuf文件

1. 下载: Releases protocolbuffers/protobuf GitHub 2. 解压缩: 3. 配置环境变量: 选择系统变量->Path -> 新增 解压缩后的bin路径 4. 打印版本: protoc --version 5. 安装protoc-gen-go cmd 下输入安装命令&#xff0…

C#-调用C++接口

一.静态&动态装载DLL C中接口通过编译为DLL对外提供调用,C#需要将DLL加载至本应用才可实现C接口调用. 1.静态装载 C#应用程序在编译为可执行exe时将外部DLL装载至本应用中,例如在CSC编译指令中添加相关参数可实现DLL引用. csc /reference:user32.dll /out:HelloWorld.exe 2…

学习C++:标识符命名规则

标识符命名规则: 作用:C规定给标识符(变量、常量)命名时,有一套自己的规则 标识符不能是关键字 标识符只能由字母、数字、下划线组成 第一个字符必须为字母或下划线 标识符中字母区分大小写 (给标识符命…