【D2】神经网络初步学习

总结:学习了 PyTorch 中的基本概念和常用功能,张量(Tensor)的操作、自动微分(Autograd)、正向传播、反向传播。通过了解认识LeNet 模型,定义神经网络类,熟悉卷积神经网络的基本结构和训练过程,卷积层和全连接层的创建和运用。在训练网络中,通过反向传播计算梯度,利用优化器根据计算出的梯度更新网络中的参数。--2025/02/12

目录

1. 实验环境

1.1. 导入库

1.2. 版本

2. 基本概念

2.1. Tensor 张量

2.2. Scalar 标量

2.3. Autograd 自动微分

2.3.1. 启动自动微分

2.3.2. 反向传播

2.3.3. 梯度累加和清零

3. LeNet 神经网络

3.1. 基本概念

3.1.1. torch.nn

3.1.2. nn.Module 类

3.1.3. 卷积层 (nn.Conv2d)

3.1.4. 全连接层 (nn.Linear)

3.2. 定义神经网络类 Net

3.2.1 __init__ 构造函数

3.2.2. forward 向前传播函数

3.3. 训练网络

3.3.1. 可学习参数

3.3.2. 批量处理(Mini-Batch)

3.3.3. 损失函数

3.3.4. 反向传播

3.3.5. 优化器:SGD

总结


1. 实验环境

1.1. 导入库
  • Import numpy as np: 用于处理数组和矩阵运算

    Import torch as t :pytorch的核心库,构建和训练深度学习模型

    import torch.optim as optim:pytorch的优化器模块,根据计算出的梯度更新神经网络的参数

    import torch.nn as nn:PyTorch 提供的神经网络模块,专门用于构建和训练神经网络模型

    import torch.nn.functional as F:包含函数操作,如激活函数、损失函数、卷积操作等)

1.2. 版本
  • torch:2.6.0

    Python 3.8.8

    jupyter-notebook : 6.3.0


2. 基本概念

2.1. Tensor 张量

Tensor是PyTorch中重要的数据结构,可认为是一个高维数组。它可以是一个数(标量)、一维数组(向量)、二维数组(矩阵)以及更高维的数组。

  • 标量(0 维):一个数值,例如 3.14。
  • 向量(1 维):一组有序的数值,例如 [1, 2, 3]。
  • 矩阵(2 维):一个二维的数值表格,例如 [[1, 2], [3, 4]]。
  • 高维数组(n 维):更高维的数组,用于存储更复杂的数据结构,例如图像数据(通常为 4 维:batch_size, channels, height, width)。
# 初始化一个 5x3 的张量
x = t.Tensor(5, 3)# 赋值为一个 2x2 的初始化矩阵
x = t.Tensor([[1, 2], [3, 4]])# 获取张量的行数(即第一个维度)
x.size(0)# 获取张量的列数(即第二个维度)
x.size(1)# 获取列数的另一种方式
x.size()[1]# 随机生成一个 5x3 的张量
x = t.rand(5, 3)
y = t.rand(5, 3)# 三种方法来进行两个矩阵相加:
a = x + y  # 方法 1:直接相加
b = t.add(x, y)  # 方法 2:使用 PyTorch 自带的加法函数
c = t.Tensor(5, 3)  # 初始化一个空张量
t.add(x, y, out=c)  # 方法 3:将结果存储到 c 中

Tensor 与 NumPy 的转换

# 创建一个全为 1 的张量
a = t.ones(5)# 将张量转换为 NumPy 数组
b = a.numpy()# 创建一个全为 1 的 NumPy 数组
a = np.ones(5)# 将 NumPy 数组转换为张量
b = t.from_numpy(a)

2.2. Scalar 标量

Scalar(标量)是一个没有维度的单一数值,它是零维的张量。标量在 PyTorch 中通常表示为一个只有一个元素的 Tensor。

2.2.1. 获取标量值

(1) 使用 .item() 从包含单一元素的张量中提取该元素的值:

(2) 使用 .tolist() 将标量张量转换为列表:

# 使用 item() 方法获取标量值
scalar = b[0]
scalar_value = scalar.item()# 使用 tolist() 方法将标量张量转换为列表
x = t.Tensor([3.14])  # 创建一个包含单一值的张量
scalar_list = x.tolist()  # 将其转换为列表
print(scalar_list)  # 输出: [3.14]

