- Java锁的逻辑(结合对象头和ObjectMonitor)
- 还在用饼状图?来瞧瞧这些炫酷的百分比可视化新图形(附代码实现)⛵
- 自动注册实体类到EntityFrameworkCore上下文,并适配ABP及ABPVNext
- 基于Sklearn机器学习代码实战
基于 torch.nn 搭建神经网络的基础教程大纲:
在我们开始深入探讨 torch.nn 之前,我们首先需要理解PyTorch及其神经网络库的基础知识。这一部分的内容将帮助你对PyTorch有一个整体的了解.
torch.nn
概述 torch.nn
是PyTorch中的核心库,用于建立和训练神经网络。它提供了层、损失函数和优化器等所有必要的组件。 torch.nn
中,一切都是模块。这包括单独的层(例如 nn.Linear
或 nn.Conv2d
)以及整个神经网络模型。 torch.nn
为参数管理和优化提供了简单的工具。 这只是一个引入的简要描述。PyTorch提供了一个非常强大且易于使用的接口,但要完全掌握它,理解其背后的核心概念是关键。在接下来的部分中,我们将逐步探讨如何使用 torch.nn 构建、训练和优化神经网络.
Tensor是PyTorch的基础数据结构,与NumPy数组类似。但Tensor提供了一些额外的功能,尤其是GPU加速计算和自动梯度计算.
Tensor是一个多维数组。在物理学中,“张量”是一个可以表示多种数据(如标量、向量、矩阵等)的数学对象,而在PyTorch和其他深度学习框架中,它主要指代多维数据数组.
- 核心数据结构 :在PyTorch中,Tensor是最基础的数据结构,被用于表示神经网络中的输入、输出、参数等所有数据。
- 计算图和自动微分 :Tensors是PyTorch自动微分(如梯度计算)的关键,允许自动计算神经网络中的梯度。
维度 。
:Tensor的维度描述了它有多少级别的数组。例如,标量是0维Tensor,向量是1维Tensor,矩阵是2维Tensor,以此类推.
- 标量(0D Tensor):单个数值,例如
torch.tensor(7)
- 向量(1D Tensor):数值序列,例如
torch.tensor([1, 2, 3])
- 矩阵(2D Tensor):数值网格,例如
torch.tensor([[1, 2], [3, 4], [5, 6]])
- 更高维度:例如,一个彩色图片可以被看作是一个3D Tensor(高、宽、颜色通道)。
形状 :Tensor的形状是一个描述每个维度大小的元组。例如,一个3x3的矩阵的形状是(3, 3)。可以使用 tensor.shape 或 tensor.size() 查看Tensor的形状.
Tensors可以包含不同类型的数据:
- 浮点型 :例如
torch.float32
(或torch.float
),torch.float64
(或torch.double
)- 整型 :例如
torch.int8
,torch.int16
,torch.int32
(或torch.int
),torch.int64
(或torch.long
)- 布尔型 :
torch.bool
- 其他 :例如
torch.complex64
,torch.complex128
使用 tensor.dtype 属性可以查看Tensor的数据类型,而创建Tensor时可以使用 dtype 参数来指定数据类型.
torch.tensor()
, torch.as_tensor()
torch.zeros()
, torch.ones()
, torch.rand()
, torch.randn()
torch.from_numpy()
view()
, reshape()
, squeeze()
, unsqueeze()
sum()
, mean()
, max()
, min()
numpy()
from_numpy()
to()
, cuda()
, cpu()
is_cuda
requires_grad
属性 backward()
grad
属性 了解Tensor的基础知识是使用PyTorch进行深度学习的关键。在接下来的部分中,我们将学习如何使用这些基础知识来构建和优化神经网络模型.
autograd
在深度学习中,梯度计算是关键的,因为它们用于更新神经网络的权重和偏置。PyTorch的 autograd 包为这种梯度计算提供了自动化工具.
autograd
会建立一个所谓的“计算图”来跟踪哪些操作和数据是相关的。 使用 requires_grad 参数:创建Tensor时,可以使用 requires_grad=True 来指示PyTorch应该跟踪此Tensor上的所有操作,并允许其计算梯度.
x = torch.tensor([1, 2, 3], dtype=torch.float32, requires_grad=True)
当完成了计算(通常是神经网络的前向传播),并得到一个输出值(通常是损失)后,可以调用该值的 .backward() 方法来自动计算所有 requires_grad=True 的Tensors的梯度.
y = x * x
z = y.sum()
z.backward() # 这会计算z关于x的梯度
用 .grad 属性查看梯度:
print(x.grad) # 这会显示x的梯度
梯度累加:注意,每次调用 .backward() 时,梯度都会累加,而不是被替换。这是为了支持RNN等模型的特定情况。如果需要,可以使用 .zero_() 方法清除累积的梯度.
detach()
和 no_grad()
detach 方法 :创建一个与当前Tensor内容相同但不需要梯度的新Tensor.
detached_x = x.detach()
torch.no_grad() 上下文 :在此上下文中执行的任何操作都不会被跟踪,通常在评估模型时使用这个上下文,因为在这种情况下我们不需要梯度.
with torch.no_grad():
y = x + 2
autograd 是PyTorch中非常强大的工具,使得手动计算复杂的梯度成为过去。了解其工作原理和如何使用它是进行有效深度学习的关键.
在PyTorch中,神经网络是使用 torch.nn 包构建的。这个包提供了神经网络的所有核心组件,包括层、损失函数和优化器.
nn.Module
继承 核心类 : nn.Module 是所有神经网络模型和层的基类。当创建自己的网络或层时,需要从这个类继承.
import torch.nn as nn
class SimpleNet(nn.Module):
def __init__(self):
super(SimpleNet, self).__init__()
组件初始化 :在 __init__ 方法中,你可以定义网络的组件。例如,可以定义线性层、卷积层等.
self.fc1 = nn.Linear(in_features=784, out_features=500)
自动调用 :当你通过网络传递一个输入时,PyTorch会自动调用 forward 方法.
定义方式 :你应该在此方法中定义数据通过网络的方式.
def forward(self, x):
x = self.fc1(x)
return x
自动管理 :在你定义的每个 nn.Module 组件(如 nn.Linear 或 nn.Conv2d )中,PyTorch会自动为你管理权重和偏置.
访问方式 :
self.fc1.weight
和 self.fc1.bias
可以分别用来访问 fc1
层的权重和偏置。 net.parameters()
来访问网络中的所有参数(权重和偏置)。 初始化 :虽然PyTorch为每个层提供了默认的初始化,但有时可能需要自定义权重的初始化。 nn.init 模块提供了一系列初始化方法.
import torch.nn.init as init
init.xavier_uniform_(self.fc1.weight)
这只是神经网络基础的简要介绍。为了构建真正的深度学习模型,还需要了解其他组件,如激活函数、损失函数、优化器等。但这些基础知识为你提供了一个坚实的起点,从这里开始,你可以继续深入.
创建有效的神经网络需要利用多种不同的层和技巧。以下是一些常用的神经网络组件及其在PyTorch中的实现.
nn.Linear
线性层是神经网络的基础,也称为全连接层.
定义
fc = nn.Linear(in_features=128, out_features=64)
其中 in_features 是输入特征的数量, out_features 是输出特征的数量.
激活函数为神经网络引入了非线性性,使其能够学习更复杂的模式.
ReLU
relu = nn.ReLU()
Sigmoid
sigmoid = nn.Sigmoid()
Tanh
tanh = nn.Tanh()
nn.Conv2d
卷积层是卷积神经网络(CNN)的核心,特别适用于图像处理.
定义
conv = nn.Conv2d(in_channels=3, out_channels=64, kernel_size=3, stride=1, padding=1)
其中, in_channels 是输入的通道数量, out_channels 是输出的通道数量, kernel_size 是卷积核的大小.
nn.MaxPool2d
池化层用于降低空间维度,常用于CNN.
定义
pool = nn.MaxPool2d(kernel_size=2, stride=2)
nn.Dropout
Dropout是一种正则化技术,用于防止模型过拟合.
定义
dropout = nn.Dropout(p=0.5)
其中, p 是dropout的概率,即随机“关闭”神经元的概率.
nn.BatchNorm2d
批标准化是一种优化技巧,可以使神经网络更快地收敛并提高模型的表现.
定义
bn = nn.BatchNorm2d(num_features=64)
当定义神经网络结构时,组合使用这些组件可以帮助你创建出功能强大的模型。这些基础组件可以为各种任务构建更复杂的网络架构,从图像分类到序列建模等.
损失函数(或称为目标函数、代价函数)衡量模型的预测与真实值之间的差距。在训练神经网络时,目标是最小化这个差距。PyTorch提供了多种内置的损失函数,适用于不同的任务.
交叉熵损失(Cross Entropy Loss) :通常用于分类问题.
criterion = nn.CrossEntropyLoss()
注意: nn.CrossEntropyLoss 同时执行了log softmax和负log likelihood计算。因此,你应该直接给它模型的原始输出,而不是softmax的输出.
均方误差损失(Mean Squared Error Loss) :常用于回归问题.
criterion = nn.MSELoss()
还有其他损失函数,如 nn.L1Loss (平均绝对误差损失), nn.BCELoss (二进制交叉熵损失), nn.SmoothL1Loss (Huber损失)等,可以根据具体任务和需求选择.
一旦选择了损失函数,计算模型的损失相对直接.
前向传播 :首先,通过模型进行前向传播以获得预测值.
outputs = model(inputs)
计算损失 :然后,使用选定的损失函数计算预测值与实际标签之间的差距.
loss = criterion(outputs, labels)
在训练循环中,你会反复计算损失,执行反向传播,并使用优化器更新模型的权重.
损失函数是训练神经网络的关键部分,因为它们为优化算法提供了明确的目标。选择合适的损失函数是获得高性能模型的关键步骤.
优化器在神经网络的训练中起到关键作用。它决定了如何根据损失函数更新网络的权重。PyTorch的 torch.optim 模块提供了多种常见的优化算法.
torch.optim
介绍 torch.optim 是一个包含多种优化算法的模块。每个优化器都实现了一个常见的优化策略,如梯度下降、动量梯度下降或Adam.
SGD (随机梯度下降) :最常见的优化算法,有时会加入动量(momentum)进行改进.
optimizer = torch.optim.SGD(model.parameters(), lr=0.01, momentum=0.9)
Adam :一个自适应学习率的优化器,结合了AdaGrad和RMSProp的思想.
optimizer = torch.optim.Adam(model.parameters(), lr=0.001, betas=(0.9, 0.999), eps=1e-08)
除了SGD和Adam, torch.optim 还提供了其他多种优化器,如RMSprop、Adagrad等,供用户选择.
梯度清零 :在每次迭代开始时,需要清除之前计算的梯度,否则新的梯度值会被添加到之前的梯度值上.
optimizer.zero_grad()
反向传播 :在计算完损失后,通过调用 loss.backward() 计算梯度.
loss.backward()
权重更新 :最后,调用优化器的 step 方法来根据计算的梯度更新权重.
optimizer.step()
优化器和其参数(如学习率)的选择对模型的训练速度和最终性能都有重要影响。经验和实验对于找到特定任务的最佳优化器和参数设置至关重要.
训练是深度学习中最核心的部分,它涉及到将输入数据送入模型并不断调整模型的权重以最小化预测误差.
torch.utils.data.DataLoader
数据加载和处理是深度学习中的一个重要阶段。 DataLoader 为我们提供了一个简便的工具来自动地进行数据批处理、打乱数据和并行加载数据.
使用方法
from torch.utils.data import DataLoader
train_loader = DataLoader(dataset=train_dataset, batch_size=32, shuffle=True, num_workers=4)
其中, train_dataset 是一个实现了 __len__ 和 __getitem__ 方法的数据集对象.
训练循环是深度学习中的核心,涉及到以下步骤:
前向传播 :将数据送入模型并获取预测.
outputs = model(inputs)
计算损失 :根据预测值和真实标签计算损失.
loss = criterion(outputs, labels)
反向传播 :根据损失计算模型的梯度.
optimizer.zero_grad() # 清零梯度
loss.backward() # 反向传播
更新权重 :使用优化器更新模型的权重.
optimizer.step()
在每个训练周期(epoch)结束后,你可能希望在验证数据集上验证模型的性能。这有助于检查模型是否过拟合,并评估其对未见过的数据的泛化能力.
验证循环 :
model.eval() # 将模型设置为评估模式
with torch.no_grad(): # 不计算梯度
for inputs, labels in val_loader:
outputs = model(inputs)
val_loss = criterion(outputs, labels)
# ...计算验证指标(如准确率)
model.train() # 将模型设置回训练模式
训练循环和验证循环是神经网络训练的核心,理解并能够有效地实现这两个循环对于建立一个强大的深度学习模型至关重要.
在PyTorch中,保存和加载模型是一个相对简单的过程。这允许你在不同的时间点保存模型、分享模型或继续中断的训练.
这将保存模型的结构和参数.
torch.save(model, 'model.pth')
通常,你可能只想保存模型的参数(状态字典),而不是整个模型.
torch.save(model.state_dict(), 'model_weights.pth')
状态字典 ( state_dict ) 是一个包含模型所有参数的Python字典对象。这提供了一种轻量级的文件格式,只包含模型的权重.
加载整个模型 :
如果你保存了整个模型,可以使用以下方式加载:
model = torch.load('model.pth')
加载模型参数 :
如果你只保存了模型的状态字典,首先你需要创建模型的实例,然后使用 load_state_dict 方法:
model = YourModelClass(*args, **kwargs) # 使用与原始模型相同的结构
model.load_state_dict(torch.load('model_weights.pth'))
确保加载的 state_dict 参数与模型的结构匹配.
保存和加载模型是深度学习工作流程的重要部分,无论是为了中断和继续训练,还是为了分享和部署模型。理解如何正确保存和恢复模型可以帮助你避免潜在的问题,并确保你的模型能够按预期工作.
深度学习模型训练时,了解模型内部的工作原理和它如何进化是非常重要的。幸运的是,有一些工具可以帮助你调试和可视化你的模型.
torchviz
可视化计算图 torchviz 是一个用于可视化PyTorch模型中的计算图的工具。计算图描述了变量之间的关系,这对于理解模型的工作原理和调试非常有用.
如何使用 :
torchviz
。 torchviz
的 make_dot
函数可视化计算图。
import torch
from torchviz import make_dot
# 假设你有一个模型和数据
model = YourModelClass()
inputs = torch.randn(1, 3, 224, 224) # 示例输入
outputs = model(inputs)
# 可视化计算图
dot = make_dot(outputs)
dot.view()
这将生成一个PDF文件,显示模型的计算图.
tensorboard
进行训练可视化 TensorBoard 是 TensorFlow 的可视化工具,但它也与 PyTorch 兼容,并提供了许多强大的可视化功能.
如何使用 :
tensorboard
和 torch.utils.tensorboard
. SummaryWriter
来记录数据。
from torch.utils.tensorboard import SummaryWriter
writer = SummaryWriter('runs/experiment_name')
for epoch in range(num_epochs):
# ... training loop ...
writer.add_scalar('Loss/train', loss, epoch)
writer.add_scalar('Accuracy/train', accuracy, epoch)
tensorboard --logdir=runs
在Web界面中,你可以查看损失、准确性等的变化,以及更多高级功能,如模型结构的可视化、特征空间的投影等.
通过使用这些工具,你可以更好地理解、调试和优化你的模型。在深度学习中,可视化通常是提高模型性能和解决问题的关键.
在这个基础教程中,我们介绍了使用PyTorch搭建和训练神经网络的关键概念和步骤。让我们总结一下我们所学的内容.
autograd
) :自动计算神经网络中的梯度。 nn.Module
继承、前向传播、权重和偏置的概念。 torch.optim
更新模型的权重。 torchviz
和 tensorboard
来了解、调试和优化你的模型。 官方文档 :PyTorch的 官方文档 是一个宝贵的资源,涵盖了框架的所有方面.
深度学习书籍 :例如《深度学习》(Goodfellow et al.)提供了深入的理论背景.
在线课程 :诸如 Deep Learning Specialization by Andrew Ng在Coursera上的课程提供了实践和理论的结合.
论文和研究 :网站如 arXiv 提供了大量的最新深度学习研究.
社区 :PyTorch论坛、GitHub、Stack Overflow等社区是解决具体问题和学习最新技巧的好地方.
当你掌握了这些基础知识后,你就已经准备好深入探索更复杂的模型、技巧和应用领域,进一步拓展你的深度学习旅程了! 。
最后此篇关于torch.nn基础学习教程|PyTorchnnBasicTutorial的文章就讲到这里了,如果你想了解更多关于torch.nn基础学习教程|PyTorchnnBasicTutorial的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
vue3 快速入门系列 - 基础 前面我们已经用 vue2 和 react 做过开发了。 从 vue2 升级到 vue3 成本较大,特别是较大的项目。所以许多公司对旧项目继续使用vue2,新项目则
C# 基础 C#项目创建 这里注意win10虚拟机需要更新下补丁,不然直接下载visual studio 2022会显示版本不支持 HelloWorld C#的类文件都是以.cs结尾,入口方法为sta
关于 iPhone 内存管理的非常基本的问题: 假设我有一个 viewController,其中有几个 subview 也由 viewController 控制。当我删除顶部 viewControll
我仍在努力适应指针。不是概念——我理解内存位置、匹配可变长度的指针增量等——这是语法。这是一个我认为是我感到困惑/无法直观把握的原因之一: int a = 42; 在一个int大小的内存空间中分配并放
1. 简介 Kafka(Apache Kafka) 是一种分布式流数据平台,最初由LinkedIn开发,并于后来捐赠给Apache软件基金会,成为了一个Apache顶级项目。它被设计用于处理大规
1.想要在命令提示符下操作mysql服务器,添加系统变量。(计算机-系统属性——环境变量——path) 2.查询数据表中的数据; select selection_lis
MySQL表的增删改查(基础) 1. CRUD 注释:在SQL中可以使用“–空格+描述”来表示注释说明 CRUD 即增加(Create)、查询(Retrieve)、更新(Update)、删除(Dele
我有一个网页,可以在加载时打开显示模式,在这个模式中,我有一个可以打开第二个模式的链接。当第二个模式关闭时(通过单击关闭按钮或单击模式外部),我想重新打开第一个模式。 对于关闭按钮,我可以通过向具有
使用 Core Data Fetched Properties,我如何执行这个简单的请求: 我希望获取的属性 ( myFetchProp ) 存储 StoreA ,它应该这样做: [myFetchPr
关闭。这个问题是opinion-based .它目前不接受答案。 想改进这个问题?更新问题,以便 editing this post 可以用事实和引用来回答它. 8年前关闭。 Improve this
最近,我得到了一个现有的Drupal项目,并被要求改进前端(HTML,JavaScript,CSS)。我在Django,PHP,Ruby等方面具有大量的前端和后端开发经验,但是我没有任何Drupal经
我试图让我的用户通过使用扫描仪类来决定要做什么,但我有一个问题,代码一旦运行就不会激活,并且它不会让我跳过任何行。我的代码如下所示: Scanner input = new Scanner(S
对模糊的标题表示歉意,因为我想不出这个名字是什么。 基本上创建一个计算学生财务付款的小程序。当我运行它时,它计算对象限额没有问题。然而,无论我尝试什么,对象“助学金”似乎除了 0 之外什么也没有提出。
这是我的代码 - main() { double x; double y = pow(((1/3 + sin(x/2))(pow(x, 3) + 3)), 1/3); prin
如果我的术语在这个问题上有误,我们深表歉意。 采取以下功能: i = 1; v = i * 2; for (j = 0; j < 4; j++ ) { console.log(v);
我的应用程序中有不同的类文件。我有 5 个类,其中 2 个是 Activity ,1 个是运行的服务。其他 2 个只是类。这两个类中变量的生命周期是多少。我知道一个 Activity 可以被操作系统杀
例如,一个方法返回一个 List 类型的对象。 public List bojangles () ... 一些代码调用方法FooBar.bojangles.iterator(); 我是 Java 的新
我遇到了一个奇怪的问题,网格的大小不适合我的屏幕。当我使用 12 列大时,它只占据屏幕的 1/3 的中间,请参见图像。我不确定是什么导致了这个问题。我没有任何会导致这种情况发生的奇怪 CSS。我不会在
我尝试使用头文件和源文件,但遇到了问题。因此,我对我正在尝试做的事情做了一个简化版本,我在 CodeBlocks 中遇到了同样的错误(undefined reference to add(double
我正在为我的网格系统使用基础,但这在任何网格系统中都可能是一个问题。我基本上用一个容器包裹了 3 个单元格,但其中一个单元格应该长到页面边框(留在我的 Sampe-Image 中)但这也可能在右侧)。
我是一名优秀的程序员,十分优秀!