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

news2024/12/28 14:27:18

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

实验大概是使用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_test

net = 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 = net

    def forward(self,X):
        out = F.log_softmax(net(X),dim=1)
        return out

def 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 = 0
    correct = 0
    with 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 = 10

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)

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_test

net = 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 = net

    def forward(self,X):
        out = F.log_softmax(net(X),dim=1)
        return out

def 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 = 0
    correct = 0
    with 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 = 10

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)

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.coloradmin.cn/o/2266959.html

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

相关文章

H5电子杂志制作工具推荐

什么样的电子杂志制作软件最好用呢?这里向大家介绍几款操作简易又稳定、功能满足工作的需求、效果非常精美大气的电子杂志制作软件。 1.FLBOOK:是一款专门为企业内刊、期刊设计的在线制作平台,用来制作企业电子期刊非常方便。它不需要下载安…

CAN201 Introduction to Networking(计算机网络)Pt.3 网络层

文章目录 4.Network Layter(网络层)4.1 Overview4.2 Router(路由器)4.3 Internet Protocol4.4 IPv4 addressing4.5 NAT(network address translation,网路地址转换)4.6 IPv64.7 Generalized For…

计算机网络——期末复习(4)协议或技术汇总、思维导图

思维导图 协议与技术 物理层通信协议:曼彻斯特编码链路层通信协议:CSMA/CD (1)停止-等待协议(属于自动请求重传ARQ协议):确认、否认、重传、超时重传、 (2)回退N帧协…

uniapp中Nvue白屏问题 ReferenceError: require is not defined

uniapp控制台输出如下 exception function:createInstanceContext, exception:white screen cause create instanceContext failed,check js stack ->Uncaught ReferenceError: require is not defined 或者 exception function:createInstanceContext, exception:white s…

http 请求总结get