2.3. Autograd 自动微分

深度学习中的训练过程本质上是通过反向传播求导数,而 PyTorch 提供的 autograd 模块自动为张量计算梯度,从而避免了手动计算导数的复杂过程。

2.3.1. 启动自动微分

在创建张量时,可以通过 requires_grad=True 来启动自动微分功能,表示该张量需要计算梯度。

x = t.ones(2, 2, requires_grad=True)  # 创建一个可以计算梯度的张量
2.3.2. 反向传播

反向传播通过调用 backward() 来计算梯度。以下示例展示了如何计算梯度:


2.3.3. 梯度累加和清零

在每次执行 backward() 之后,PyTorch 会将梯度值累加,因此每次反向传播之前需要手动清零梯度。

#清零梯度,以下划线结束的函数是inplace操作,修改自身的值
x.grad.zero_()


3. LeNet 神经网络

LeNet 是一种经典的卷积神经网络(CNN)结构,广泛应用于图像分类任务。LeNet 模型通常由两个卷积层、两个池化层以及三个全连接层组成。

3.1. 基本概念
3.1.1. torch.nn

torch.nn 是 PyTorch 中专门为构建神经网络设计的模块,封装了构建和训练神经网络所需的大量工具,包括各种层(如卷积层、全连接层、激活函数等)和常用的操作(如损失函数、优化器等)。

3.1.2. nn.Module

nn.Moduletorch.nn 中最重要的类,所有的神经网络模型都应该继承自 nn.Module。我们可以通过继承 nn.Module 来定义自己的网络模型。在继承 nn.Module 时,需要定义以下两个方法:

  • __init__:用于定义模型的结构,初始化网络的各个层。
  • forward:定义前向传播,描述数据如何通过网络流动。
3.1.3. 卷积层 (nn.Conv2d)

卷积层用于从输入数据中提取空间特征nn.Conv2d 用于定义二维卷积层。它的常用参数包括:

  • in_channels:输入数据的通道数(例如,RGB图像的通道数为3,灰度图像为1)。
  • out_channels:卷积层输出的通道数(卷积核的数量)。
  • kernel_size:卷积核的大小,通常是一个整数或元组(height, width)。

# 卷积层 '1'表示输入通道数为1→灰度图像, '6'表示输出通道数→卷积核的数量,'5'表示卷积核为5*5
self.conv1 = nn.Conv2d(1, 6, 5) 
# 卷积层
self.conv2 = nn.Conv2d(6, 16, 5) 

3.1.4. 全连接层 (nn.Linear)

全连接层是神经网络中非常重要的一部分,主要用于将提取到的特征映射到最终的输出。nn.Linear 定义了一个全连接层,其常用参数为:

  • in_features:输入特征的数量。
  • out_features:输出特征的数量。

  # 仿射层/全连接层,y = Wx + b
        #16*5*5是卷积层输出的特征图像展平后的维度,表示每个样本通过卷积层处理后的大小。
        self.fc1   = nn.Linear(16*5*5, 120) 
        #120,84,10全连接层的输出维度。10表示模型的预测类别数。10类
        self.fc2   = nn.Linear(120, 84)
        self.fc3   = nn.Linear(84, 10)

