ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

2026深度学习框架选型:TensorFlow与PyTorch对比及PyTorch实战

2026深度学习框架选型:TensorFlow与PyTorch对比及PyTorch实战 距离我第一次在 CSDN 上写深度学习入门文章已经过去好几年了。但直到今天私信里最频繁的问题依然是“我准备入门深度学习到底选 TensorFlow 还是 PyTorch”到了 2026 年这个问题依然没有被完美解决反而因为两个框架都在迭代让新手更难选了。TensorFlow 依然在工业部署和服务端场景里占主导PyTorch 依然是学术界和论文复现的首选同时也在快速加强自己的部署能力。这篇文章不打算“站队”而是用一套完整的对比思路 PyTorch 速通实战帮你解决三个问题两个框架的核心差异到底在哪里哪些优势和你真正相关。根据你的背景、目标、硬件条件如何做出合适选择。如果决定从 PyTorch 入手如何用一套完整可运行的代码快速跑通深度学习全流程。文章内容偏新手友好但也适合想从 TensorFlow 切换到 PyTorch 的开发者。阅读前建议你准备好一个 Python 3.10 以上的环境跟着第四部分的实战代码实际操作一遍。1. 为什么到了 2026 年大家还在纠结框架选择1.1 深度学习框架到底解决什么问题先回到最基础的问题。深度学习本质上是一连串大规模矩阵运算和自动求导过程。手写梯度下降不现实于是出现了深度学习框架帮我们解决三件核心事自动求导不需要手动计算每一层梯度的数学公式。算子库把卷积、池化、激活函数、损失函数等常用操作封装成现成接口。设备调度统一管理 CPU、GPU、多卡训练、混合精度等底层细节。所以框架本身不是“算法”而是“算法工程的工具”。选框架本质上是在选一种开发体验和生态而不是选一种数学能力。1.2 TensorFlow 和 PyTorch 的现状TensorFlow 诞生时间最早2015 年开源背靠 Google早期迅速占领市场。PyTorch 2017 年开源背后是 Meta凭借“动态计算图”和 Python 式的开发体验在学术界快速崛起。根据近年来大量论文实现、开源模型权重、课程教学的现状来看PyTorch 已经成为很多研究团队默认选择。但 TensorFlow 并没有消失它在生产环境、移动端、服务端领域依然有大量存量项目和完整方案。到了 2026 年两个框架都走向了“大一统”路线TensorFlow 2.x 默认动态执行PyTorch 也提供了 torch.compile、TorchScript、ONNX 导出等部署手段。换句话说两者都在互相学习差异已经不像 2018 年那么悬殊。1.3 为什么新手往往选错我见过很多新手选框架的理由不太靠谱的包括听说 PyTorch 代码简单所以选 PyTorch。听说 TensorFlow 岗位多所以选 TensorFlow。学校课程或培训视频用什么就跟着用什么。这些理由没有错但没有结合自己的目标。比如目标是把深度学习模型部署到安卓手机上那 TensorFlow Lite 生态更成熟目标是快速复现论文结果、准备算法岗面试那 PyTorch 更直接目标是学习深度学习原理不想被框架语法干扰那 PyTorch 门槛相对更低。选框架不是选一个“标准答案”而是选一个“更适合现在目标”的起点。2. TensorFlow 与 PyTorch 核心差异对比为了让你更直观地理解这一节我从 API 风格、调试体验、部署方案、生态分布四个维度做对比。2.1 API 风格与开发体验TensorFlow 2.x 虽然默认开启了 Eager Execution动态执行但从历史沿革和编程风格看它还是在很多地方保留着比较“工程化”的感觉。你可能需要接触tf.data做数据管道用tf.keras做高层模型定义用tf.function做图加速。PyTorch 的设计更贴近 Python 原生习惯。网络结构、训练循环、数据加载几乎都是用纯 Python 代码写的。你在forward函数里写什么模型前向传播就是什么没有太多隐式转换。下面用最简单的全连接网络对比两者写法。TensorFlow Keras 写法# 文件路径model_tf.py import tensorflow as tf model tf.keras.Sequential([ tf.keras.layers.Dense(128, activationrelu), tf.keras.layers.Dense(10, activationsoftmax) ]) model.compile( optimizeradam, losssparse_categorical_crossentropy, metrics[accuracy] )PyTorch 写法# 文件路径model_torch.py import torch import torch.nn as nn class MLP(nn.Module): def __init__(self): super().__init__() self.fc1 nn.Linear(784, 128) self.fc2 nn.Linear(128, 10) def forward(self, x): x torch.relu(self.fc1(x)) x self.fc2(x) return x model MLP()这两种写法没有绝对优劣。Keras 更简洁适合快速尝试PyTorch 更直白和 Python 代码风格一致适合想深入理解每一层细节的人。2.2 调试体验这点差异在实战里非常明显。PyTorch 的动态计算图意味着你可以在forward或训练循环中直接print变量形状、使用breakpoint()打断点、用 Python 自带调试器。因为整个计算过程就是普通 Python 函数逻辑报错信息能追溯到原始代码位置。TensorFlow 2.x 虽然已经改善但由于涉及计算图和自动图转换部分场景下仍然可能遇到“报错出现在图编译阶段”的情况对新手来说问题定位会更费劲。这也是为什么相当多教学视频、论文复现代码都选择 PyTorch 的原因之一它更贴近“代码即逻辑”的直觉。2.3 部署方案与工业落地TensorFlow 的工业化部署是它的传统强项TensorFlow Serving服务端模型部署。TensorFlow Lite移动端和嵌入式端推理。TensorFlow.js浏览器端部署。PyTorch 近几年的部署生态也在快速补齐比如TorchScript把 PyTorch 模型导出为静态图。torch.compile在 PyTorch 2.x 中加速训练和推理。ONNX 导出对接不同的推理引擎。ExecuTorch、TorchServe 等。如果业务场景是大型服务端模型推荐系统两个框架都有成熟案例。如果场景是安卓/iOS 端或嵌入式设备TensorFlow Lite 的案例和经验积累相对更多。2.4 学术研究与社区生态在论文复现、开源模型权重、Hugging Face Transformers 生态里PyTorch 已经成为事实标准。大多数新发布的模型都会优先提供 PyTorch 权重和推理代码。社区里有个很有意思的现象很多用 TensorFlow 的开发者最后也学会了 PyTorch因为读别人代码、跑开源模型时绕不开。反过来也成立但比例上 PyTorch 更容易成为“共同语言”。所以如果目标是算法工程师、研究工程师、模型训练方向从 PyTorch 入手更稳妥。3. 根据场景选择到底哪个框架适合你这一节我直接按用户类型给建议你可以对号入座。3.1 在校学生、论文复现、算法岗求职这类场景的目标是快速理解模型结构、训练模型、跑实验对比。PyTorch 的 Python 风格、动态图和庞大的论文复现资源可以帮你把精力集中在“模型设计”而不是“框架转化”。建议选择 PyTorch。3.2 后端工程师、无 GPU 环境、以 API 调用为主如果你的主要工作不是训练模型而是调用现成模型接口、做服务封装、数据预处理那么框架选择影响不大。你反而应该重点关注模型导出和推理接口比如 ONNX、TensorRT、TFLite。在这个场景下我个人建议团队已有框架栈优先没有历史包袱就选 PyTorch因为它在开源模型社区里更容易找到现成实现。3.3 移动端 / 嵌入式 / IoT 场景如果目标是手机端实时推理或嵌入式设备部署TensorFlow Lite 生态更成熟踩坑资料也更多。PyTorch 也在进步但整体成熟度、社区案例、硬件加速支持方面仍有差距。建议先做充分调研如果团队里已经有人熟悉 TensorFlow建议选 TensorFlow。3.4 纯粹想学习“深度学习原理”的新手如果你不需要马上上生产只是想知道神经网络内部发生了什么那么优先考虑代码可读性。从这个角度讲PyTorch 更合适。你可以只用几十行代码完成一个训练循环每一行都看得懂。4. PyTorch 速通2 小时跑通深度学习全流程如果你已经决定从 PyTorch 入手下面这套流程是纯实战内容。我会按“环境搭建 → 张量 → 自动求导 → 模型定义 → 训练循环 → 完整案例”的顺序展开。4.1 创建虚拟环境强烈建议使用 Miniconda 或 Anaconda 创建独立的 Python 环境。虚拟环境可以避免不同项目的依赖冲突也能在环境弄乱了之后一键删除重来。# 创建 Python 3.10 环境名字设为 dl conda create -n dl python3.10 -y # 激活环境 conda activate dl如果你不用 conda也可以使用 venvpython -m venv dl_env source dl_env/bin/activate # Windows 下执行 dl_env\Scripts\activate4.2 安装 PyTorchPyTorch 的安装命令建议从官网生成不要凭记忆硬记。版本不同、操作系统不同、CPU/GPU 不同命令会有差异。如果你只是先体验 CPU 版本安装非常简单pip install torch torchvision如果你的电脑有 NVIDIA 显卡并且想用 GPU 训练需要先安装匹配的 CUDA 驱动然后根据官网提供的命令安装对应版本。这里不建议直接复制某个固定版本号命令请访问 PyTorch 官网选择对应系统、CUDA 版本的命令。安装过程中要注意显卡驱动版本和 CUDA 版本要对齐。不同面板的 PyTorch 命令不要混用例如先 pip 后又 conda容易把环境搞乱。安装完后可以用下面的代码验证 GPU 是否可用。import torch print(torch.__version__) print(torch.cuda.is_available()) print(torch.cuda.get_device_name(0) if torch.cuda.is_available() else 未检测到GPU)如果输出结果中torch.cuda.is_available()为True说明安装成功可以正常调用 GPU。4.3 张量深度学习中的“数组”PyTorch 的核心数据结构是 Tensor可以理解成“带设备信息的、支持自动求导的 N 维数组”。它和 NumPy 的 ndarray 很像但多了一些深度学习中需要的特性。import torch # 从列表创建张量 x torch.tensor([[1.0, 2.0], [3.0, 4.0]]) print(x) # 随机张量 y torch.randn(2, 3) # 标准正态分布随机数 print(y) # 形状 print(x.shape) # 张量转换到 NumPy import numpy as np arr x.numpy() print(arr)注意到一个关键概念PyTorch 中张量默认在 CPU 上。如果要放到 GPU 上需要调用.to(cuda)或.cuda()。# 如果 GPU 可用将张量移动到 GPU if torch.cuda.is_available(): x_gpu x.to(cuda) print(x_gpu.device)4.4 自动求导深度学习框架的“灵魂”PyTorch 的autograd机制会自动记录你对张量的所有操作并在反向传播时自动计算梯度。举个例子import torch # 创建一个需要梯度的张量 x torch.tensor(2.0, requires_gradTrue) # 定义一个简单的函数 y x^2 y x ** 2 # 反向传播 y.backward() # 查看梯度 print(x.grad) # 输出 tensor(4.0)这个简单的例子背后是链式法则dy/dx 2x当x2时梯度等于 4。实际神经网络中框架会沿着计算图从输出向输入逐层传播梯度这个过程中调用者除了设置requires_gradTrue和调用backward()不需要手动实现数学推导。4.5 定义神经网络模型在 PyTorch 中模型通常继承自torch.nn.Module。你只需要在__init__中定义网络层在forward中定义数据如何前向传播。下面是一个经典的 LeNet 风格卷积神经网络适用于图片分类。import torch.nn as nn class LeNet(nn.Module): def __init__(self, num_classes10): super().__init__() # 卷积层 池化层 self.features nn.Sequential( nn.Conv2d(1, 6, kernel_size5, padding2), nn.ReLU(), nn.MaxPool2d(kernel_size2), nn.Conv2d(6, 16, kernel_size5), nn.ReLU(), nn.MaxPool2d(kernel_size2), ) # 全连接分类器 self.classifier nn.Sequential( nn.Linear(16 * 6 * 6, 120), nn.ReLU(), nn.Linear(120, 84), nn.ReLU(), nn.Linear(84, num_classes), ) def forward(self, x): x self.features(x) x x.view(x.size(0), -1) # 展平操作 x self.classifier(x) return x # 实例化模型 model LeNet(num_classes10) print(model)这里的x.view(x.size(0), -1)经常让新手困惑它把形状为[batch_size, channel, height, width]的特征图展平成[batch_size, 特征长度]以便输入全连接层。算它的由来很简单经过两次卷积和两次池化后输入 32×32 的图片会变成 6×6 的特征图通道数为 16所以是16 * 6 * 6。4.6 数据加载与预处理PyTorch 中数据部分主要由torch.utils.data.Dataset和DataLoader完成。Dataset 定义“如何取数据”DataLoader 定义“如何高效批量加载数据”。以手写数字数据集 MNIST 为例注意本文案例计划使用 Fashion-MNIST服装分类数据集它和 MNIST 图像尺寸一致但分类难度略高更适合作为入门案例。你需要保证网络可以访问对应数据源第一次运行会自动下载。import torchvision import torchvision.transforms as transforms # 数据预处理转为 Tensor 并归一化 transform transforms.Compose([ transforms.ToTensor(), transforms.Normalize((0.5,), (0.5,)) ]) # 训练集 train_dataset torchvision.datasets.FashionMNIST( root./data, trainTrue, downloadTrue, transformtransform ) # 测试集 test_dataset torchvision.datasets.FashionMNIST( root./data, trainFalse, downloadTrue, transformtransform ) # DataLoader每批 64 张训练时打乱顺序 train_loader torch.utils.data.DataLoader( train_dataset, batch_size64, shuffleTrue ) test_loader torch.utils.data.DataLoader( test_dataset, batch_size64, shuffleFalse )Fashion-MNIST 中每张图片是 28×28 的灰度图但因为它是单通道所以在 LeNet 里的nn.Conv2d(1, 6, ...)输入通道仍然是 1。不过 LeNet 原始设计是针对 32×32 输入我们需要在预处理中增加一个 Resize 操作或者把网络适配为 28×28。为了简单下面的代码里我直接把transform中加入Resize((32, 32))这样就能对应上16 * 6 * 6的展平维度。transform transforms.Compose([ transforms.Resize((32, 32)), transforms.ToTensor(), transforms.Normalize((0.5,), (0.5,)) ])4.7 完整训练循环接下来是 PyTorch 中最核心的主干代码。虽然看起来只有几十行但它是所有深度学习项目的骨架值得逐行读懂。import torch import torch.nn as nn import torch.optim as optim # 选择设备 device torch.device(cuda if torch.cuda.is_available() else cpu) model LeNet(num_classes10).to(device) # 损失函数和优化器 criterion nn.CrossEntropyLoss() optimizer optim.Adam(model.parameters(), lr0.001) # 训练轮数 num_epochs 5 for epoch in range(num_epochs): model.train() running_loss 0.0 correct 0 total 0 for images, labels in train_loader: images, labels images.to(device), labels.to(device) # 清零梯度 optimizer.zero_grad() # 前向传播 outputs model(images) # 计算损失 loss criterion(outputs, labels) # 反向传播 loss.backward() # 更新参数 optimizer.step() running_loss loss.item() # 计算训练集准确率 _, predicted torch.max(outputs, 1) total labels.size(0) correct (predicted labels).sum().item() train_acc 100.0 * correct / total print(fEpoch [{epoch1}/{num_epochs}], Loss: {running_loss/len(train_loader):.4f}, Acc: {train_acc:.2f}%)这段代码里的几个关键点model.train()和之后的model.eval()是设置训练/评估模式影响 Dropout 和 BatchNorm 的行为。optimizer.zero_grad()必须放在前向传播之前否则梯度会累积。loss.backward()计算梯度optimizer.step()用梯度更新参数。torch.max(outputs, 1)返回每个样本的预测类别索引。4.8 测试与评估训练完成后需要在测试集上做验证判断模型的泛化能力。注意评估时不需要计算梯度可以使用torch.no_grad()加快计算并降低显存占用。# 切换到评估模式 model.eval() correct 0 total 0 with torch.no_grad(): for images, labels in test_loader: images, labels images.to(device), labels.to(device) outputs model(images) _, predicted torch.max(outputs, 1) total labels.size(0) correct (predicted labels).sum().item() print(f测试集准确率: {100.0 * correct / total:.2f}%)预期输出的测试集准确率应该在 90% 左右因为 Fashion-MNIST 的完整训练需要更多轮数这里只用来演示完整流程。如果你想提高准确率可以增加训练轮数、调整学习率、加入数据增强。4.9 模型保存与加载模型训练完成后需要保存方便下次直接加载。# 保存模型权重 torch.save(model.state_dict(), lenet_fashion_mnist.pth)加载时先实例化模型再load_state_dictmodel LeNet(num_classes10) model.load_state_dict(torch.load(lenet_fashion_mnist.pth, map_locationcpu)) model.eval()这里map_locationcpu表示即使模型是在 GPU 上训练的也能在 CPU 机器上加载。5. 常见问题与排查思路下面这些问题是新手在跑 PyTorch 代码时最容易遇到的我按问题现象整理成表。问题现象常见原因解决思路torch.cuda.is_available()返回 FalsePyTorch 装成了 CPU 版本卸载后按官网命令安装对应 CUDA 版本安装 PyTorch 后报CUDA error: no kernel image is availableCUDA 版本和驱动不匹配检查nvidia-smi驱动版本选择匹配的 CUDA 版本运行报RuntimeError: shape [...] is invalid for input of size ...网络全连接层维度计算错误打印特征图实际形状动态计算展平后维度模型训练时显存不足batch_size 太大或图片尺寸太大调小 batch_size、降低图片分辨率、使用混合精度DataLoader 在多进程时报错Windows 下多进程启动问题把训练代码放到if __name__ __main__:中训练后期 loss 变成 NaN学习率过大、数据未归一化检查输入范围、降低学习率5.1 设备相关报错最典型的是在 GPU 不可用的时候把模型和数据都推到了cuda。比如device torch.device(cuda) model.to(device)一旦你的电脑没有 GPU 或 PyTorch 没安装 CUDA 版本运行到model.to(device)就会报错。更稳妥的写法是先判断再设置device torch.device(cuda if torch.cuda.is_available() else cpu)5.2 张量形状不匹配新手最常见的报错是RuntimeError: mat1 and mat2 shapes cannot be multiplied原因往往是卷积层输出的展平维度和全连接层的输入维度不一致。排查方法是把前向传播中的view操作前临时打印一下形状def forward(self, x): x self.features(x) print(卷积输出形状:, x.shape) x x.view(x.size(0), -1) x self.classifier(x) return x有了实际形状你就能准确知道自己全连接层的输入维度应该是多少。5.3 训练结果不收敛排除代码 bug 后最常见的原因有三个学习率设置不合理。太大容易震荡甚至 NaN太小收敛极慢。数据没有归一化。灰度图本来范围在 0-255如果直接用网络训练会非常不稳定。损失函数选择错误。多分类场景下非多标签问题一般用nn.CrossEntropyLoss()不要在输出层再加 Softmax 后再接 NLLLoss。6. 最佳实践与工程建议代码能跑通是一个层次在真实项目中稳定迭代是另一个层次。下面分享几个在项目实战中比较重要的习惯。6.1 固定随机种子深度学习涉及大量随机性包括模型初始化、数据打乱顺序、Dropout 等。如果不固定随机种子同样的代码两次训练结果可能完全不同不利于实验对比。import random import numpy as np import torch def set_seed(seed42): random.seed(seed) np.random.seed(seed) torch.manual_seed(seed) torch.cuda.manual_seed_all(seed)在训练脚本开头调用set_seed(42)可以让实验结果更容易复现。注意由于 GPU 并行计算的原子操作不确定性完全复现依然可能存在极小误差。6.2 使用 GPU 时注意数据搬运在训练循环中我会经常看到新手反复把数据从 CPU 搬到 GPU造成严重性能瓶颈。正确的做法是在训练开始前把模型放到设备上。每个 batch 的数据统一to(device)。不要在循环内部频繁创建新张量。另外DataLoader中设置num_workers可以加快数据读取但不是越大越好。在 Windows 上如果设置过大反而可能报错建议从 2 或 4 开始测试。6.3 使用 TensorBoard 记录训练过程PyTorch 自带torch.utils.tensorboard可以记录 loss、准确率、模型结构、特征图等信息。相比直接 printTensorBoard 更适合跟踪长时间训练过程。from torch.utils.tensorboard import SummaryWriter writer SummaryWriter(runs/lenet_exp) # 在每个 epoch 最后记录 writer.add_scalar(Loss/train, running_loss / len(train_loader), epoch) writer.add_scalar(Acc/train, train_acc, epoch) # 结束后关闭 writer.close()启动可视化tensorboard --logdirruns然后在浏览器打开默认地址即可查看。6.4 考虑模型部署时的转换问题如果你后续想把 PyTorch 模型部署到服务端或移动端建议在训练阶段就考虑导出格式。常用方案是导出为 ONNX# 导出为 ONNX 示例 dummy_input torch.randn(1, 1, 32, 32).to(device) torch.onnx.export( model, dummy_input, lenet.onnx, input_names[input], output_names[output], dynamic_axes{input: {0: batch_size}, output: {0: batch_size}} )ONNX 格式可以在多个推理引擎中运行是通往生产环境的常用中间格式。6.5 不要直接在生产环境训练生产环境讲求稳定性、可观测性、资源隔离。即便你只是学习也要养成好习惯训练任务放在独立环境中运行只导出推理模型用于生产不要把训练过程和线上服务混在一起。7. 学习路线与下一步建议如果你已经跑通了上面的 Fashion-MNIST 分类案例说明你掌握了 PyTorch 的核心使用流程。接下来可以按下面的顺序继续深入学习如何处理自己的数据集。包括自定义Dataset、图片读取、数据增强。学习更现代的模型结构。比如 ResNet、Vision TransformerViT以及 Hugging Face Transformers 的用法。学习训练优化技巧。包括学习率调度、早停、正则化、混合精度训练。学习分布式训练和模型部署。包括多卡训练、ONNX 导出、TensorRT、TorchServe 等。如果你正在准备面试或做研究项目建议关注 PyTorch 生态中与 Transformer、大模型微调相关的内容这是当前实际应用中最活跃的方向。学习时重点从“框架怎么用”转向“模型怎么设计、训练怎么优化”这个阶段的进步会很快。最后再说回框架选择的问题。选 TensorFlow 还是 PyTorch本质上没有标准答案但有一个比较务实的原则在学习和研究阶段选社区资源更丰富、代码更易读的框架在团队和产品阶段选已有技术栈和部署生态更成熟的框架。对我个人而言如果今天有人让我推荐一个入门路径我会建议从 PyTorch 开始因为它的学习曲线更平滑写起来也更像普通 Python 代码。等你把模型原理和训练流程都吃透了再去了解 TensorFlow 的部署方案会发现很多概念都是相通的。
返回列表