当前位置: 首页 > article >正文

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

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

实验大概是使用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.kler.cn/a/459401.html

相关文章:

  • net core介绍
  • 共阳极LED的控制与短路问题解析
  • 深入理解Java中的Set集合:特性、用法与常见操作指南
  • 机器人C++开源库The Robotics Library (RL)使用手册(四)
  • 虚拟机Centos下安装Mysql完整过程(图文详解)
  • 手机实时提取SIM卡打电话的信令声音-双卡手机来电如何获取哪一个卡的来电
  • Nginx 配置前端后端服务
  • 【Python实现连续学习算法】Python实现连续学习Baseline 及经典算法EWC
  • Spring Cloud Alibaba2022之Sentinel总结
  • 【GraphRAG】LEGO-GraphRAG框架解读
  • 商米电子秤服务插件
  • 华为ensp-BGP联盟
  • vue 修改vant样式NoticeBar中的图标,不用插槽可以直接用图片
  • AI与药学:ChatGPT与临床培训——药学博士(Pharm-D)学生的看法、担忧和实践
  • 《机器学习》——数据标准化(0~1标准化,z标准化)
  • 【杂谈】-艺术中的AI:作用及未来
  • C语言内存管理函数
  • [python SQLAlchemy数据库操作入门]-14.实时数据采集 记录股市动态
  • No.2十六届蓝桥杯备战|练习题4道|数据类型|字符型|整型|浮点型|布尔型|signed|unsigned(C++)
  • 下载并使用CICFlowMeter提取网络流特征(Windows版本)
  • Mac 环境 VVenC 编译与编码命令行工具使用教程
  • 英创主板ESM8400支持Debian 12桌面系统
  • CPT203 Software Engineering 软件工程 Pt.1 概论和软件过程(中英双语)
  • Python入门:8.Python中的函数
  • kanzi做3d时钟屏保
  • 【算法day27】动态规划:基础2