3.2. 定义神经网络类 Net
import torch.nn as nn
import torch.nn.functional as F
#包含常见函数,比如激活函数relu,池化操作maxpool
class Net(nn.Module):#定义神经网络类Net,继承于nn.Moduledef __init__(self):#定义构造函数,用来定义网络各个层super(Net, self).__init__()#调用父类nn.module的构造函数# 卷积层 '1'表示输入图片为单通道的灰度图像, '6'表示输出通道数,'5'表示卷积核为5*5self.conv1 = nn.Conv2d(1, 6, 5) # 卷积层self.conv2 = nn.Conv2d(6, 16, 5) # 仿射层/全连接层,y = Wx + b#16*5*5是卷积层输出的特征图像展平后的维度,表示每个样本通过卷积层处理后的大小。self.fc1   = nn.Linear(16*5*5, 120) #120,84,10全连接层的输出维度。10表示模型的预测类别数。10类self.fc2   = nn.Linear(120, 84)self.fc3   = nn.Linear(84, 10)def forward(self, x): #定义向前传播# 卷积 -> 激活函数(ReLU) -> 池化(MaxPool)x = F.max_pool2d(F.relu(self.conv1(x)), (2, 2))#self.conv1(x):通过卷积层conv1,将输入x进行卷积操作#F.relu():relu激活函数,将输入的负值变为0,正值不变。#F.max_pool2d(...,(2,2)):最大池化操作,池化窗口大小2*2x = F.max_pool2d(F.relu(self.conv2(x)), 2) # reshape,展平数据,输入全连接层,‘-1’表示自适应x = x.view(x.size()[0], -1) #展平的数据进入全连接层,relu激活函数增加非线性#最后一层输出类别的预测值x = F.relu(self.fc1(x))x = F.relu(self.fc2(x))x = self.fc3(x)        return x
#创建Net对象,神经网络
net = Net()
#打印出网络的结构显示每一层参数
print(net)
Net((conv1): Conv2d(1, 6, kernel_size=(5, 5), stride=(1, 1))(conv2): Conv2d(6, 16, kernel_size=(5, 5), stride=(1, 1))(fc1): Linear(in_features=400, out_features=120, bias=True)(fc2): Linear(in_features=120, out_features=84, bias=True)(fc3): Linear(in_features=84, out_features=10, bias=True)
)
3.2.1 __init__ 构造函数

__init__ 方法中,我们定义了网络的各个层(卷积层、池化层、全连接层)。LeNet 网络一般包含两个卷积层和三个全连接层。

3.2.2. forward 向前传播函数

forward 方法中,我们定义了数据如何在网络中流动,包括卷积、池化、激活函数、展平和全连接层的应用。

3.3. 训练网络
3.3.1. 可学习参数
  • 权重(weight):网络中的参数,决定了输入和输出之间的关系,影响每一层的输出结果。
  • 偏置(bias):每个神经元的额外参数,与权重一起决定神经元的激活值。
3.3.2. 批量处理(Mini-Batch)

批量处理mini-batch:多个样本组成的小批量.
PyTorch 的神经网络层(如卷积层)要求输入的形状是一个 4D 张量(batch_size, channels, height, width)。
只想输入一个样本,input.unsqueeze(0)将batch_size设为1

3.3.3. 损失函数
  • 损失函数:衡量网络输出(预测值)与目标值之间的差距

    均方误差 (MSE, Mean Squared Error):用于回归问题,计算预测值与真实值之间的平均平方误差。

    交叉熵损失 (Cross-Entropy Loss):用于分类问题,衡量真实标签与预测概率分布之间的差异。

3.3.4. 反向传播

反向传播包括三个步骤:

  1. 正向传播:先通过前向传播计算出模型的输出和损失。
  2. 计算梯度:然后通过反向传播计算出每个参数的梯度。梯度的绝对值较大,该参数对损失有很大影响,需要大幅调整
  3. 参数更新:使用这些梯度来调整网络的参数,使得损失最小化。
#梯度变化
print('反向传播前conv1.bias偏置的梯度')
print(net.conv1.bias.grad)# 执行一次前向传播
output = net(input)
target = t.arange(0,10).view(1,10).float()
criterion = nn.MSELoss()# 计算损失
loss = criterion(output, target)# 执行反向传播(retain_graph=True)用于保留计算图
loss.backward(retain_graph=True)# 打印反向传播后的梯度
print('反向传播后conv1.bias偏置的梯度')
print(net.conv1.bias.grad)# 如果需要继续进行其他操作,记得清零梯度
net.zero_grad()

梯度的符号(正负)表示了参数调整的方向:

负梯度:表示 如果减小 当前参数的值,损失函数会减少。当前参数的值较大,应该减少它来减小损失。
正梯度:表示 如果增大 当前参数的值,损失函数会减少。意味着当前参数的值较小,应该增加它来减小损失。

3.3.5. 优化器:SGD

主要任务是 根据反向传播计算出的梯度更新网络中的参数(如权重和偏置),从而使得损失函数逐步降低,最终达到优化目标。

SGD(随机梯度下降)优化器
SGD 是最常见的一种优化器,它的基本思路是每次使用一个 mini-batch(小批量)计算梯度,并使用这个梯度更新网络参数。

