深度学习入门最常被问到的几个问题里,一定包含“应该先学 PyTorch 还是 TensorFlow”。这个问题表面上只是两个框架二选一,背后实际对应三个更具体的问题:你准备用深度学习解决什么任务,你当前的机器能把哪个环境先跑通,以及你希望在多大程度上控制模型的训练过程。如果只盯着“哪个教程评价更高”,很容易陷入反复比较却始终没有动手的循环。下面会沿着一条可复现的路线展开:先理解两个框架的设计差异,再准备环境,接着用同一个最小分类任务跑通两个框架,最后聊一聊工程部署、常见问题和选型决策。这套流程走完,你至少能自己判断该从哪里开始。
1. 先搞清楚框架之争在争什么
1.1 为什么新人会卡在这个问题上
深度学习框架本质上做的事情是:把网络结构定义成可计算的图,自动计算梯度,并利用 GPU 加速训练。PyTorch 和 TensorFlow 在早期分别代表了两种设计思路:动态计算图和静态计算图。PyTorch 在代码运行时逐行构建计算图,写起来接近普通 Python 程序,调试时可以直接打印中间张量;TensorFlow 1.x 则更像先定义一张完整计算图,再放到会话中执行,好处是部署时可以整体优化,坏处是调试不够直观。
TensorFlow 2.0 之后默认开启了 eager 模式,也提供了 Keras 高层 API,因此两个框架在入门体验上的差距已经明显缩小。不过它们设计时的定位差异仍然会体现在后续的代码风格和部署生态里。很多课程、论文复现、竞赛代码默认使用 PyTorch,而不少企业级平台、移动端和嵌入式方案仍然基于 TensorFlow 或在其生态上扩展。
新人会被这个问题困住,通常不是因为两个框架真的无法选择,而是因为缺少一个“先跑通最小模型”的目标。在没有目标的情况下,框架对比、教程评价、资料多少都会变成噪音。更好的方式是先把问题缩小到:我的第一个深度学习程序要在哪个环境里跑起来,要完成一个什么样的任务。
1.2 PyTorch 与 TensorFlow 的核心定位差异
可以把差异理解为“编程体验”和“部署生态”的不同侧重点,而不是单纯的优劣。PyTorch 的默认工作流非常接近研究代码:你需要自己写训练循环,自己控制 batch 的迭代,自己调用loss.backward()计算梯度。这套过程对初学者其实很有价值,因为自动求导虽然省事,但你不应该完全不知道梯度从哪里来。
TensorFlow 的 Keras 高层 API 则把训练过程封装得更彻底。一个model.fit()可以完成数据迭代、梯度计算、参数更新和验证集评估,代码量更少,适合快速验证。但封装度高也意味着出问题时,排查链路更长,尤其是当模型行为不符合预期时,你需要在封装层里找到对应的回调或执行细节。
下面的表格可以做一个快速对照:
| 比较维度 | PyTorch | TensorFlow |
|---|---|---|
| 默认编程风格 | 命令式,逐行构建动态图 | 命令式 + Keras 高层 API,也保留静态图部署能力 |
| 模型定义 | 继承nn.Module,实现forward | 常用Sequential或函数式 API 堆叠层 |
| 训练过程 | 手动 for 循环,暴露梯度计算细节 | compile+fit,高层封装 |
| 调试方式 | 可以直接打印中间张量,与 Python 调试器配合自然 | 也可以打印,但高层封装下部分堆栈较绕 |
| 部署生态 | TorchScript、ONNX、PyTorch Serve | SavedModel、TF Serving、TFLite、TF.js |
| 典型场景 | 论文复现、课程实验、算法验证、竞赛 | 企业服务、移动端、已有 TensorFlow 基础设施 |
这张表不是告诉你“必须学哪个”,而是告诉你“哪个更匹配你现在的场景”。如果你是学生,需要尽快复现论文或完成课程作业,PyTorch 的默认工作流通常更接近你要看的代码。如果你所在团队已经有完整的 TensorFlow 服务链路,或者你准备做移动端模型部署,TensorFlow 的生态更值得优先熟悉。
1.3 教程数量和“公认”并不等于可复现
网络上很多标题会写“公认最好”“全套教程”“一网打尽”,这类说法能吸引点击,但很难作为技术选型依据。教程的真正价值取决于三点:环境是否可复现,代码能否直接运行,报错之后能否继续往下排查。一个教程如果只是概念讲得漂亮,却要求读者使用已经过时的 API,或者安装步骤隐藏了一堆环境假设,那么它对你完成第一个项目的帮助很有限。
更务实的做法是:选择一套语言简洁、版本明确、代码能形成最小闭环的教程,然后在自己的机器上一步步操作。遇到报错不要第一时间怀疑资料,先检查环境路径、依赖版本和输入数据是否符合预期。框架的选择始终服务于一件事:让你能尽快把想法转化成可运行、可验证的程序。
2. 学习框架之前的共识:环境准备比框架本身更容易卡住
2.1 先确定硬件和系统
深度学习环境可以分为三类:纯 CPU 环境、带 NVIDIA GPU 的 PC/服务器、嵌入式平台如 Jetson。CPU 环境完全可以用于学习最小模型,比如后面要写的两层全连接网络,训练时间可以接受;GPU 环境能明显加速训练,但多出来的驱动、CUDA、cuDNN 匹配问题往往比框架安装本身更耗时;Jetson 平台则依赖 JetPack 版本,不能直接照搬 PC 的 pip 安装命令。
| 环境类型 | 适合场景 | 主要风险 |
|---|---|---|
| CPU | 语法学习、最小示例、验证代码流程 | 大模型训练很慢 |
| NVIDIA GPU | 常规深度学习实验和业务训练 | CUDA 版本、显卡驱动、框架 wheel 不匹配 |
| Jetson / 嵌入式 | 边缘推理、机器人、嵌入式视觉 | PyTorch 版本与 JetPack 强绑定 |
实际项目中,很多新手并不是不会写模型,而是把一整天时间耗在安装和依赖上。所以环境准备阶段一定要慢下来,每一步都验证之后再进入下一步。
2.2 用虚拟环境隔离依赖
不同项目依赖的 Python 版本、CUDA 版本和框架版本可能不一样。不要把深度学习依赖直接装到系统 Python 里,否则项目一多很快就会冲突。推荐在项目目录下创建虚拟环境:
python -m venv dl_envLinux/macOS 激活:
source dl_env/bin/activateWindows 激活:
dl_env\Scripts\activate激活后先升级 pip:
python -m pip install --upgrade pip创建虚拟环境的目的是让 PyTorch、TensorFlow、NumPy 等依赖互相隔离。每个实验项目使用独立环境,出现问题时可以直接删除重建,不会影响其他项目。
2.3 PyTorch 与 TensorFlow 的安装命令
PyTorch 官方安装页会根据你的操作系统、包管理工具和 CUDA 版本生成命令。这里需要先知道两个概念:显卡驱动和 CUDA Toolkit。驱动层面可以用nvidia-smi查看,PyTorch 的 wheel 包通常会自带对应 CUDA 运行库,但需要和你的驱动版本兼容。
如果是纯 CPU 环境,可以安装 CPU 版本:
pip install torch torchvision torchaudio如果需要 GPU 版本,通常使用官方 index-url。下面的命令是常用写法,实际版本号以官方页面为准:
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121TensorFlow 的安装相对直接。在 Linux 上通常一条命令即可:
pip install tensorflow如果只需要 CPU 版本,可以安装tensorflow-cpu。要注意 TensorFlow 2.18 这类较新版本对 Python 版本有明确要求,安装前先看官方发布说明。不要凭记忆选版本,尤其是旧教程里的安装命令,很可能对应的是已不再维护的版本。
2.4 安装后的验证清单
安装完成后,不要急着写模型。先做几个最小验证,确认框架确实能正常工作。
PyTorch 验证:
import torch print(torch.__version__) print(torch.cuda.is_available())如果可以识别 GPU,再打印设备名称:
if torch.cuda.is_available(): print(torch.cuda.get_device_name(0))TensorFlow 验证:
import tensorflow as tf print(tf.__version__) print(tf.config.list_physical_devices('GPU'))验证时不要只看“能 import”,还要看版本号是否符合预期,GPU 是否真的被识别。可以跑一个很小的矩阵乘法,确认没有隐藏的链接错误。如果版本号带+cu字样,说明这是带 CUDA 支持的构建;如果安装了 CPU 版本,torch.cuda.is_available()返回False是正常的,不需要继续排查 GPU。
注意:不要只验证程序能启动,还要验证输入、输出、异常分支和日志是否符合预期。环境验证最重要的是把“当前环境到底是什么”记录下来,方便后面排错。
3. 用最小项目跑通两个框架,先不要追求复杂模型
3.1 为什么选择同一个最小分类任务
如果你一上来就去搭 ResNet 或 Transformer,很容易把“框架语法”和“模型原理”混在一起。模型结构复杂时,你很难判断报错原因是网络设计问题、数据 shape 问题,还是框架 API 使用问题。最小任务只需要用两层全连接网络把一组二分类数据分开,但已经覆盖了张量创建、数据加载、模型定义、损失计算、梯度更新、验证评估这些关键环节。
为了公平对比,两个框架使用同一个数据集、同一个网络结构、同一个优化器配置。
3.2 用 PyTorch 完成最小训练示例
先准备数据和数据加载器:
import torch import torch.nn as nn from torch.utils.data import DataLoader, TensorDataset from sklearn.datasets import make_moons from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler X, y = make_moons(n_samples=1000, noise=0.2, random_state=42) X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.2, random_state=42 ) scaler = StandardScaler() X_train = scaler.fit_transform(X_train) X_test = scaler.transform(X_test) X_train_t = torch.tensor(X_train, dtype=torch.float32) y_train_t = torch.tensor(y_train, dtype=torch.long) X_test_t = torch.tensor(X_test, dtype=torch.float32) y_test_t = torch.tensor(y_test, dtype=torch.long) train_ds = TensorDataset(X_train_t, y_train_t) train_loader = DataLoader(train_ds, batch_size=32, shuffle=True)定义模型:
class MLP(nn.Module): def __init__(self): super().__init__() self.net = nn.Sequential( nn.Linear(2, 16), nn.ReLU(), nn.Linear(16, 2) ) def forward(self, x): return self.net(x) model = MLP() loss_fn = nn.CrossEntropyLoss() optimizer = torch.optim.Adam(model.parameters(), lr=0.01)训练循环:
for epoch in range(20): model.train() total_loss = 0.0 for xb, yb in train_loader: optimizer.zero_grad() out = model(xb) loss = loss_fn(out, yb) loss.backward() optimizer.step() total_loss += loss.item() * xb.size(0) avg_loss = total_loss / len(X_train_t) print(f"epoch {epoch}, loss {avg_loss:.4f}")测试评估:
model.eval() with torch.no_grad(): pred = model(X_test_t).argmax(dim=1) acc = (pred == y_test_t).float().mean().item() print("test acc:", acc)PyTorch 的特点在这段代码里体现得很明显:训练循环是显式的,梯度清零、前向、反向、参数更新都在你自己的控制范围内。loss.backward()是自动求导的核心,它会根据计算图反向计算每个参数的梯度,然后由optimizer.step()更新参数。推理阶段通过model.eval()切换模型状态,用torch.no_grad()关闭梯度计算,节省内存和耗时。
3.3 用 TensorFlow 完成最小训练示例
TensorFlow 使用 Keras 高层 API,同一个任务的代码明显更短:
import tensorflow as tf from sklearn.datasets import make_moons from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler X, y = make_moons(n_samples=1000, noise=0.2, random_state=42) X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.2, random_state=42 ) scaler = StandardScaler() X_train = scaler.fit_transform(X_train) X_test = scaler.transform(X_test) model = tf.keras.Sequential([ tf.keras.layers.Dense(16, activation='relu', input_shape=(2,)), tf.keras.layers.Dense(2, activation='softmax') ]) model.compile( optimizer=tf.keras.optimizers.Adam(learning_rate=0.01), loss=tf.keras.losses.SparseCategoricalCrossentropy(), metrics=['accuracy'] ) model.fit(X_train, y_train, epochs=20, batch_size=32, validation_split=0.2, verbose=2) loss, acc = model.evaluate(X_test, y_test, verbose=0) print("test acc:", acc)TensorFlow 通过compile指定优化器、损失函数和评估指标,通过fit完成训练。validation_split=0.2表示从训练数据里再拿 20% 作为验证集。这里要说明一点:如果同时使用validation_split和单独的测试集,验证集和测试集是两个不同概念。验证集用于观察训练过程中的泛化情况,测试集用于最终评估。
SparseCategoricalCrossentropy适合标签是整数编号的分类任务,如果标签是 one-hot 编码,则应使用CategoricalCrossentropy。这是新手很容易踩的问题。
3.4 两个框架在同一个任务上的差异
| 环节 | PyTorch | TensorFlow/Keras |
|---|---|---|
| 数据加载 | 使用Dataset+DataLoader | 可以直接传入 NumPy 数组,也可以使用tf.data |
| 模型定义 | 继承nn.Module,手写forward | 使用Sequential堆叠层 |
| 训练入口 | 自己写 for 循环 | model.fit封装训练 |
| 梯度计算 | 显式调用loss.backward() | compile和fit中隐式完成 |
| 推理评估 | model.eval()+no_grad | model.evaluate/predict |
同样是两层全连接网络,PyTorch 更接近“教你理解神经网络如何训练”,TensorFlow 的 Keras API 更接近“快速得到结果”。对深度学习入门来说,两种路线都有价值。我的建议是:如果时间有限,先按一个框架跑通,但至少要把 PyTorch 里手动训练的这几个步骤理解清楚,因为它能帮你建立对训练循环的正确直觉。
4. 从第一个最小项目到真实项目:训练、验证、部署和监控
4.1 学习环境能跑通之后,生产环境还要补什么
本地 Jupyter Notebook 里模型能跑,不等于生产环境可用。实际项目还要补充这些能力:
- 配置外置化:训练参数、数据路径、模型路径不要写死在代码里,通过环境变量或配置文件管理。
- 日志与监控:记录训练 loss、验证指标、资源占用,以及推理阶段的延迟和错误率。
- 模型版本管理:模型文件要有版本号,训练代码和数据也要能对应到同一个版本。
- 数据校验:推理输入数据可能缺失、格式错误,需要提前定义校验规则。
- 权限与审计:谁访问了模型、谁发起了推理、谁修改了配置,生产环境都需要可追溯。
- 回滚方案:新模型效果不如旧模型时,要能快速切回旧版本。
这些能力不一定要在入门阶段全部实现,但你应该知道,从“跑通最小示例”到“上线一个服务”之间还有很长的工程距离。
4.2 模型保存与加载格式
训练结束后,模型需要持久化。PyTorch 常用的做法是保存state_dict:
torch.save(model.state_dict(), "mlp.pt")加载时需要先创建同样的模型结构,再加载参数:
model = MLP() model.load_state_dict(torch.load("mlp.pt")) model.eval()TensorFlow 的 Keras 模型常用SavedModel格式保存:
model.save("mlp_savedmodel")加载:
model = tf.keras.models.load_model("mlp_savedmodel")如果要在不同框架或不同运行时之间迁移模型,ONNX 是一个常见的中转格式。PyTorch 导出 ONNX 的方式如下:
dummy_input = torch.randn(1, 2) torch.onnx.export( model, dummy_input, "mlp.onnx", input_names=["input"], output_names=["output"] )ONNX 模型可以由 ONNX Runtime 加载,也可以继续转换到其他推理引擎。需要注意的是,ONNX 不是万能格式,一些自定义算子可能无法完整转换。落地前要针对目标推理引擎做充分验证。
4.3 部署场景怎么选
部署选型更多取决于运行环境:
| 部署场景 | 常用方案 |
|---|---|
| Python 服务 | PyTorch 可用 TorchScript、ONNX Runtime;TensorFlow 可用 SavedModel + TF Serving |
| 移动端 | TensorFlow Lite 较成熟;PyTorch 也有移动端方案,但生态相对少 |
| 浏览器端 | TensorFlow.js 是常见选择 |
| Jetson / 嵌入式 | 通常使用 TensorRT 或 ONNX Runtime,版本需匹配 JetPack |
嵌入式场景尤其要注意版本绑定。比如 Jetson 的 JetPack 6.2.2 支持哪些 PyTorch 版本、哪些 CUDA 版本,必须以 NVIDIA 官方支持矩阵为准。不要看到一篇博客说“这样安装成功”就直接照抄,先确认对方的 JetPack、Python、PyTorch 版本和你的环境是否一致。
4.4 框架之外同样重要的基础知识
框架只是工具,底层知识仍然很关键。入门阶段不必去啃完整数学推导,但至少要理解:什么是张量,什么是梯度下降,损失函数怎样衡量预测和真实值的差距,反向传播为什么能让参数更新,过拟合和欠拟合有什么区别。
后面学习 CNN 时,要能说清楚卷积、池化之后张量尺寸为什么变化;学习 Transformer 时,要能理解注意力机制和输入序列的关系。如果这些基础不补,遇到报错时你不知道该从模型结构、数据 shape、还是框架 API 三个方向去排查。正确的顺序是:先用最小模型建立框架手感,再回到深度学习基础补原理,最后再上复杂模型。
5. 常见问题排查:安装失败、GPU 不生效、版本不匹配
5.1 PyTorch 安装后torch.cuda.is_available()返回 False
现象:
import torch print(torch.cuda.is_available()) # False可能原因:
- 安装的是 CPU 版本。
- 显卡驱动版本过旧,与 PyTorch 自带的 CUDA 运行库不兼容。
- 系统没有识别到 NVIDIA 显卡。
检查方式:
nvidia-smi如果命令能输出显卡和驱动信息,说明驱动层面正常。接着查看 PyTorch 构建信息:
print(torch.__version__)如果版本号没有+cu后缀,说明是 CPU 版本。需要按官方 index-url 重新安装 GPU 版本。安装前在https://download.pytorch.org/whl/下选择与驱动兼容的 CUDA 版本。
注意:不要只对着教程抄安装命令,要先确认本机 CUDA 环境再选 index-url。GPU 版 PyTorch 对驱动版本有最低要求,驱动太老会导致程序运行时报 CUDA 初始化失败。
5.2 TensorFlow 识别不到 GPU
现象:
import tensorflow as tf print(tf.config.list_physical_devices('GPU')) # []可能原因:
- 安装了
tensorflow-cpu。 - CUDA、cuDNN 版本与 TensorFlow 版本不匹配。
- 在一个没有 GPU 的环境中运行。
检查方式:先确认安装的是哪个包:
pip show tensorflow再确认系统是否能识别显卡:
nvidia-smiTensorFlow 2.x 对 CUDA 和 cuDNN 版本有明确要求,需要查看官方兼容列表。如果版本不匹配,推荐创建一个新的虚拟环境,按官方要求安装对应版本,不要在同一环境里反复覆盖依赖。
5.3 Ubuntu 驱动安装后nvidia-smi没有反应
现象:在 Ubuntu 22.04 或 24.04 上安装驱动后,执行nvidia-smi提示找不到命令,或者显示 GPU 在,但训练时仍然无法使用 GPU。
可能原因:
- 安装了驱动但没有重启系统。
- 系统仍在使用开源的 Nouveau 驱动,和 NVIDIA 驱动冲突。
- Secure Boot 未配置,内核模块未能加载。
- 驱动安装命令不完整,只装了部分组件。
检查方式:
nvidia-smi lsmod | grep nouveau dmesg | grep -i nvidia如果lsmod输出有nouveau,说明开源驱动还在占用显卡。不同发行版屏蔽 Nouveau 的方式不同,需要按照当前系统版本的官方文档操作。如果dmesg里出现签名错误,则需要处理 Secure Boot 相关配置。不要为了解决这个问题去修改系统安全配置之外的东西,按官方文档来最稳妥。
5.4 Jetson 等嵌入式平台的 PyTorch 版本选择
Jetson 的软件栈和普通 PC 差异很大。JetPack 版本决定 CUDA、cuDNN、TensorRT 的可用版本,PyTorch 必须使用对应版本的预编译 wheel 或官方容器。如果你在 Jetson 上直接执行普通 PC 的 pip 安装命令,通常会得到不兼容的包,甚至无法 import。
正确做法是先确认 JetPack 版本,例如 JetPack 6.2.2,再从 NVIDIA 官方支持矩阵或官方容器源中找到匹配的 PyTorch 版本。不要仅凭“某论坛说能装”来安装,版本差一个主版本可能就会导致训练和推理行为不一致。
5.5 环境冲突排查顺序
遇到环境问题,建议严格按下面的顺序排查:
- 当前命令是否在正确的虚拟环境里执行,输入是否有拼写错误。
- 文件路径和命名是否正确,
pip show torch、pip show tensorflow确认安装位置。 - 依赖版本是否与操作系统、Python 版本、CUDA 版本匹配。
- 配置是否真的生效,环境变量、配置文件修改后是否需要重启。
- 驱动和硬件状态,
nvidia-smi是最直接的检查命令。 - 日志是否出现明确异常,把完整错误堆栈贴到搜索引擎,优先看官方 Issue。
| 问题现象 | 常见原因 | 检查方式 | 处理建议 |
|---|---|---|---|
| torch.cuda.is_available() 为 False | 装成 CPU 版本 | 查看 torch.version是否有 +cu | 按官方 index-url 重装 |
| TF 无法识别 GPU | 装了 tensorflow-cpu 或 CUDA 版本不匹配 | pip show tensorflow,nvidia-smi | 查看官方兼容矩阵并重建环境 |
| Ubuntu 装驱动后无反应 | 未重启或 Nouveau 冲突 | lsmod、dmesg | 按发行版官方文档处理 |
| Jetson 上安装失败 | 未匹配 JetPack 版本 | 查看 JetPack 和官方支持矩阵 | 使用官方预编译 wheel 或容器 |
6. 决策清单和下一步学习路径
6.1 用一张表辅助决定先学哪个框架
| 你的场景 | 优先建议 |
|---|---|
| 在校学生,需要复现论文或完成课程作业 | PyTorch |
| 课程或项目已经指定框架 | 先按指定框架来,不要中途换 |
| 企业后端已有 TensorFlow 服务 | TensorFlow |
| 准备做移动端模型部署 | TensorFlow Lite 生态更成熟,可优先 TensorFlow |
| 目标是嵌入式 Jetson 开发 | 先看 JetPack 支持矩阵再决定 |
| 完全新手,想最快看到模型效果 | TensorFlow Keras 的 fit 更快,但建议之后用 PyTorch 补一遍训练循环 |
这张表只是起点。实际工作中,团队和项目约束往往比个人偏好更重要。如果你所在团队用 PyTorch,那么你对 TensorFlow 的熟悉可以慢慢补;反之亦然。学会一个框架后,迁移到另一个框架的成本远低于从零开始。
6.2 最少必要学习路径
建议按下面的顺序走,不要在任意一步求快:
- 掌握 Python 和 NumPy 基础:数组操作、函数、类、切片、广播。
- 理解深度学习的核心概念:梯度下降、反向传播、损失函数、过拟合。
- 用最小模型跑通框架:数据加载、模型构建、训练、评估、保存和加载。
- 学习数据管线:PyTorch 的
Dataset/DataLoader,TensorFlow 的tf.data。 - 从 MLP 过渡到 CNN,重点理解卷积和池化后的张量 shape 变化。
- 再进入序列模型和 Transformer,不要跳过前面的基础。
- 最后补工程化能力:模型管理、部署、日志、监控、回滚。
每一步都要求能运行、能复现、能解释。只把代码跑通但不理解每一行在做什么,遇到真实问题时还是会卡住。
6.3 容易继续踩的坑
坑一:在 CPU 环境里安装了 GPU 版本,但没有显卡驱动。程序能跑,但训练慢,偶尔还会出现 CUDA 初始化失败。安装前先确认nvidia-smi是否可用,再选对应安装命令。
坑二:照着过时教程写 API。比如 TensorFlow 1.x 的Session、placeholder写法在 2.x 中已经不再推荐;PyTorch 某些接口也经历过变动。看到旧教程时,先看发布时间和版本号,再决定是否参考。
坑三:只背框架 API,不关注数据 shape。CNN 中一个常见的报错是卷积或池化后张量维度不匹配。这时候应该手动计算一下输入从(batch_size, channels, height, width)到输出 shape 的变化,而不是盲目加Flatten或调整全连接层尺寸。框架不会替你解决模型结构设计错误。
6.4 让第一个项目成为你的判断基准
从“选框架”到“跑通第一个模型”,真正有效的动作是动手。即使最后你选择的框架被证明不适合某个任务,你也会在这个过程中学到环境排查、数据准备、模型调试的能力,这些能力可以迁移到任何框架上。
建议今天只做一件事:按第 2 节的内容创建虚拟环境,安装一个框架,跑通第 3 节的最小分类示例,然后把运行结果和版本信息保存成一份环境记录文档。下一个项目开始时,你会感谢这份记录。它不是完美的选择,但比继续比较十个教程要有效得多。