首页 > 其他分享 >从零开始的Pytorch【02】:构建你的第一个神经网络

从零开始的Pytorch【02】:构建你的第一个神经网络

时间:2024-08-26 21:27:06浏览次数:6  
标签:02 训练 0.0 模型 神经网络 Pytorch 从零开始 self 神经元

从零开始的Pytorch【02】:构建你的第一个神经网络

前言

欢迎来到PyTorch学习系列的第二篇!在上一篇文章中,我们介绍了PyTorch的基本概念,包括张量、自动求导和Jupyter Notebook的使用。在这篇文章中,我们将继续深入,指导你如何使用PyTorch构建一个简单的神经网络并进行训练。这将是你迈向深度学习应用的第一步。

什么是神经网络?

神经网络(Neural Network)是深度学习的核心,它模仿了人类大脑的神经元结构来处理和分析数据。一个典型的神经网络由多个层(layers)组成,每层包含若干个神经元(neurons),通过权重(weights)和偏置(biases)相连接。神经网络的目的是通过调整这些权重和偏置,使得输入数据通过网络后得到的输出接近于预期结果。

在本教程中,我们将构建一个简单的前馈神经网络(Feedforward Neural Network),并使用它来处理一个二分类问题。

构建一个简单的神经网络

首先,我们需要导入PyTorch库,并定义我们要使用的网络模型。这里我们将使用PyTorch的torch.nn模块,该模块提供了许多构建神经网络的基础工具。

import torch
import torch.nn as nn
import torch.optim as optim
import torch.nn.functional as F

# 定义一个简单的神经网络类
class SimpleNN(nn.Module):
    def __init__(self):
        super(SimpleNN, self).__init__()
        # 定义输入层到隐藏层的全连接层
        self.fc1 = nn.Linear(2, 10)
        # 定义隐藏层到输出层的全连接层
        self.fc2 = nn.Linear(10, 1)

    def forward(self, x):
        # 使用ReLU激活函数处理输入层到隐藏层
        x = F.relu(self.fc1(x))
        # 使用Sigmoid激活函数处理隐藏层到输出层
        x = torch.sigmoid(self.fc2(x))
        return x

# 创建模型实例
model = SimpleNN()

解析:

  1. 定义网络结构:我们使用nn.Module类定义了一个简单的神经网络模型。fc1是从输入层到隐藏层的全连接层,fc2是从隐藏层到输出层的全连接层。
  2. 前向传播:在forward方法中,我们定义了数据如何通过网络传播。这里我们使用了ReLU激活函数(用于隐藏层)和Sigmoid激活函数(用于输出层)。
  3. 创建模型实例:最后,我们创建了一个SimpleNN模型的实例。
准备训练数据

接下来,我们需要为模型准备训练数据。在这个示例中,我们使用一个简单的二分类数据集,其中每个输入有两个特征,输出为0或1。

# 准备训练数据
data = torch.tensor([[0.0, 0.0], [0.0, 1.0], [1.0, 0.0], [1.0, 1.0]])
labels = torch.tensor([[0.0], [1.0], [1.0], [0.0]])

# 查看数据和标签
print("Data:", data)
print("Labels:", labels)

在这里插入图片描述

解析:

  • 数据集:这里的数据集data由四个二维数据点组成,每个点对应一个标签labels。这个数据集表示了一个简单的逻辑异或(XOR)问题。
定义损失函数和优化器

在训练神经网络时,我们需要定义一个损失函数来衡量模型的预测与实际标签之间的差异。我们还需要定义一个优化器来更新模型的权重,使损失最小化。

# 定义损失函数和优化器
criterion = nn.BCELoss()  # 二分类交叉熵损失函数
optimizer = optim.SGD(model.parameters(), lr=0.1)  # 随机梯度下降优化器,学习率为0.1

解析:

  • 损失函数:我们使用BCELoss,即二分类交叉熵损失函数,它非常适合处理二分类问题。
  • 优化器:我们使用随机梯度下降(SGD)优化器,并设置学习率lr为0.1。
