torch.nn基础学习教程 | PyTorch nn Basic Tutorial
基于
torch.nn搭建神经网络的基础教程大纲:
1. 引言
在我们开始深入探讨torch.nn之前,我们首先需要理解PyTorch及其神经网络库的基础知识。这一部分的内容将帮助你对PyTorch有一个整体的了解。
1.1 为什么选择PyTorch?
- 动态计算图:PyTorch使用动态计算图(也称为即时执行),这意味着网络的行为可以在运行时更改,这在调试和研究时非常有用。
- 直观性:PyTorch的API和语法非常直观,特别是对于有Python经验的人来说。
- 研究友好:由于其动态性和灵活性,PyTorch在研究界得到了广泛的欢迎。
- 强大的生态系统:PyTorch不仅仅是一个深度学习框架。它还有TorchVision、TorchText和TorchAudio等库,这些库为特定的任务提供了工具和预训练的模型。
1.2 torch.nn概述
- 神经网络包:
torch.nn是PyTorch中的核心库,用于建立和训练神经网络。它提供了层、损失函数和优化器等所有必要的组件。 - 模块化:在
torch.nn中,一切都是模块。这包括单独的层(例如nn.Linear或nn.Conv2d)以及整个神经网络模型。 - 参数管理:每个模块都可以包含多个参数(例如权重和偏置),
torch.nn为参数管理和优化提供了简单的工具。
这只是一个引入的简要描述。PyTorch提供了一个非常强大且易于使用的接口,但要完全掌握它,理解其背后的核心概念是关键。在接下来的部分中,我们将逐步探讨如何使用torch.nn构建、训练和优化神经网络。
2. Tensor基础
Tensor是PyTorch的基础数据结构,与NumPy数组类似。但Tensor提供了一些额外的功能,尤其是GPU加速计算和自动梯度计算。
2.1 什么是Tensor?
- 定义和Tensor的意义
Tensor是一个多维数组。在物理学中,“张量”是一个可以表示多种数据(如标量、向量、矩阵等)的数学对象,而在PyTorch和其他深度学习框架中,它主要指代多维数据数组。
- 核心数据结构:在PyTorch中,Tensor是最基础的数据结构,被用于表示神经网络中的输入、输出、参数等所有数据。
- 计算图和自动微分:Tensors是PyTorch自动微分(如梯度计算)的关键,允许自动计算神经网络中的梯度。
- Tensor的维度和形状
维度
: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参数来指定数据类型。
2.2 创建Tensor
- 从列表和数组创建:
torch.tensor(),torch.as_tensor() - 特殊Tensor:
torch.zeros(),torch.ones(),torch.rand(),torch.randn() - 从NumPy数组创建Tensor:
torch.from_numpy()
2.3 Tensor操作
- 基本算术操作:加、减、乘、除等
- 形状操作:
view(),reshape(),squeeze(),unsqueeze() - 索引和切片
- 聚合操作:
sum(),mean(),max(),min() - 与NumPy的交互
2.4 Tensor与NumPy间的转换
- Tensor转NumPy:
numpy() - NumPy数组转Tensor:
from_numpy()
2.5 设备间的Tensor操作
- CPU与GPU间的移动:
to(),cuda(),cpu() - 检查Tensor的设备:
is_cuda
2.6 自动梯度与Tensor
- 为Tensor启用/禁用自动梯度:
requires_grad属性 - 计算梯度:
backward() - 获取梯度:
grad属性
了解Tensor的基础知识是使用PyTorch进行深度学习的关键。在接下来的部分中,我们将学习如何使用这些基础知识来构建和优化神经网络模型。
3. 自动微分:autograd
在深度学习中,梯度计算是关键的,因为它们用于更新神经网络的权重和偏置。PyTorch的autograd包为这种梯度计算提供了自动化工具。
3.1 什么是自动微分?
- 基础概念:自动微分是一种计算函数导数或梯度的技术。在深度学习中,这通常涉及反向传播算法。
- 计算图:当您在PyTorch中执行Tensor操作时,
autograd会建立一个所谓的“计算图”来跟踪哪些操作和数据是相关的。
3.2 创建需要梯度的Tensor
使用
requires_grad参数:创建Tensor时,可以使用requires_grad=True来指示PyTorch应该跟踪此Tensor上的所有操作,并允许其计算梯度。x = torch.tensor([1, 2, 3], dtype=torch.float32, requires_grad=True)
3.3 计算梯度
当完成了计算(通常是神经网络的前向传播),并得到一个输出值(通常是损失)后,可以调用该值的
.backward()方法来自动计算所有requires_grad=True的Tensors的梯度。y = x * x
z = y.sum()
z.backward() # 这会计算z关于x的梯度
3.4 查看和操作梯度
用
.grad属性查看梯度:print(x.grad) # 这会显示x的梯度
梯度累加:注意,每次调用
.backward()时,梯度都会累加,而不是被替换。这是为了支持RNN等模型的特定情况。如果需要,可以使用.zero_()方法清除累积的梯度。
3.5 detach()和no_grad()
detach方法:创建一个与当前Tensor内容相同但不需要梯度的新Tensor。detached_x = x.detach()
torch.no_grad()上下文:在此上下文中执行的任何操作都不会被跟踪,通常在评估模型时使用这个上下文,因为在这种情况下我们不需要梯度。with torch.no_grad():
y = x + 2
autograd是PyTorch中非常强大的工具,使得手动计算复杂的梯度成为过去。了解其工作原理和如何使用它是进行有效深度学习的关键。
4. 神经网络基础
在PyTorch中,神经网络是使用torch.nn包构建的。这个包提供了神经网络的所有核心组件,包括层、损失函数和优化器。
4.1 从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)
4.2 定义前向传播
自动调用:当你通过网络传递一个输入时,PyTorch会自动调用
forward方法。定义方式:你应该在此方法中定义数据通过网络的方式。
def forward(self, x):
x = self.fc1(x)
return x
4.3 权重和偏置
自动管理:在你定义的每个
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)
这只是神经网络基础的简要介绍。为了构建真正的深度学习模型,还需要了解其他组件,如激活函数、损失函数、优化器等。但这些基础知识为你提供了一个坚实的起点,从这里开始,你可以继续深入。
5. 定义神经网络结构
创建有效的神经网络需要利用多种不同的层和技巧。以下是一些常用的神经网络组件及其在PyTorch中的实现。
5.1 线性层:nn.Linear
线性层是神经网络的基础,也称为全连接层。
定义:
fc = nn.Linear(in_features=128, out_features=64)
其中
in_features是输入特征的数量,out_features是输出特征的数量。
5.2 激活函数
激活函数为神经网络引入了非线性性,使其能够学习更复杂的模式。
ReLU:
relu = nn.ReLU()
Sigmoid:
sigmoid = nn.Sigmoid()
Tanh:
tanh = nn.Tanh()
5.3 卷积层: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是卷积核的大小。
5.4 池化层:nn.MaxPool2d
池化层用于降低空间维度,常用于CNN。
定义:
pool = nn.MaxPool2d(kernel_size=2, stride=2)
5.5 Dropout:nn.Dropout
Dropout是一种正则化技术,用于防止模型过拟合。
定义:
dropout = nn.Dropout(p=0.5)
其中,
p是dropout的概率,即随机“关闭”神经元的概率。
5.6 批标准化:nn.BatchNorm2d
批标准化是一种优化技巧,可以使神经网络更快地收敛并提高模型的表现。
定义:
bn = nn.BatchNorm2d(num_features=64)
当定义神经网络结构时,组合使用这些组件可以帮助你创建出功能强大的模型。这些基础组件可以为各种任务构建更复杂的网络架构,从图像分类到序列建模等。
6. 损失函数
损失函数(或称为目标函数、代价函数)衡量模型的预测与真实值之间的差距。在训练神经网络时,目标是最小化这个差距。PyTorch提供了多种内置的损失函数,适用于不同的任务。
6.1 常见的损失函数
交叉熵损失(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损失)等,可以根据具体任务和需求选择。
6.2 计算损失
一旦选择了损失函数,计算模型的损失相对直接。
前向传播:首先,通过模型进行前向传播以获得预测值。
outputs = model(inputs)
计算损失:然后,使用选定的损失函数计算预测值与实际标签之间的差距。
loss = criterion(outputs, labels)
在训练循环中,你会反复计算损失,执行反向传播,并使用优化器更新模型的权重。
损失函数是训练神经网络的关键部分,因为它们为优化算法提供了明确的目标。选择合适的损失函数是获得高性能模型的关键步骤。
7. 优化器
优化器在神经网络的训练中起到关键作用。它决定了如何根据损失函数更新网络的权重。PyTorch的torch.optim模块提供了多种常见的优化算法。
7.1 torch.optim介绍
torch.optim是一个包含多种优化算法的模块。每个优化器都实现了一个常见的优化策略,如梯度下降、动量梯度下降或Adam。
7.2 SGD, 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等,供用户选择。
7.3 更新权重
梯度清零:在每次迭代开始时,需要清除之前计算的梯度,否则新的梯度值会被添加到之前的梯度值上。
optimizer.zero_grad()
反向传播:在计算完损失后,通过调用
loss.backward()计算梯度。loss.backward()
权重更新:最后,调用优化器的
step方法来根据计算的梯度更新权重。optimizer.step()
优化器和其参数(如学习率)的选择对模型的训练速度和最终性能都有重要影响。经验和实验对于找到特定任务的最佳优化器和参数设置至关重要。
8. 训练神经网络
训练是深度学习中最核心的部分,它涉及到将输入数据送入模型并不断调整模型的权重以最小化预测误差。
8.1 数据加载: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__方法的数据集对象。
8.2 训练循环
训练循环是深度学习中的核心,涉及到以下步骤:
前向传播:将数据送入模型并获取预测。
outputs = model(inputs)
计算损失:根据预测值和真实标签计算损失。
loss = criterion(outputs, labels)
反向传播:根据损失计算模型的梯度。
optimizer.zero_grad() # 清零梯度
loss.backward() # 反向传播
更新权重:使用优化器更新模型的权重。
optimizer.step()
8.3 验证模型性能
在每个训练周期(epoch)结束后,你可能希望在验证数据集上验证模型的性能。这有助于检查模型是否过拟合,并评估其对未见过的数据的泛化能力。
验证循环:
model.eval() # 将模型设置为评估模式
with torch.no_grad(): # 不计算梯度
for inputs, labels in val_loader:
outputs = model(inputs)
val_loss = criterion(outputs, labels)
# ...计算验证指标(如准确率)
model.train() # 将模型设置回训练模式
训练循环和验证循环是神经网络训练的核心,理解并能够有效地实现这两个循环对于建立一个强大的深度学习模型至关重要。
9. 保存和加载模型
在PyTorch中,保存和加载模型是一个相对简单的过程。这允许你在不同的时间点保存模型、分享模型或继续中断的训练。
9.1 保存整个模型
这将保存模型的结构和参数。
torch.save(model, 'model.pth')
9.2 仅保存模型参数
通常,你可能只想保存模型的参数(状态字典),而不是整个模型。
torch.save(model.state_dict(), 'model_weights.pth')
状态字典 (state_dict) 是一个包含模型所有参数的Python字典对象。这提供了一种轻量级的文件格式,只包含模型的权重。
9.3 加载模型
加载整个模型:
如果你保存了整个模型,可以使用以下方式加载:
model = torch.load('model.pth')
加载模型参数:
如果你只保存了模型的状态字典,首先你需要创建模型的实例,然后使用
load_state_dict方法:model = YourModelClass(*args, **kwargs) # 使用与原始模型相同的结构
model.load_state_dict(torch.load('model_weights.pth'))
确保加载的
state_dict参数与模型的结构匹配。
保存和加载模型是深度学习工作流程的重要部分,无论是为了中断和继续训练,还是为了分享和部署模型。理解如何正确保存和恢复模型可以帮助你避免潜在的问题,并确保你的模型能够按预期工作。
10. 调试与可视化
深度学习模型训练时,了解模型内部的工作原理和它如何进化是非常重要的。幸运的是,有一些工具可以帮助你调试和可视化你的模型。
10.1 使用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文件,显示模型的计算图。
- 首先,你需要安装
10.2 使用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查看数据。
tensorboard --logdir=runs
在Web界面中,你可以查看损失、准确性等的变化,以及更多高级功能,如模型结构的可视化、特征空间的投影等。
- 安装
通过使用这些工具,你可以更好地理解、调试和优化你的模型。在深度学习中,可视化通常是提高模型性能和解决问题的关键。
11. 总结
在这个基础教程中,我们介绍了使用PyTorch搭建和训练神经网络的关键概念和步骤。让我们总结一下我们所学的内容。
11.1 主要概念回顾
- Tensor:PyTorch的基本数据结构,用于表示多维数组。
- 自动微分 (
autograd):自动计算神经网络中的梯度。 - 神经网络的基础:从
nn.Module继承、前向传播、权重和偏置的概念。 - 定义神经网络结构:如何使用PyTorch内置的层和功能构建复杂的神经网络。
- 损失函数:如何定义和计算模型的预测与真实标签之间的差异。
- 优化器:如何使用
torch.optim更新模型的权重。 - 训练神经网络:数据加载、训练循环、验证模型性能的核心步骤。
- 保存和加载模型:如何储存和恢复模型以及其参数。
- 调试与可视化:使用
torchviz和tensorboard来了解、调试和优化你的模型。
11.2 进阶资源和学习路径
官方文档:PyTorch的官方文档是一个宝贵的资源,涵盖了框架的所有方面。
深度学习书籍:例如《深度学习》(Goodfellow et al.)提供了深入的理论背景。
在线课程:诸如Deep Learning Specialization by Andrew Ng在Coursera上的课程提供了实践和理论的结合。
论文和研究:网站如arXiv提供了大量的最新深度学习研究。
社区:PyTorch论坛、GitHub、Stack Overflow等社区是解决具体问题和学习最新技巧的好地方。
当你掌握了这些基础知识后,你就已经准备好深入探索更复杂的模型、技巧和应用领域,进一步拓展你的深度学习旅程了!
torch.nn基础学习教程 | PyTorch nn Basic Tutorial的更多相关文章
- C++基础学习教程(八)
转载请注明出处:http://blog.csdn.net/suool/article/details/38300117 引入 在进行下一步的学习之前,我们须要厘清几个概念. RAII 首先介绍一个编程 ...
- C++基础学习教程(六)----类编写的前情回想以及项目实战(1)
在開始类的编写之前我们依旧须要回想整理一下前面所说的内容,(前面尽管是一个自己定义数据类型的实现过程,可是内容有点繁杂). 先看一段代码: /** @file calssStruct.cpp */ / ...
- C++基础学习教程(一)
開始自己的C++复习进阶之路. 声明: 这次写的博文纯当是一个回想复习的教程.一些非常基础的知识将不再出现.或者一掠而过,这次的主要风格就是演示样例代码非常多~~~ 全部代码在Ubuntu 14.04 ...
- spring boot基础学习教程
Spring boot 标签(空格分隔): springboot HelloWorld 什么是spring boot Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新 ...
- webpack从0到1超详细超基础学习教程
概念 自己是一个一听到webpack就头大,看着一堆不知道那是什么玩意的东西总觉得自己做好前端就行了,但是在使用vue-cli的时候总觉得要改其中的一些东西进行项目初始化的时候能够更好使用!所以想要根 ...
- C++基础学习教程(五)
这一讲我们集中解说类和他的一些特性.首先我们从自己定义一个有理数类来開始. 在C语言中有一个keyword: struct ,用来创建一个结构体类型.可是在C++中这个关键的含义就不只如此了,以下我们 ...
- C++基础学习教程(三)
承接上一讲. 2.7文件I/O 关于读写文件,C++中有一个专门的头文件<fstream>. 首先是读文件演示样例,例如以下: </pre><pre> /***** ...
- C++基础学习教程(七)----类编写及类的两个特性解析--->多态&继承
类引入 到眼下为止我们所写的自己定义类型都是keywordstruct,从如今起我们将採用class方式定义类,这样的方式对于学习过其它高级语言包含脚本(Such as Python)的人来说再熟悉只 ...
- Vuejs 基础学习教程
(四)构建基础进阶-env文件与环境设置 我们在实际开发中,我们一般会经历项目的开发阶段,测试阶段,和最终上线阶段,每个阶段对于项目代码的需要可能都有所不同,那我们怎么让它在不同阶段呈现不同的效果呢? ...
- javascript 基础学习教程
http://www.itxueyuan.org/javascript/jiaocheng_2/
随机推荐
- Selenium - 浏览器配置(2) - 浏览器默认下载路径设置
Selenium - 浏览器配置 浏览器下载路径设置 我们默认使用谷歌浏览器下载文件的时候,总会弹出窗口指定文件下载路径: 但是selenium不能对浏览器窗口以外的窗口做操作: 可以在谷歌配置信息中 ...
- 【GiraKoo】夜神模拟器提示“当前设备未开启VT”
[解决]夜神模拟器提示"当前设备未开启VT" 环境 Windows 11 夜神模拟器64位 现象 启动夜神模拟器时,提示"检测到当前设备未开启VT,请先开启VT后再运行6 ...
- STM32为何在诸多的单片机中脱颖而出?
1.前言 在STM32之前,都是老大头51,带着它的"小弟们" MSP430.AVR.PIC在单片机界呼风唤雨.那个时候,市场上遍布8位机,大学教材用51入门,个人.企业学单片机 ...
- windows下搭建docker容器环境
下载Docker Desktop https://www.docker.com/ 安装Docker Desktop(软件默认安装c盘,若要安装到其他盘,在安装之前创建软连接再进行安装) 在自定义磁盘中 ...
- 计算机网络 传输层协议TCP和UDP
目录 一.传输层协议 二.tcp协议介绍 三.tcp报文格式 四.tcp三次握手 五.tcp四次挥手 六.udp协议介绍 七.常见协议和端口 八.有限状态机 一.传输层协议 传输层协议主要是TCP和U ...
- 文档在线预览(三)使用js前端实现word、excel、pdf、ppt 在线预览
@ 目录 实现方案 一.docx文件实现前端预览 1.docx-preview 2.Mammoth 二.PDF文件实现前端预览 1.pdf.js 2.pdfobject.js 3.vue-pdf 4. ...
- 【建议收藏】Log4j配置详解
大家在日常开发中必然会使用到日志组件,Log4j是Java方向上比较常用的日志组件,今天给大家分享下Log4j支持的配置项,强烈建议收藏,以便配置时查看 #展示log4j各种配置,私有部分见文件中注释 ...
- FnOnce , FnMut <RUST>
FnOnce 1 #[lang = "fn_once"] 2 #[must_use = "closures are lazy and do nothing unless ...
- 新建maven项目的时候idea的一些设置
1.统一字符编码 2.开启注解生效激活 3.选择编译编码格式 4.设置忽略文件
- 数仓性能调优:大宽表关联MERGE性能优化
摘要:本文主要为大家讲解在数仓性能调优过程中,关于大宽表关联MERGE性能优化过程. 本文分享自华为云社区<GaussDB(DWS)性能调优:大宽表关联MERGE性能优化>,作者:譡里个檔 ...