深度学习框架是连接算法理论与工程实践的重要工具。它让开发者不必从零实现张量运算、自动求导、参数更新、GPU 调度和模型保存等底层细节而可以把主要精力放在数据处理、模型结构设计、训练策略和实验验证上。在众多深度学习框架中PyTorch 凭借直观的 Python 编程风格、动态图机制、强大的自动微分能力和活跃的生态已经成为深度学习学习、研究和工程实践中的主流框架之一。一、深度学习框架概览深度学习框架Deep Learning Framework是用于构建、训练和部署深度神经网络的程序系统。它通常需要同时解决三类问题• 如何高效表示和计算大规模多维数据• 如何自动计算梯度并完成反向传播• 如何调用 CPU、GPU 等硬件资源加速训练和推理从整体关系看深度学习算法、开发环境和深度学习框架的分工并不相同。算法回答的是“模型为什么这样设计”和“参数为什么这样更新”开发环境回答的是“代码在哪里编写、运行和调试”深度学习框架则回答的是“如何把数学模型变成可训练、可计算、可扩展的程序”。图 1深度学习框架在算法、开发环境与硬件之间的位置例如神经网络中的线性层、激活函数、损失函数、反向传播和优化器在数学上属于算法原理而在 PyTorch 中它们被组织成张量、模块、损失函数、自动微分和优化器等可编程对象。框架的作用就是把抽象的数学过程转化为可运行的工程流程。目前PyTorch 和 TensorFlow 是深度学习中最具代表性的两个框架。TensorFlow 在工程部署和生态工具方面积累深厚PyTorch 则以代码直观、调试方便、研究友好著称。对于希望理解深度学习计算过程的学习者来说PyTorch 更接近普通 Python 程序的书写方式也更便于观察模型从前向传播到反向传播的完整过程。二、PyTorch 的安装与环境准备图 2PyTorch 安装环境选择流程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 提供音频任务相关工具如果使用 Anaconda 或 Miniconda可以先创建独立环境再在该环境中执行安装命令conda create -n pytorch_env python3.11conda activate pytorch_env pip3 install torch torchvision torchaudio这样可以把 PyTorch 与其他项目隔离开减少依赖冲突。3、CUDA 支持说明CUDACompute Unified Device Architecture是 NVIDIA 推出的并行计算平台使 GPU 能够执行大规模通用计算任务。在深度学习中GPU 可以并行处理大量矩阵运算因此常用于加速神经网络训练。需要注意的是普通用户通过 pip 安装 PyTorch 预编译包时通常不需要单独安装完整的 CUDA Toolkit。更关键的是• 本机有支持 CUDA 的 NVIDIA 显卡• NVIDIA 显卡驱动版本足够新• 安装的 PyTorch CUDA 版本与驱动兼容系统级 CUDA Toolkit 通常只在编译 PyTorch 源码、编写自定义 CUDA 扩展或使用其他依赖系统 CUDA 的程序时才需要。对于一般学习和常规开发优先使用 PyTorch 官网生成的安装命令即可。安装完成后可以用以下代码检查 PyTorch 与 CUDA 是否可用import torch print(torch.__version__) # 查看 PyTorch 版本print(torch.cuda.is_available()) # CUDA 是否可用 if torch.cuda.is_available(): print(torch.cuda.get_device_name(0)) # 查看 GPU 型号如果 torch.cuda.is_available() 返回 True说明当前 PyTorch 可以调用 CUDA GPU。若返回 False并不一定表示安装失败也可能是机器没有 NVIDIA GPU或当前安装的是 CPU 版本或显卡驱动与 PyTorch CUDA 版本不匹配。三、PyTorch 的核心数据结构张量张量Tensor是 PyTorch 中最基础的数据结构。它可以理解为支持高效数值计算的多维数组与 NumPy 数组类似但具备两个关键扩展• 可以在 CPU 或 GPU 上执行计算• 可以记录计算过程并通过自动微分计算梯度从维度上看张量可以表示不同层级的数据• 0 维张量标量如一个损失值• 1 维张量向量如一个样本的特征• 2 维张量矩阵如一批样本的特征矩阵• 3 维及以上张量高维数据如图像批次、视频数据、文本嵌入等图 3PyTorch 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 提供了多种创建张量的方法import torch a torch.tensor([1, 2, 3])b torch.zeros(2, 3)c torch.ones(2, 3)d torch.arange(0, 10, 2)e torch.randn(3, 4) print(a)print(b)print(c)print(d)print(e)常用函数包括• torch.tensor()根据已有数据创建张量• torch.zeros()创建全 0 张量• torch.ones()创建全 1 张量• torch.empty()创建未初始化张量• torch.arange()创建等差序列• torch.linspace()创建指定范围内的等间隔数值• torch.randn()创建服从标准正态分布的随机张量PyTorch 也可以与 NumPy 互相转换import numpy as npimport torch arr np.array([1, 2, 3])x torch.from_numpy(arr) print(x) arr2 x.numpy()print(arr2)需要注意的是torch.from_numpy() 创建的张量与原 NumPy 数组通常共享内存。修改其中一个另一个也可能受到影响。3、张量的重要属性一个张量不仅包含数据还包含形状、类型和设备等信息x torch.randn(2, 3) print(x.shape) # 张量形状print(x.dtype) # 数据类型print(x.device) # 所在设备常见属性包括• shape表示张量的维度结构• dtype表示张量的数据类型• device表示张量位于 CPU 还是 GPU• grad保存自动微分计算得到的梯度图 4张量的核心属性在调试模型时shape、dtype 和 device 是最常检查的三个属性。很多深度学习代码错误本质上都来自张量形状不匹配、数据类型不匹配或设备不一致。4、张量的基本运算张量支持常见数学运算x torch.tensor([1.0, 2.0, 3.0])y torch.tensor([4.0, 5.0, 6.0]) print(x y)print(x * y)print(x / y)矩阵运算也是神经网络的基础a torch.randn(2, 3)b torch.randn(3, 4) c torch.matmul(a, b)print(c.shape)常用矩阵运算包括• torch.dot()一维向量点积• torch.mm()二维矩阵乘法• torch.matmul()支持更一般的矩阵乘法和批量矩阵乘法• 矩阵乘法运算符等价于常见场景下的 torch.matmul()。在神经网络中全连接层的核心计算可以理解为其中• x 表示输入• W 表示权重矩阵• b 表示偏置• y 表示输出在代码层面也可以理解为y x weight.T biasPyTorch 的 nn.Linear 会自动完成这一过程。5、张量形状变换深度学习中经常需要调整张量形状。常用操作包括x torch.randn(2, 3, 4) print(x.reshape(6, 4).shape)print(x.unsqueeze(0).shape)print(x.squeeze().shape)print(x.permute(1, 0, 2).shape)常用方法包括• reshape()改变张量形状• view()改变张量视图要求内存连续性更强• unsqueeze()增加一个维度• squeeze()去掉长度为 1 的维度• transpose()交换两个维度• permute()按指定顺序重排多个维度对于图像数据形状变换尤其重要。例如有些图像库使用 (height, width, channels)而 PyTorch 卷积层通常要求输入形状为 (batch_size, channels, height, width)。6、设备迁移CPU 与 GPUPyTorch 中张量和模型都可以放在不同设备上。常见写法如下device torch.device(cuda if torch.cuda.is_available() else cpu)然后将张量移动到该设备x torch.randn(5, 3)x x.to(device) print(x.device)需要特别注意参与同一次计算的张量必须位于同一设备上。如果模型在 GPU 上而输入数据仍在 CPU 上就会报错。因此训练时通常要同时移动模型和数据model model.to(device)x x.to(device)y y.to(device)延伸阅读《PyTorch张量与基础计算模块》四、自动微分与计算图自动微分Automatic Differentiation是 PyTorch 的核心能力之一。它可以根据张量运算过程自动构建计算图并在调用 .backward() 时计算梯度。图 5PyTorch 自动微分与计算图1、requires_grad 与 backward如果希望 PyTorch 跟踪某个张量的计算过程需要设置 requires_gradTrueimport torch x torch.tensor(2.0, requires_gradTrue)y x ** 2 y.backward() print(x.grad)这里y x²当 x 2 时导数为 2x 4因此输出结果为tensor(4.)这说明 PyTorch 自动计算出了 y 对 x 的梯度。2、梯度存储在 grad 属性中对于需要求导的张量调用 .backward() 后梯度会保存在 .grad 属性中x torch.tensor([1.0, 2.0, 3.0], requires_gradTrue)y (x ** 2).sum() y.backward() print(x.grad)输出结果为tensor([2., 4., 6.])因为y x₁² x₂² x₃²所以每个分量的梯度分别是2x₁、2x₂、2x₃。3、梯度清零在 PyTorch 中梯度默认会累积。也就是说如果连续多次调用 .backward()新的梯度会加到原来的梯度上而不是自动覆盖。训练神经网络时每轮参数更新前通常需要清零梯度optimizer.zero_grad()loss.backward()optimizer.step()这三个步骤是 PyTorch 训练循环中最核心的代码。4、停止梯度跟踪在模型评估或推理阶段我们只需要前向计算不需要计算梯度。此时应使用 torch.no_grad()model.eval() with torch.no_grad(): y_pred model(x)这样可以减少内存占用并提高推理效率。五、搭建神经网络模型PyTorch 中构建神经网络主要依赖 torch.nn 模块。该模块提供了大量神经网络层、激活函数、损失函数和模型容器。1、继承 nn.Module 定义模型图 6nn.Module 中的层定义与前向传播自定义模型通常需要继承 nn.Module并实现两个部分• 在 __init__() 中定义网络层• 在 forward() 中定义前向传播逻辑例如下面定义一个简单的多层全连接网络import torchimport torch.nn as nn class SimpleNN(nn.Module): def __init__(self): super().__init__() self.hidden1 nn.Linear(2, 3) self.hidden2 nn.Linear(3, 3) self.output nn.Linear(3, 1) def forward(self, x): x torch.relu(self.hidden1(x)) x torch.relu(self.hidden2(x)) x self.output(x) return x这个模型的结构是输入 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、激活函数如果神经网络只有线性层那么多层线性变换叠加后本质上仍然是线性变换。激活函数的作用是为模型引入非线性表达能力。常见激活函数包括• ReLU常用于隐藏层计算简单收敛较快• Sigmoid常用于二分类概率表达• Tanh输出范围为 -1 到 1• Softmax常用于多分类输出概率PyTorch 中激活函数既可以用函数式写法也可以用模块式写法x torch.relu(x)或self.relu nn.ReLU()x self.relu(x)函数式写法适合简单临时调用模块式写法更适合需要作为网络结构一部分保存和显示的场景。4、损失函数损失函数Loss Function用于衡量模型预测结果与真实标签之间的差异。不同任务使用的损失函数不同• 回归任务常用 nn.MSELoss()• 二分类任务常用 nn.BCEWithLogitsLoss()• 多分类任务常用 nn.CrossEntropyLoss()需要注意的是nn.CrossEntropyLoss() 内部已经包含 LogSoftmax 与负对数似然损失因此多分类模型的最后一层通常直接输出 logits不需要先手动加 Softmax。5、优化器优化器Optimizer负责根据梯度更新模型参数。PyTorch 的优化器位于 torch.optim 模块中。常见优化器包括• torch.optim.SGD随机梯度下降原理清晰常用于教学和基础实验• torch.optim.Adam结合动量和自适应学习率实际应用非常广泛• torch.optim.AdamW在大模型和 Transformer 训练中非常常见优化器通常这样创建optimizer torch.optim.Adam(model.parameters(), lr0.001)其中• model.parameters() 表示需要更新的模型参数• lr 表示学习率控制每次参数更新的步长延伸阅读《PyTorch神经网络模块》《PyTorch主要模块简介》六、数据集与数据加载真实训练任务通常不会一次性把全部数据直接传入模型而是把数据划分成一个个小批量mini-batch进行训练。PyTorch 提供了 Dataset 和 DataLoader 来组织数据读取流程。图 7Dataset 与 DataLoader 的数据加载流程1、Dataset定义数据如何取出Dataset 表示一个数据集对象通常需要实现• __len__()返回数据集大小• __getitem__()根据索引返回一个样本简单示例from torch.utils.data import Dataset class SimpleDataset(Dataset): def __init__(self, x, y): self.x x self.y y def __len__(self): return len(self.x) def __getitem__(self, index): return self.x[index], self.y[index]2、DataLoader批量读取数据DataLoader 用于批量读取数据并可自动打乱顺序from torch.utils.data import DataLoader dataset SimpleDataset(x, y)loader DataLoader(dataset, batch_size16, shuffleTrue)训练时可以这样遍历for batch_x, batch_y in loader: y_pred model(batch_x)DataLoader 的作用主要包括• 自动按批次读取数据• 支持打乱训练数据• 支持多进程加载数据• 让训练循环更加规范对于入门学习先理解 TensorDataset、自定义 Dataset 和 DataLoader 的基本配合即可。七、模型训练的标准流程图 8PyTorch 模型训练的标准闭环PyTorch 中一个典型训练循环通常包括以下步骤1、将模型切换到训练模式2、读取一个批次的数据3、将数据移动到指定设备4、前向传播得到预测结果5、计算损失6、清零上一轮梯度7、反向传播计算梯度8、优化器更新参数对应代码结构如下model.train() for batch_x, batch_y in train_loader: batch_x batch_x.to(device) batch_y batch_y.to(device) y_pred model(batch_x) loss criterion(y_pred, batch_y) optimizer.zero_grad() loss.backward() optimizer.step()模型评估时通常使用model.eval() with torch.no_grad(): for batch_x, batch_y in test_loader: batch_x batch_x.to(device) batch_y batch_y.to(device) y_pred model(batch_x)其中• model.train() 会启用训练模式对 Dropout、BatchNorm 等层有影响• model.eval() 会启用评估模式• torch.no_grad() 会关闭梯度跟踪节省显存和计算资源八、Python 示例线性回归下面使用 PyTorch 构建一个简单线性回归模型拟合如下关系y 2x 1 noise示例展示完整流程准备数据、定义模型、选择损失函数与优化器、训练模型、可视化拟合结果。# # 1. 导入必要的库# import torchimport torch.nn as nnimport torch.optim as optimimport matplotlib.pyplot as plt # 根据操作系统选择中文字体二选一plt.rcParams[font.sans-serif] [Microsoft YaHei] # Windows# plt.rcParams[font.sans-serif] [Songti SC] # macOSplt.rcParams[axes.unicode_minus] False # 正常显示负号 # # 2. 准备数据# torch.manual_seed(42) # 生成输入 x形状为 (100, 1)x torch.linspace(-1, 1, 100).unsqueeze(1) # 生成目标 y 2x 1 噪声y 2 * x 1 torch.randn(x.size()) * 0.3 # 可视化原始数据plt.scatter(x.numpy(), y.numpy(), alpha0.6)plt.xlabel(x)plt.ylabel(y)plt.title(数据集分布)plt.show() # # 3. 定义线性回归模型# class LinearRegressionModel(nn.Module): def __init__(self): super().__init__() self.linear nn.Linear(1, 1) def forward(self, x): return self.linear(x) model LinearRegressionModel() # # 4. 定义损失函数和优化器# criterion nn.MSELoss()optimizer optim.SGD(model.parameters(), lr0.2) # # 5. 训练模型# epochs 200 for epoch in range(epochs): # 前向传播 y_pred model(x) # 计算损失 loss criterion(y_pred, y) # 梯度清零 optimizer.zero_grad() # 反向传播 loss.backward() # 参数更新 optimizer.step() if (epoch 1) % 20 0: print(fEpoch [{epoch 1}/{epochs}], Loss: {loss.item():.4f}) # # 6. 查看训练结果# for name, param in model.named_parameters(): print(f{name}: {param.data}) # # 7. 可视化拟合结果# model.eval() with torch.no_grad(): y_fitted model(x) plt.scatter(x.numpy(), y.numpy(), label原始数据, alpha0.6)plt.plot(x.numpy(), y_fitted.numpy(), label拟合直线, linewidth2)plt.xlabel(x)plt.ylabel(y)plt.legend()plt.title(线性回归拟合效果)plt.show()这个示例虽然简单但已经包含 PyTorch 训练模型的核心结构模型定义 → 前向传播 → 损失计算 → 梯度清零 → 反向传播 → 参数更新以后无论训练线性回归、图像分类模型还是更复杂的深度神经网络基本训练循环都与此类似。九、Python 示例多层神经网络下面构建一个简单多层神经网络学习非线性关系y x₁² x₂² noise输入包含两个特征输出为一个连续数值因此这是一个回归任务。# # 1. 导入必要的库# import torchimport torch.nn as nnimport torch.optim as optim # # 2. 定义多层神经网络# class SimpleNN(nn.Module): def __init__(self): super().__init__() self.hidden1 nn.Linear(2, 16) self.hidden2 nn.Linear(16, 16) self.output nn.Linear(16, 1) def forward(self, x): x torch.relu(self.hidden1(x)) x torch.relu(self.hidden2(x)) x self.output(x) return x # # 3. 准备数据# torch.manual_seed(42) # 生成 200 条样本每条样本有 2 个特征x torch.randn(200, 2) # 构造非线性目标 y x1^2 x2^2 噪声y x[:, 0:1] ** 2 x[:, 1:2] ** 2 torch.randn(200, 1) * 0.1 # # 4. 创建模型、损失函数和优化器# model SimpleNN()criterion nn.MSELoss()optimizer optim.Adam(model.parameters(), lr0.01) # # 5. 训练模型# epochs 500 model.train() for epoch in range(epochs): y_pred model(x) loss criterion(y_pred, y) optimizer.zero_grad() loss.backward() optimizer.step() if (epoch 1) % 50 0: print(fEpoch [{epoch 1}/{epochs}], Loss: {loss.item():.4f}) # # 6. 简单测试# model.eval() with torch.no_grad(): test_x torch.tensor([[1.0, 2.0]]) test_y model(test_x) print(测试输入, test_x)print(模型预测, test_y.item())print(理论值约为, 1.0 ** 2 2.0 ** 2)与线性回归示例相比这个模型只是在网络结构上增加了隐藏层和 ReLU 激活函数训练流程并没有本质变化。这正体现了 PyTorch 的统一性模型可以复杂但训练范式保持相对稳定。十、初学者常见问题1、为什么要调用 optimizer.zero_grad()因为 PyTorch 中梯度默认会累积。如果不清零当前批次的梯度会与上一批次的梯度相加导致参数更新错误。因此每次反向传播前通常需要调用optimizer.zero_grad()2、为什么训练时要用 model.train()推理时要用 model.eval()有些层在训练和推理阶段行为不同。例如• Dropout 在训练时会随机丢弃部分神经元在推理时不再随机丢弃• BatchNorm 在训练时使用当前批次统计量在推理时使用累计统计量因此训练前应调用model.train()推理或评估前应调用model.eval()3、为什么有时会出现 CPU 和 GPU 不一致的错误图 9PyTorch 中模型与数据的设备一致性如果模型在 GPU 上而输入数据在 CPU 上就会出现设备不一致错误。解决方法是把模型和数据都移动到同一设备device torch.device(cuda if torch.cuda.is_available() else cpu) model model.to(device)x x.to(device)y y.to(device)4、为什么多分类任务最后一层通常不加 Softmax如果使用 nn.CrossEntropyLoss()模型最后一层应直接输出 logits。因为 CrossEntropyLoss 内部已经包含了 LogSoftmax 相关计算。手动先加 Softmax 反而可能导致数值稳定性变差。5、什么时候需要 DataLoader当数据量较大或者需要按批次训练、随机打乱数据、多进程读取数据时就应该使用 DataLoader。在真实项目中DataLoader 几乎是标准训练流程的一部分。 小结PyTorch 以张量为运算基础以自动微分为训练核心以 nn.Module 组织模型结构并通过损失函数、优化器和数据加载器构成完整训练流程。掌握张量、计算图、模型定义、损失计算、反向传播和参数更新就能理解大多数深度学习代码的基本运行逻辑。“点赞有美意赞赏是鼓励”