训练神经网络

接下来,我们将训练神经网络。训练过程包括前向传播(计算预测值)、计算损失、反向传播(计算梯度),以及更新权重。我们将这个过程循环多次,直到模型的性能达到满意的水平。

# 训练神经网络
num_epochs = 1000  # 训练迭代次数

for epoch in range(num_epochs):
    # 前向传播
    outputs = model(data)
    loss = criterion(outputs, labels)
    
    # 反向传播和优化
    optimizer.zero_grad()  # 清除梯度缓存
    loss.backward()  # 计算梯度
    optimizer.step()  # 更新权重
    
    if (epoch+1) % 100 == 0:
        print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item():.4f}')

在这里插入图片描述

在训练的1000个epoch中,模型的损失函数值从最初的0.5077下降到0.0122,显示出模型的预测误差在逐渐减少,性能逐步提高。以下是训练过程中的一些关键点:

  • Epoch [100/1000]: Loss = 0.5077
  • Epoch [200/1000]: Loss = 0.2628
  • Epoch [500/1000]: Loss = 0.0420
  • Epoch [1000/1000]: Loss = 0.0122

训练日志表明,随着训练的进行,损失值显著下降。这表明通过反复的训练迭代,模型成功学习到了数据的特征,并优化了权重,使得预测结果更加准确。

模型评估

训练完成后,我们可以使用模型对新数据进行预测,并评估其性能。

# 测试模型
with torch.no_grad():  # 关闭梯度计算
    test_data = torch.tensor([[1.0, 0.0], [0.0, 0.0]])
    predictions = model(test_data)
    print("Test Data:", test_data)
    print("Predictions:", predictions)

测试模型时,输入两个测试数据点:[1.0, 0.0][0.0, 0.0],模型给出的预测结果如下:

  • 对于输入 [1.0, 0.0],预测值为 0.9898,接近于1,表示模型认为该输入属于标签为1的类别。
  • 对于输入 [0.0, 0.0],预测值为 0.0169,接近于0,表示模型认为该输入属于标签为0的类别。

在这里插入图片描述

通过这些测试结果可以看出,模型能够对训练数据进行合理预测,说明模型在训练后能够拟合训练数据,出于数据集的问题,暂时不能有新数据来证明其泛化能力。

探索性分析:对数据集的调整

我们可以干一件有意思的事情,对原始数据集进行修改,去掉一个数据点,看看其对整体性能的影响如何,不妨去掉[1.0, 0.0]

# 准备训练数据
data = torch.tensor([[0.0, 0.0], [0.0, 1.0], [1.0, 1.0]])
labels = torch.tensor([[0.0], [1.0], [0.0]])

# 查看数据和标签
print("Data:", data)
print("Labels:", labels)

其他因素均保持不变,我们看看效果如何:

在这里插入图片描述
在这里插入图片描述
训练日志显示,模型的损失函数值在1000个epoch内从0.0097下降到了0.0027,表现出稳定的训练过程。然而,由于数据集中移除了一个关键数据点,模型的表现能力有所下降。

在测试阶段,我们使用原本被移除的数据点 [1.0, 0.0] 以及其他数据进行评估,结果如下:

对于输入 [1.0, 0.0],预测值为 0.9289,虽然接近1,但与先前的模型相比稍微下降,表明模型的准确性受到了数据移除的影响。
对于输入 [0.0, 0.0],预测值为 0.0034,仍然接近于0,显示出模型在此数据点上的良好表现。

通过这次实验可以看到,尽管模型在训练集上的损失值继续降低,但在面对未见过的数据点时,预测结果有所偏差,说明模型的表现能力受到了影响,但是这个在新数据中的表现,往往能正确反应模型的泛化能力。这也提示我们,数据的完整性在模型训练中的重要性。

探索性的调整:增加隐藏层与神经元数量