import torch.optim as optim
#SGD随机梯度下降,创建优化器,将需要优化的参数传入优化器
#指定学习率learning rate
optimizer = optim.SGD(net.parameters(),lr = 0.01)
#先梯度清零
optimizer.zero_grad()
#前向传播
output = net(input)
#计算损失函数
loss = criterion(output,target)
#反向传播
loss.backward()
#更新参数
optimizer.step()

总结

  • LeNet 网络结构:包含卷积层、池化层、全连接层。
  • nn.Moduleforward:通过继承 nn.Module 和定义 forward 方法来实现网络结构。
  • 损失函数和优化器:通过损失函数(如交叉熵损失)和优化器(如 SGD)来训练网络。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/895586.shtml

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

相关文章

DeepSeek处理自有业务的案例:让AI给你写一份小众编辑器(EverEdit)的语法着色文件

1 DeepSeek处理自有业务的案例:让AI给你写一份小众编辑器(EverEdit)的语法着色文件 1.1 背景 AI能力再强,如果不能在企业的自有业务上产生助益,那基本也是一无是处。将企业的自有业务上传到线上训练,那是脑子进水的做法&#xff…

DeepSeek教unity------MessagePack-05

动态反序列化 当调用 MessagePackSerializer.Deserialize<object> 或 MessagePackSerializer.Deserialize<dynamic> 时&#xff0c;二进制数据中存在的任何值都将被转换为基本值&#xff0c;即 bool、char、sbyte、byte、short、int、long、ushort、uint、ulong、…

C++入门之《拷贝构造函数》详解

拷贝构造函数是构造函数的一个重载 拷贝构造函数是特殊的构造函数&#xff0c;用于基于已存在对象创建新对象。比如定义一个 Person 类&#xff1a; class Person { private:std::string name;int age; public:Person(const std::string& n, int a) : name(n), age(a…

Ollama命令使用指南

Ollama 命令使用指南 Ollama 命令使用指南1. Ollama 命令概览2. Ollama 命令详解2.1 启动 Ollama2.2 创建模型2.3 查看模型信息2.4 运行模型2.5 停止运行的模型2.6 从注册表拉取模型2.7 推送模型到注册表2.8 列出本地模型2.9 查看正在运行的模型2.10 复制模型2.11 删除模型 3. …

为什么配置Redis时候要序列化配置呢

序列化和反序列化&#xff1f;&#xff1a; 序列化&#xff1a;将对象转换为二进制数据&#xff0c;以便存储到Redis中。 反序列化&#xff1a;将Redis中的二进制数据转换回对象&#xff0c;以便在应用程序中使用。 1. 默认序列化器的问题 如果不配置序列化器&#xff0c;Re…

【问】强学如何支持 迁移学习呢?

案例&#xff1a;从CartPole-v1迁移到MountainCar-v0 在源环境&#xff08;CartPole-v1&#xff09;中训练模型 首先&#xff0c;我们使用DQN算法在CartPole-v1环境中训练一个强化学习模型。以下是代码示例&#xff1a; import gym import torch import torch.nn as nn impor…

深入浅出Java反射:掌握动态编程的艺术

小程一言反射何为反射反射核心类反射的基本使用获取Class对象创建对象调用方法访问字段 示例程序应用场景优缺点分析优点缺点 注意 再深入一些反射与泛型反射与注解反射与动态代理反射与类加载器 结语 小程一言 本专栏是对Java知识点的总结。在学习Java的过程中&#xff0c;学习…

【算法与数据结构】并查集详解+题目

目录 一&#xff0c;什么是并查集 二&#xff0c;并查集的结构 三&#xff0c;并查集的代码实现 1&#xff0c;并查集的大致结构和初始化 2&#xff0c;find操作 3&#xff0c;Union操作 4&#xff0c;优化 小结&#xff1a; 四&#xff0c;并查集的应用场景 省份…

C语言简单练习题

文章目录 练习题一、计算n的阶乘bool类型 二、计算1!2!3!...10!三、计算数组arr中的元素个数二分法查找 四、动态打印字符Sleep()ms延时函数system("cls")清屏函数 五、模拟用户登录strcmp()函数 六、猜数字小游戏产生一个随机数randsrandRAND_MAX时间戳time() 示例 …