关于get请求传递body的问题 错误代码 有400 , 415 等情况 <!doctype html><html lang"zh"><head><title>HTTP Status 400 – 错误的请求</title><style type"text/css">body {font-family:Tahoma,Arial,sans-seri…

【微信小程序】4plus|搜索框-历史搜索 | 我的咖啡店-综合实训

升级版1-清空全部的再次确认 实现功能: 历史搜索记录展示-历史搜索记录展示10条点击跳转-点击历史搜索记录可同步到搜索框并自动搜索全部删除-可一次性全部删除历史搜索记录全部删除-有再次确认操作展示 进行搜索后留下搜索记录 点击垃圾桶图标,显示【清空全部】 点击【清…

Kubernetes 安装 Nginx以及配置自动补全

部署 Nginx &#xff1a; [rootk8s-master ~]# kubectl create deployment nginx --imagenginx:1.14-alpine deployment.apps/nginx created暴露端口&#xff1a; [rootk8s-master ~]# kubectl expose deployment nginx --port80 --typeNodePort service/nginx exposed查看服…

“库存管理软件的用户体验”:界面与交互设计

3.1可行性分析 开发者在进行开发系统之前&#xff0c;都需要进行可行性分析&#xff0c;保证该系统能够被成功开发出来。 3.1.1技术可行性 开发该库存管理软件所采用的技术是vue和MYSQL数据库。计算机专业的学生在学校期间已经比较系统的学习了很多编程方面的知识&#xff0c;同…

基于openEuler22.09部署OpenStack Yoga云平台(一)

OpenStack Yoga部署 安装OpenStack 一、基础准备 基于OpenStack经典的三节点环境进行部署&#xff0c;三个节点分别是控制节点&#xff08;controller&#xff09;、计算节点&#xff08;compute&#xff09;、存储节点&#xff08;storage&#xff09;&#xff0c;其中存储…

AutoDL服务器深度学习使用过程

前期准备 Xshell,Xftp,Pycharm专业版 step 1:实例开机&#xff08;无卡or有卡&#xff09;&#xff0c;Xshell连接 新建xshell会话&#xff1a; 登录指令格式为&#xff1a; ssh -p 38076 rootregion-1.autodl.com 在ssh -p 38076 rootregion-1.autodl.com命令中&#xff0…

【RabbitMQ的死信队列】

死信队列 什么是死信队列死信队列的配置方式死信消息结构 什么是死信队列 消息被消费者确认拒绝。消费者把requeue参数设置为true(false)&#xff0c;并且在消费后&#xff0c;向RabbitMQ返回拒绝。channel.basicReject或者channel.basicNack。消息达到预设的TTL时限还一直没有…

详解从输入url到页面渲染

当你在浏览器中输入一个 URL 并按下回车键&#xff0c;浏览器会经历一系列步骤来加载并渲染页面。这些步骤包括 DNS 解析、缓存处理、建立连接、发送请求、接收响应、解析 HTML、构建 DOM 树和 CSSOM 树、执行 JavaScript、布局和绘制等。以下是这些步骤的详细解释&#xff0c;…

从 GitLab.com 到 JihuLab.com 的迁移指南

本文分享从 GitLab.com 到 JihuLab.com 的迁移指南。 近期&#xff0c;GitLab Inc. 针对其 SaaS 产品做了限制&#xff0c;如果被判定为国内用户&#xff0c;则会建议使用其在国内的发布版本极狐GitLab。从 GitLab SaaS 产品&#xff08;GitLab.com&#xff09;迁移到极狐GitL…

AIA - IMSIC之二(附IMSIC处理流程图)

本文属于《 RISC-V指令集基础系列教程》之一,欢迎查看其它文章。 1 ​​​​​​​通过IMSIC接收外部中断的CSR 软件通过《AIA - 新增的CSR》描述的CSR来访问IMSIC。 machine level 的 CSR 与 IMSIC 的 machine level interrupt file 可相互互动;而 supervisor level 的 CSR…

Python爬虫实战(保姆级登网页信息爬取教程)

此blog为爬虫实战教学&#xff0c;代码已附上&#xff0c;可以复制运行。若要直接看实战代码翻到博客后半部分。 本文使用selenium库进行爬虫&#xff0c;实现爬取数据操作&#xff0c;此库是通过模仿用户的操作进行对页面的处理。了解了这个思维模式&#xff0c;可以对代码进…

国产三维CAD正强势崛起

CAD软件作为现代工业设计和制造领域不可或缺的核心工具&#xff0c;其重要性不言而喻。它极大地提升了设计效率与精度&#xff0c;缩短了产品开发周期&#xff0c;为企业的创新与发展注入了强大动力。随着全球市场竞争的日益激烈&#xff0c;以及当前国际局势的复杂多变&#x…

编码滤波技术-SAO

1. AVS中的SAO样值偏移自适应补偿技术&#xff0c;首先将正在处理的块往左上移动了四行四列&#xff0c;超过图像边界的部分丢弃&#xff0c;右、下图像边界部分补齐。 也就是偏移前在图像边缘的块&#xff0c;进行去除和扩展得到偏移后的块。图像内部的块&#xff0c;正常往左…

Leetcode打卡:查询数组中元素出现的位置

执行结果&#xff1a;通过 题目 3159 查询数组中元素出现的位置 给你一个整数数组 nums &#xff0c;一个整数数组 queries 和一个整数 x 。 对于每个查询 queries[i] &#xff0c;你需要找到 nums 中第 queries[i] 个 x 的位置&#xff0c;并返回它的下标。如果数组中 x 的出…

【游戏设计原理】32 - 消费者剩余

1. 如何理解消费者剩余原理&#xff1f; 消费者剩余是一种经济学概念&#xff0c;表示消费者愿意为商品支付的最大金额与实际支付金额之间的差额。 简单来说&#xff0c;消费者剩余衡量了消费者从交易中获得的“额外价值”或“剩余利益”。 在传统商业模式下&#xff0c;由于…

肝功能不正常可以过教师入职体检吗?

如何看肝功能报告单 转氨酶正常等于肝功能正常吗?要想看懂肝功能报告单就要看懂各指标含义。 1、总胆红素TbiL正常值是 1.7-17.1μmol/L 急性黄疸型肝炎活动性肝炎肝坏死、肝癌、胰头癌都异常偏高。 2、直接胆红素 DbiL正常值是 0-6.84μmol/L 结石病、肝癌、胰头癌与这项…