在完成了基础网络的训练后,我们可以进行一些探索性的调整,看看这些调整对模型性能的影响。我们可以尝试:

  1. 增加隐藏层:在模型中引入更多的隐藏层。
  2. 改变神经元数量:在每一层中增加或减少神经元的数量。
增加隐藏层

我们可以增加一个新的隐藏层,看其对模型的影响:

class DeeperNN(nn.Module):
    def __init__(self):
        super(DeeperNN, self).__init__()
        # 第一层,全连接层,输入2个特征,输出10个神经元
        self.fc1 = nn.Linear(2, 10)
        # 第二层,新增的隐藏层,10个神经元输入,10个神经元输出
        self.fc2 = nn.Linear(10, 10)
        # 输出层,全连接层,10个神经元输入,1个输出
        self.fc3 = nn.Linear(10, 1)

    def forward(self, x):
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))  # 新增隐藏层的激活函数
        x = torch.sigmoid(self.fc3(x))
        return x

训练这个更深的模型,你可能会发现:

  • 准确性提升:更多的隐藏层能够使模型捕获到更复杂的模式,从而提升预测准确性。
  • 训练时间增加:引入更多的层意味着更多的计算量,训练时间相应增加。
改变神经元数量

我们也可以通过调整每层中的神经元数量来优化模型的性能。例如,将隐藏层的神经元数量从10增加到50:

class WiderNN(nn

.Module):
    def __init__(self):
        super(WiderNN, self).__init__()
        self.fc1 = nn.Linear(2, 50)  # 增加隐藏层的神经元数量
        self.fc2 = nn.Linear(50, 1)

    def forward(self, x):
        x = F.relu(self.fc1(x))
        x = torch.sigmoid(self.fc2(x))
        return x

这种调整的效果可能包括:

  • 准确性提升:更多的神经元可以让模型拥有更大的表示能力。
  • 过拟合风险:如果神经元数量过多,模型可能会过拟合训练数据,对新数据的泛化能力下降。
  • 训练时间增加:更多的神经元需要更多的计算资源,训练时间会相应增加。

结果对比与总结

通过增加隐藏层和调整神经元数量,我们可以探索不同网络结构对模型性能的影响。

  • 增加隐藏层可以提升模型对复杂模式的捕获能力,但也增加了训练时间。
  • 增加每层的神经元数量可以提高模型的表示能力,但也可能导致过拟合,尤其是在数据量较小的情况下。

在实际应用中,选择网络结构时需要权衡模型的准确性和训练时间,并注意避免过拟合。通过这些探索,你将对神经网络的设计有更深的理解,并能更有效地应用PyTorch构建复杂的深度学习模型。

小结

在这篇文章中,我们构建了一个简单的神经网络,并通过实验探索了数据集的改变,增加隐藏层和调整神经元数量对模型性能的影响。希望这些探索能帮助你更好地理解神经网络结构设计的要点,为今后的深度学习实践打下坚实基础。

下一篇文章中,我们将深入探讨如何使用更高级的PyTorch功能来提升模型性能。敬请期待!

课后练习

为了巩固今天的学习内容,建议你尝试以下练习:

  1. 尝试不同数量的隐藏层,并观察对模型准确性和训练时间的影响。
  2. 尝试不同的数据集,调整每层的神经元数量,观察模型是否过拟合,以及如何调整模型以避免过拟合

如果在练习过程中遇到问题,欢迎随时留言讨论。希望你能继续享受PyTorch学习的过程!

标签:02,训练,0.0,模型,神经网络,Pytorch,从零开始,self,神经元
From: https://blog.csdn.net/Lewiz_124/article/details/141572652