ShenNiusModularity项目源码学习(8:数据库操作)

ShenNiusModularity项目使用SqlSugar操作数据库。在ShenNius.Repository项目中定义了ServiceCollectionExtensions.AddSqlsugarSetup函数注册SqlSugar服务&#xff0c;并在ShenNius.Admin.API项目的ShenniusAdminApiModule.OnConfigureServices函数中调用&#xff0c;SqlSugar所…

MATLAB图像处理:图像特征概念及提取方法HOG、SIFT

图像特征是计算机视觉中用于描述图像内容的关键信息&#xff0c;其提取质量直接影响后续的目标检测、分类和匹配等任务性能。本文将系统解析 全局与局部特征的核心概念&#xff0c;深入讲解 HOG&#xff08;方向梯度直方图&#xff09;与SIFT&#xff08;尺度不变特征变换&…

java枚举类型的查找

AllArgsConstructor Getter public enum FileFilterRangeEnum {FILE_NAME("文件名称","fileName"),FILE_CONTENT("文件内容","fileContent");private final String text;private final String value;// 根据传入的字符串值查找对应的枚…

小白win10安装并配置yt-dlp

需要yt-dlp和ffmpeg 注意存放路径最好都是全英文 win10安装并配置yt-dlp 一、下载1.下载yt-dlp2. fffmpeg下载 二、配置环境三、cmd操作四、yt-dlp下视频操作 一、下载 1.下载yt-dlp yt-dlp地址 找到win的压缩包点下载&#xff0c;并解压 2. fffmpeg下载 ffmpeg官方下载 …

【技术解析】MultiPatchFormer:多尺度时间序列预测的全新突破

今天给我大家带来一篇最新的时间序列预测论文——MultiPatchFormer。这篇论文提出了一种基于Transformer的创新模型&#xff0c;旨在解决时间序列预测中的关键挑战&#xff0c;特别是在处理多尺度时间依赖性和复杂通道间相关性时的难题。MultiPatchFormer通过引入一维卷积技术&…

145,【5】 buuctf web [GWCTF 2019]mypassword

进入靶场 修改了url后才到了注册页面 注测后再登录 查看源码 都点进去看看 有个反馈页面 再查看源码 又有收获 // 检查$feedback是否为数组 if (is_array($feedback)) {// 如果是数组&#xff0c;弹出提示框提示反馈不合法echo "<script>alert(反馈不合法);<…

CTF-WEB: 利用iframe标签利用xss,waf过滤后再转换漏洞-- N1ctf Junior display

核心逻辑 // 获取 URL 查询参数的值 function getQueryParam(param) { // 使用 URLSearchParams 从 URL 查询字符串中提取参数 const urlParams new URLSearchParams(window.location.search); // 返回查询参数的值 return urlParams.get(param); } // 使用 DOMPuri…

晶闸管主要参数分析与损耗计算

1. 主要参数 断态正向可重复峰值电压 :是晶闸管在不损坏的情况下能够承受的正向最大阻断电压。断态正向不可重复峰值电压 :是晶闸管只有一次可以超过的正向最大阻断电压,一旦晶闸管超过此值就会损坏,一般情况下 反向可重复峰值电压 :是指晶闸管在不损坏的情况下能够承受的…

el-select 设置宽度 没效果

想实现下面的效果&#xff0c;一行两个&#xff0c;充满el-col12 然后设置了 width100%,当时一直没有效果 解决原因&#xff1a; el-form 添加了 inline 所以删除inline属性 即可

Python创建FastApi项目模板

1. 项目结构规范 myproject/ ├── app/ │ ├── core/ # 核心配置 │ │ ├── config.py # 环境配置 │ │ └── security.py # 安全配置 │ ├── routers/ # 路由模块 │ │ └── users.py # 用户路由 │ ├…

面试完整回答:SQL 分页查询中 limit 500000,10和 limit 10 速度一样快吗?

首先&#xff1a;在 SQL 分页查询中&#xff0c;LIMIT 500000, 10 和 LIMIT 10 的速度不会一样快&#xff0c;以下是原因和优化建议&#xff1a; 性能差异的原因 LIMIT 10&#xff1a; 只需要扫描前 10 条记录&#xff0c;然后返回结果。 性能非常高&#xff0c;因为数据库只…