深度学习框架是连接算法理论与工程实践的重要工具。它让开发者不必从零实现张量运算、自动求导、参数更新、GPU 调度和模型保存等底层细节,而可以把主要精力放在数据处理、模型结构设计、训练策略和实验验证上。
在众多深度学习框架中,PyTorch 凭借直观的 Python 编程风格、动态图机制、强大的自动微分能力和活跃的生态,已经成为深度学习学习、研究和工程实践中的主流框架之一。
一、深度学习框架概览
深度学习框架(Deep Learning Framework)是用于构建、训练和部署深度神经网络的程序系统。它通常需要同时解决三类问题:
• 如何高效表示和计算大规模多维数据
• 如何自动计算梯度并完成反向传播
• 如何调用 CPU、GPU 等硬件资源加速训练和推理
从整体关系看,深度学习算法、开发环境和深度学习框架的分工并不相同。
算法回答的是“模型为什么这样设计”和“参数为什么这样更新”;开发环境回答的是“代码在哪里编写、运行和调试”;深度学习框架则回答的是“如何把数学模型变成可训练、可计算、可扩展的程序”。
![]()
图 1:深度学习框架在算法、开发环境与硬件之间的位置
例如,神经网络中的线性层、激活函数、损失函数、反向传播和优化器,在数学上属于算法原理;而在 PyTorch 中,它们被组织成张量、模块、损失函数、自动微分和优化器等可编程对象。框架的作用,就是把抽象的数学过程转化为可运行的工程流程。
目前,PyTorch 和 TensorFlow 是深度学习中最具代表性的两个框架。TensorFlow 在工程部署和生态工具方面积累深厚,PyTorch 则以代码直观、调试方便、研究友好著称。
对于希望理解深度学习计算过程的学习者来说,PyTorch 更接近普通 Python 程序的书写方式,也更便于观察模型从前向传播到反向传播的完整过程。
二、PyTorch 的安装与环境准备
![]()
图 2:PyTorch 安装环境选择流程
1、安装前需要确认的环境
安装 PyTorch 之前,建议先确认三项内容:
• 操作系统:Windows、macOS 还是 Linux
• Python 环境:建议使用独立虚拟环境,避免与其他项目依赖冲突
• 计算平台:仅使用 CPU,还是希望使用 NVIDIA GPU 进行 CUDA 加速
如果只是学习 PyTorch 基础,CPU 版本已经足够。如果需要训练较大的神经网络、图像模型或大规模数据集,则建议使用支持 CUDA 的 NVIDIA GPU。
2、使用官网安装选择器
推荐进入 PyTorch 官网安装页面,根据本机环境依次选择:
• PyTorch Build:通常选择 Stable
• Your OS:选择当前操作系统
• Package:通常选择 pip 或 conda
• Language:选择 Python
• Compute Platform:选择 CPU 或对应 CUDA 版本
![]()
如上图所示,页面会自动生成安装命令。实际安装时,不建议手动拼接安装命令,也不建议随意复制旧教程中的 CUDA 版本命令,因为 PyTorch、Python、CUDA 和显卡驱动之间存在版本匹配关系。
CPU 版本的常见安装形式如下:
pip3 install torch torchvision torchaudio其中:
• torch 是 PyTorch 的核心包
• torchvision 提供图像任务常用的数据集、模型和图像变换工具
• torchaudio 提供音频任务相关工具
如果使用 或 Miniconda,可以先创建独立环境,再在该环境中执行安装命令:
pip3 install torch torchvision torchaudio这样可以把 PyTorch 与其他项目隔离开,减少依赖冲突。
3、CUDA 支持说明
CUDA(Compute Unified Device Architecture)是 NVIDIA 推出的并行计算平台,使 GPU 能够执行大规模通用计算任务。在深度学习中,GPU 可以并行处理大量矩阵运算,因此常用于加速神经网络训练。
需要注意的是,普通用户通过 pip 安装 PyTorch 预编译包时,通常不需要单独安装完整的 CUDA Toolkit。更关键的是:
• 本机有支持 CUDA 的 NVIDIA 显卡
• NVIDIA 显卡驱动版本足够新
• 安装的 PyTorch CUDA 版本与驱动兼容
系统级 CUDA Toolkit 通常只在编译 PyTorch 源码、编写自定义 CUDA 扩展或使用其他依赖系统 CUDA 的程序时才需要。对于一般学习和常规开发,优先使用 PyTorch 官网生成的安装命令即可。
安装完成后,可以用以下代码检查 PyTorch 与 CUDA 是否可用:
如果 torch.cuda.is_available() 返回 True,说明当前 PyTorch 可以调用 CUDA GPU。若返回 False,并不一定表示安装失败,也可能是机器没有 NVIDIA GPU,或当前安装的是 CPU 版本,或显卡驱动与 PyTorch CUDA 版本不匹配。
三、PyTorch 的核心数据结构:张量
张量(Tensor)是 PyTorch 中最基础的数据结构。它可以理解为支持高效数值计算的多维数组,与 NumPy 数组类似,但具备两个关键扩展:
• 可以在 CPU 或 GPU 上执行计算
• 可以记录计算过程,并通过自动微分计算梯度
从维度上看,张量可以表示不同层级的数据:
• 0 维张量:标量,如一个损失值
• 1 维张量:向量,如一个样本的特征
• 2 维张量:矩阵,如一批样本的特征矩阵
• 3 维及以上张量:高维数据,如图像批次、视频数据、文本嵌入等
![]()
图 3:PyTorch Tensor 的维度层级
例如,在图像任务中,一批彩色图像通常可以表示为四维张量:
(batch_size, channels, height, width)其中:
• batch_size 表示一次输入模型的样本数量
• channels 表示通道数,彩色图像通常为 3
• height 和 width 表示图像高度和宽度
1、常见张量类型
PyTorch 张量支持多种数据类型,常见类型包括以下几类。
第一类是浮点型,主要用于神经网络中的连续数值计算:
• torch.float32:最常用的浮点类型
• torch.float16:半精度浮点,常用于混合精度训练
• torch.bfloat16:常用于部分深度学习加速场景
第二类是整型,常用于类别编号、索引和离散值:
• torch.int64:分类标签中非常常见
• torch.int32、torch.int16、torch.int8:用于不同位宽的整数数据
第三类是布尔型:
• torch.bool:常用于条件判断、掩码和布尔索引
在深度学习中,模型参数和输入特征通常使用浮点型,而分类标签常常使用整型。
2、创建张量
PyTorch 提供了多种创建张量的方法:
常用函数包括:
• torch.tensor():根据已有数据创建张量
• torch.zeros():创建全 0 张量
• torch.ones():创建全 1 张量
• torch.empty():创建未初始化张量
• torch.arange():创建等差序列
• torch.linspace():创建指定范围内的等间隔数值
• torch.randn():创建服从标准正态分布的随机张量
PyTorch 也可以与 NumPy 互相转换:
需要注意的是,torch.from_numpy() 创建的张量与原 NumPy 数组通常共享内存。修改其中一个,另一个也可能受到影响。
3、张量的重要属性
一个张量不仅包含数据,还包含形状、类型和设备等信息:
常见属性包括:
• shape:表示张量的维度结构
• dtype:表示张量的数据类型
• device:表示张量位于 CPU 还是 GPU
• grad:保存自动微分计算得到的梯度
![]()
图 4:张量的核心属性
在调试模型时,shape、dtype 和 device 是最常检查的三个属性。很多深度学习代码错误,本质上都来自张量形状不匹配、数据类型不匹配或设备不一致。
4、张量的基本运算
张量支持常见数学运算:
矩阵运算也是神经网络的基础:
常用矩阵运算包括:
• torch.dot():一维向量点积
• torch.mm():二维矩阵乘法
• torch.matmul():支持更一般的矩阵乘法和批量矩阵乘法
• @:矩阵乘法运算符,等价于常见场景下的 torch.matmul()。
在神经网络中,全连接层的核心计算可以理解为:
其中:
• x 表示输入
• W 表示权重矩阵
• b 表示偏置
• y 表示输出
在代码层面,也可以理解为:
y = x @ weight.T + biasPyTorch 的 nn.Linear 会自动完成这一过程。
5、张量形状变换
深度学习中经常需要调整张量形状。常用操作包括:
常用方法包括:
• reshape():改变张量形状
• view():改变张量视图,要求内存连续性更强
• unsqueeze():增加一个维度
• squeeze():去掉长度为 1 的维度
• transpose():交换两个维度
• permute():按指定顺序重排多个维度
对于图像数据,形状变换尤其重要。例如,有些图像库使用 (height, width, channels),而 PyTorch 卷积层通常要求输入形状为 (batch_size, channels, height, width)。
6、设备迁移:CPU 与 GPU
PyTorch 中,张量和模型都可以放在不同设备上。常见写法如下:
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")然后将张量移动到该设备:
需要特别注意:参与同一次计算的张量必须位于同一设备上。如果模型在 GPU 上,而输入数据仍在 CPU 上,就会报错。因此,训练时通常要同时移动模型和数据:
四、自动微分与计算图
(Automatic Differentiation)是 PyTorch 的核心能力之一。它可以根据张量运算过程自动构建,并在调用 .backward() 时计算。
![]()
图 5:PyTorch 自动微分与计算图
1、requires_grad 与 backward
如果希望 PyTorch 跟踪某个张量的计算过程,需要设置 requires_grad=True:
这里,y = x²,当 x = 2 时,导数为 2x = 4,因此输出结果为:
tensor(4.)这说明 PyTorch 自动计算出了 y 对 x 的梯度。
2、梯度存储在 grad 属性中
对于需要求导的张量,调用 .backward() 后,梯度会保存在 .grad 属性中:
print(x.grad)输出结果为:
tensor([2., 4., 6.])因为:
y = x₁² + x₂² + x₃²
所以每个分量的梯度分别是:2x₁、2x₂、2x₃。
3、梯度清零
在 PyTorch 中,梯度默认会累积。也就是说,如果连续多次调用 .backward(),新的梯度会加到原来的梯度上,而不是自动覆盖。训练神经网络时,每轮参数更新前通常需要清零梯度:
optimizer.step()这三个步骤是 PyTorch 训练循环中最核心的代码。
4、停止梯度跟踪
在模型评估或推理阶段,我们只需要前向计算,不需要计算梯度。此时应使用 torch.no_grad():
这样可以减少内存占用并提高推理效率。
五、搭建神经网络模型
PyTorch 中构建神经网络主要依赖 torch.nn 模块。该模块提供了大量神经网络层、激活函数、损失函数和模型容器。
1、继承 nn.Module 定义模型
![]()
图 6:nn.Module 中的层定义与前向传播
自定义模型通常需要继承 nn.Module,并实现两个部分:
• 在 __init__() 中定义网络层
• 在 forward() 中定义前向传播逻辑
例如,下面定义一个简单的多层全连接网络:
这个模型的结构是:输入 2 个特征 → 隐藏层 1 → ReLU → 隐藏层 2 → ReLU → 输出 1 个数值。
在 PyTorch 中,只要调用:
y_pred = model(x)就会自动执行模型的 forward() 方法。
2、常用层
常见神经网络层包括:
• nn.Linear:全连接层,常用于表格数据、回归任务、分类任务和多层感知器
• nn.Conv2d:二维卷积层,常用于图像任务
• nn.MaxPool2d:最大池化层,常用于降低图像特征图尺寸
• nn.Embedding:嵌入层,常用于文本和离散编号数据
• nn.Dropout:随机失活层,常用于缓解过拟合
• nn.BatchNorm1d / nn.BatchNorm2d:批归一化层,常用于稳定训练
其中,nn.Linear 是最基础的层。它实现的线性变换为:
y = xWᵀ + b
其中:
• x 表示输入
• W 表示权重矩阵
• b 表示偏置
• y 表示输出
3、激活函数
如果神经网络只有线性层,那么多层线性变换叠加后本质上仍然是线性变换。的作用,是为模型引入非线性表达能力。
常见激活函数包括:
• :常用于隐藏层,计算简单,收敛较快
• :常用于二分类概率表达
• :输出范围为 -1 到 1
• :常用于多分类输出概率
PyTorch 中,激活函数既可以用函数式写法,也可以用模块式写法:
x = torch.relu(x)或:
x = self.relu(x)函数式写法适合简单临时调用;模块式写法更适合需要作为网络结构一部分保存和显示的场景。
4、损失函数
(Loss Function)用于衡量模型预测结果与真实标签之间的差异。不同任务使用的损失函数不同:
• 回归任务:常用 nn.MSELoss()
• 二分类任务:常用 nn.BCEWithLogitsLoss()
• 多分类任务:常用 nn.CrossEntropyLoss()
需要注意的是,nn.CrossEntropyLoss() 内部已经包含 LogSoftmax 与负对数似然损失,因此多分类模型的最后一层通常直接输出 ,不需要先手动加 Softmax。
5、优化器
(Optimizer)负责根据梯度更新模型参数。PyTorch 的优化器位于 torch.optim 模块中。
常见优化器包括:
• torch.optim.SGD:随机梯度下降,原理清晰,常用于教学和基础实验
• torch.optim.Adam:结合动量和自适应学习率,实际应用非常广泛
• torch.optim.AdamW:在大模型和 Transformer 训练中非常常见
优化器通常这样创建:
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)其中:
• model.parameters() 表示需要更新的模型参数
• lr 表示学习率,控制每次参数更新的步长
六、数据集与数据加载
真实训练任务通常不会一次性把全部数据直接传入模型,而是把数据划分成一个个小批量(mini-batch)进行训练。PyTorch 提供了 Dataset 和 DataLoader 来组织数据读取流程。
![]()
图 7:Dataset 与 DataLoader 的数据加载流程
1、Dataset:定义数据如何取出
Dataset 表示一个数据集对象,通常需要实现:
• __len__():返回数据集大小
• __getitem__():根据索引返回一个样本
简单示例:
2、DataLoader:批量读取数据
DataLoader 用于批量读取数据,并可自动打乱顺序:
训练时可以这样遍历:
DataLoader 的作用主要包括:
• 自动按批次读取数据
• 支持打乱训练数据
• 支持多进程加载数据
• 让训练循环更加规范
对于入门学习,先理解 TensorDataset、自定义 Dataset 和 DataLoader 的基本配合即可。
七、模型训练的标准流程
![]()
图 8:PyTorch 模型训练的标准闭环
PyTorch 中,一个典型训练循环通常包括以下步骤:
1、将模型切换到训练模式
2、读取一个批次的数据
3、将数据移动到指定设备
4、前向传播得到预测结果
5、计算损失
6、清零上一轮梯度
7、反向传播计算梯度
8、优化器更新参数
对应代码结构如下:
模型评估时,通常使用:
其中:
• model.train() 会启用训练模式,对 Dropout、BatchNorm 等层有影响
• model.eval() 会启用评估模式
• torch.no_grad() 会关闭梯度跟踪,节省显存和计算资源
八、Python 示例:线性回归
下面使用 PyTorch 构建一个简单线性回归模型,拟合如下关系:
y = 2x + 1 + noise
示例展示完整流程:准备数据、定义模型、选择损失函数与优化器、训练模型、可视化拟合结果。
这个示例虽然简单,但已经包含 PyTorch 训练模型的核心结构:
模型定义 → 前向传播 → 损失计算 → 梯度清零 → 反向传播 → 参数更新
以后无论训练线性回归、图像分类模型,还是更复杂的深度神经网络,基本训练循环都与此类似。
九、Python 示例:多层神经网络
下面构建一个简单多层神经网络,学习非线性关系:
y = x₁² + x₂² + noise
输入包含两个特征,输出为一个连续数值,因此这是一个回归任务。
与线性回归示例相比,这个模型只是在网络结构上增加了隐藏层和 ReLU 激活函数,训练流程并没有本质变化。这正体现了 PyTorch 的统一性:模型可以复杂,但训练范式保持相对稳定。
十、初学者常见问题
1、为什么要调用 optimizer.zero_grad()?
因为 PyTorch 中梯度默认会累积。如果不清零,当前批次的梯度会与上一批次的梯度相加,导致参数更新错误。因此,每次反向传播前通常需要调用:
optimizer.zero_grad()2、为什么训练时要用 model.train(),推理时要用 model.eval()?
有些层在训练和推理阶段行为不同。例如:
• Dropout 在训练时会随机丢弃部分神经元,在推理时不再随机丢弃
• BatchNorm 在训练时使用当前批次统计量,在推理时使用累计统计量
因此,训练前应调用:
model.train()推理或评估前应调用:
model.eval()3、为什么有时会出现 CPU 和 GPU 不一致的错误?
![]()
图 9:PyTorch 中模型与数据的设备一致性
如果模型在 GPU 上,而输入数据在 CPU 上,就会出现设备不一致错误。解决方法是把模型和数据都移动到同一设备:
4、为什么多分类任务最后一层通常不加 Softmax?
如果使用 nn.CrossEntropyLoss(),模型最后一层应直接输出 logits。因为 CrossEntropyLoss 内部已经包含了 LogSoftmax 相关计算。手动先加 Softmax 反而可能导致数值稳定性变差。
5、什么时候需要 DataLoader?
当数据量较大,或者需要按批次训练、随机打乱数据、多进程读取数据时,就应该使用 DataLoader。在真实项目中,DataLoader 几乎是标准训练流程的一部分。
小结
PyTorch 以张量为运算基础,以自动微分为训练核心,以 nn.Module 组织模型结构,并通过损失函数、优化器和数据加载器构成完整训练流程。掌握张量、计算图、模型定义、损失计算、反向传播和参数更新,就能理解大多数深度学习代码的基本运行逻辑。
“点赞有美意,赞赏是鼓励”
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.