相关文章

  • OUC 2024夏 移动软件开发 实验一:第一个微信小程序
    一、实验准备课程主页:课程主页(gitee.com)实验文档:lab1.pdf(gitee.com)学习视频:第一个小程序(1)bilibili.com二、实验目标1、学习使用快速启动模板创建小程序的方法;2、学习不使用模板手动创建小程序的方法。三、实验方法1、使用模板创建小程序:如下图所示,填写项目名......
  • OUC 2024夏 移动软件开发 实验三:微信小程序云开发
    一、实验准备课程主页:课程主页(gitee.com)实验文档:lab3文档实验代码:lab3代码二、实验目标学习微信小程序云开发的基础知识。能够完成利用文本搜索的功能就好,图像识别、语音识别接口有时有问题,不强求。三、实验步骤1、创建微信小程序过程见前两个lab,在此不再赘述。2......
  • 【ACM出版,快录用】2024年智能医疗与可穿戴智能设备国际学术会议(SHWID 2024, 10月18-2
    2024年智能医疗与可穿戴智能设备国际学术会议(SHWID2024)将于2024年10月18-20日在广东广州举行。本次会议主要围绕“智能医疗与可穿戴智能设备”的最新研究展开,旨在荟聚世界各地该领域的专家、学者、研究人员及相关从业人员,分享研究成果,探索热点问题,交流新的经验和技术。......
  • 题解:P9256 [PA 2022] Muzyka pop 2
    题解:P9256[PA2022]Muzykapop2题目传送门题目重点从前往后比较,和数字比较一样,如:12345<12445。如果一个串是另一个串的前缀,那么不是前缀串的那个字典序小。题目思路我爱贪心贪心就行了,每次让x增加1,找出1的个数来实现。要求序列是字典序最小的,因此每次选择尽可......
  • 动态dp——P8820 [CSP-S 2022] 数据传输 题解
    P8820[CSP-S2022]数据传输可怜的cnblog被(昨天DDos+今天CC)攻击了(望周知!),只好先发在CSDN题面:题目描述小C正在设计计算机网络中的路由系统。测试用的网络总共有nn......
  • 【CSS】从零开始学CSS第二篇:字体属性、文本属性、引入方式
    目录CSS字体属性1.1字体系列1.2字体大小1.3字体粗细1.4文字样式1.5字体复合属性1.6字体属性总结CSS文本属性2.1文本颜色2.2对齐文本2.3装饰文本2.4文本缩进2.5行间距2.6文本属性总结 CSS引入方式3.1CSS的三种样式表3.2内部样式表3.3行内......
  • 2024下半年,软考和PMP推荐考哪个?
    在项目管理领域,专业资格认证是提升个人能力、拓宽职业发展道路的重要途径。2024年下半年,面对软考(计算机技术与软件专业技术资格水平考试)和PMP(项目管理专业人士资格认证)两大热门证书,许多从业者陷入了选择的困境。本文旨在分析两者的证书价值、适合人群、考试安排,为大家提供选......
  • C#/.NET/.NET Core技术前沿周刊 | 第 2 期(2024年8.19-8.25)
    前言C#/.NET/.NETCore技术前沿周刊,你的每周技术指南针!记录、追踪C#/.NET/.NETCore领域、生态的每周最新、最实用、最有价值的技术文章、社区动态、优质项目和学习资源等。让你时刻站在技术前沿,助力技术成长与视野拓宽。欢迎投稿,推荐或自荐优质文章/项目/学习资源等。每......
  • 面试 | 30个热门PyTorch面试题助你轻松通过机器学习/深度学习面试
    前言PyTorch作为首选的深度学习框架的受欢迎程度正在持续攀升,在如今的AI顶会中,PyTorch的占比已高达80%以上!本文精心整理了关键的30个PyTorch相关面试问题,帮助你高效准备机器学习/深度学习相关岗位。基础篇问题1:什么是PyTorchPyTorch是一个开源机器学习库,用于......
  • 4款超火的U盘恢复软件,2024年一键操作,数据瞬间回
    在这个数字化的时代,数据简直太重要了。不管是工作文件、学习资料,还是那些珍贵的照片和视频,要是不小心弄丢了或者删掉了,那损失可就大了。所以,数据恢复软件就成了很多人电脑里必不可少的工具。今天,我要给大家介绍四款特别受欢迎的U盘数据恢复软件。咱们通过试用来看看,这些软件是......