2024 年提起 tensorflow,不少人的第一反应是“过气网红”“都去用 PyTorch 了”。我身边做算法的朋友,三年前从 TensorFlow 切到 PyTorch 之后就没再回头看过一眼,一说 TensorFlow 就摇头。但最近因为要维护一个老项目,我硬着头皮把 TensorFlow 2.x 从零装了一遍,顺手把当前生态也摸了一圈。装完跑通模型那一刻我最大的感受是:这个框架离“劝退”很远,离“好用”也有一段距离,关键看你会不会绕开那些坑。
这篇东西不是官方文档翻译,也不是卖课推广。我会从 2024 年 TensorFlow 的真实处境说起,把安装环节最容易让人放弃的几个点掰开揉碎,然后带你把 Tensor、Keras、tf.data 这条最短上手路径走一遍,最后聊聊 TensorFlow 和 PyTorch 的 2024 年局势,以及我个人在实际项目里怎么选型。
如果你正准备装 TensorFlow、在 TF 和 PyTorch 之间纠结、或者当年被 TF 1.x 劝退想回坑,这篇应该能用得上。
1. TensorFlow 在 2024 年的真实处境:别被“过气”两个字骗了
1.1 热度确实降了,但降的是话题度而不是使用量
打开各种社区的热搜词,tensorflow 的讨论热度在 2024 年确实不比 PyTorch。但你要分辨一件事:**讨论热度和生产环境使用量是两码事。**论文代码仓库里 PyTorch 的多,这是事实;但工业界存量系统里 TensorFlow 的占比依然非常可观,很多公司的推荐系统、搜索排序模型、端侧推理链路,底层还是 TF 或者 TF Lite。你上招聘网站看岗位要求,不少偏工程方向的深度学习工程师职位仍然明确写着 TensorFlow。
我自己的体感是,tensorflow 在 2024 年的角色有点像 Java——论话题热度永远比不过新语言,但企业级存量就是大。新人可能觉得它不性感,老团队却不敢随便把核心链路换掉,因为整套部署体系、监控、调优经验都长在这个框架上。换成 PyTorch 表面是换 API,实际上把上线后那一整套配套工具链全得重来一遍,成本极高。
1.2 2.x 版本之后,当年劝退你的东西基本都改了
很多人对 TensorFlow 的坏印象还停留在 1.x:session、placeholder、Graph 先构建再运行,调试一个张量形状要来回折腾。坦率说,TF 1.x 那套设计确实反人类,我自己当年也被折磨得不轻。但 TensorFlow 2.0 是 2019 年的事,到 2024 年已经迭代了好几个大版本,默认就是 Eager Execution(动态执行),跟 PyTorch 一样写代码即时出结果,同时保留了 @tf.function 和 SavedModel 做部署。
还有一个变化容易被忽略:Keras 已经从“TensorFlow 的玩具高级 API”长成了核心入口。官方推荐的上手姿势就是tf.keras,你写出来的代码跟 PyTorch 的torch.nn.Module风格差别没那么大了。如果你拿现在的 TensorFlow 2.x 和五年前的 TensorFlow 1.x 比,基本是两个框架。
1.3 2024 年选 TensorFlow 仍然顺手的几类场景
我不是来拉人回坑的,只是说清楚哪些场景选它依然合理:
- 移动端和嵌入式部署:TF Lite 这几年沉淀很好,量化、裁剪工具链成熟,比你自己手搓推理引擎省太多事。
- 已有 TF 存量项目:团队代码、线上模型、监控系统都是 TF 的,硬切 PyTorch 等于给公司找事。
- 想系统理解计算图优化的人:TF 的 SavedModel 和 tf.function 让你能真切看到“动态图如何转静态图”,这套思维方式在推理引擎优化里非常值钱。
- 喜欢 Keras 这种极简 API 的初学者:如果你不想一上来就研究
torch.utils.data和自定义训练循环,Keras 的compile+fit一次到位。
反过来,如果你要做的是纯研究探索、天天改模型结构、依赖最新论文的社区实现,那 PyTorch 的生态确实更舒服。这个结论很现实,没必要嘴硬。
2. 安装 TensorFlow:最容易让人放弃的第一关,我全踩了一遍
2.1 先把 Python、CUDA、cuDNN 三者关系搞明白
装 TensorFlow 最大的拦路虎不是框架本身,而是环境匹配。很多人第一步就死在pip install tensorflow之后import报错,或者 GPU 识别不出来。
先说核心逻辑:TensorFlow 通过 CUDA 调用 NVIDIA 显卡,通过 cuDNN 加速卷积等算子。这两者不是“装得越新越好”,而是要跟 TensorFlow 官方要求的版本对上。你单独装一个最新版 CUDA 往往适得其反。2024 年 TensorFlow 2.x 的部分版本还开始涉及 TensorRT / XLA 的配合,自己手动逐一对版本纯属给自己找麻烦。
我比较推荐你按这三条路线之一来:
| 路线 | 适合谁 | 一句话建议 |
|---|---|---|
| CPU-only | 入门学习、数据量小、没独显 | pip install tensorflow装完就能跑,别折腾 CUDA |
| pip 装 GPU 支持 | Linux 用户 | pip install tensorflow[and-cuda],一条命令帮你把配套 CUDA 依赖装好 |
| 官方 Docker 镜像 | 不想碰环境依赖的人 | 拉tensorflow/tensorflow:latest-gpu镜像,开箱即用 |
2.2 我的推荐流程:虚拟环境 + pip,三步搭好
先说为什么必须用虚拟环境。我见过太多人图省事,直接在系统 Python 里pip install tensorflow,然后某天装别的包时把依赖一升级,TensorFlow 就崩了,还找不到是谁干的。虚拟环境你能随时删掉重来,成本极低。
完整过程这样:
python -m venv tf_env source tf_env/bin/activate # Windows 是 tf_env\Scripts\activate pip install --upgrade pip pip install tensorflow有 NVIDIA 显卡并且是 Linux 的朋友,把最后一行换成:
pip install tensorflow[and-cuda]装完别急着跑模型,先验证一下:
python -c "import tensorflow as tf; print(tf.__version__); print(tf.config.list_physical_devices('GPU'))"如果能看到 GPU 列表,说明 GPU 支持正常;如果打印为空,说明你装的是 CPU 版,或者 CUDA 对应的动态库没被识别到。这时候不要慌,回到 2.1 看路线选择,多数情况是你在自己装 CUDA 时版本没对齐。
2.3 踩坑记录:最容易出问题的五个点
我这次装的时候特意把老项目从 TF 1.15 升到 2.x,直接撞了一串问题,列出来给你省时间:
| 现象 | 根因 | 处理办法 |
|---|---|---|
| pip 下载到一半超时 | 网络到默认源不稳定 | 用国内 PyPI 镜像源,比如清华或阿里的源 |
Windows 下DLL load failed | 缺微软 VC++ 运行库,或环境里同时装了多个 TensorFlow 版本 | 装 VC++ 2015-2022 Redistributable,把环境清理干净重装 |
报cudart64_12.dll not found | CUDA 库路径没配对 | 优先用tensorflow[and-cuda]或 Docker,别再手动配 CUDA |
| 显卡利用率上不去,总报显存不足 | 其他进程占了显存,或 TF 默认一次性申请全部显存 | 代码里开启显存动态增长,见下方示例 |
| 装完 TensorFlow 后别的包崩了 | protobuf 等依赖版本被显式指定过 | 让你自己安装的 protobuf 版本和 TF 要求保持一致,或干脆别手动指定 |
显存动态增长的代码值得单独贴出来,因为它能解决很多“刚 import 就 OOM”的问题:
import tensorflow as tf gpus = tf.config.experimental.list_physical_devices('GPU') if gpus: try: for gpu in gpus: tf.config.experimental.set_memory_growth(gpu, True) except RuntimeError as e: print(e)这段我在自己机器上测试过:设了 memory growth 之后,TF 不是启动就把整张卡显存占了,而是按需分配。你做实验的时候不会因为显存占用太大把别人也登录到这张卡上的进程挤掉。
3. 上手 TensorFlow 2.x:从 Tensor 到模型的“最短路径”
3.1 先弄明白 Tensor:一切数据都是它
TensorFlow 里所有数据都装在 Tensor(张量)里。你可以粗暴地把它理解成 NumPy 的 ndarray 加上两大增强:一是能自动记录梯度,二是能在 GPU 上运行。学习的时候不用想得太玄,就先当多维数组用。
import tensorflow as tf import numpy as np x = tf.constant([[1.0, 2.0], [3.0, 4.0]]) print(x.shape) # (2, 2) print(x.dtype) # float32 y = x.numpy() # 转成 NumPy 数组numpy()这个转换很重要。很多人卡在“数据怎么喂给模型”“模型输出怎么转成 numpy”这类问题上,核心就记住三个词:tf.constant建张量,.numpy()转回数组,tf.cast转类型。
自动微分是 TensorFlow 的看家本领。用法也不复杂:
x = tf.Variable(3.0) with tf.GradientTape() as tape: y = x ** 2 grad = tape.gradient(y, x) print(grad) # 6.0用反直觉的方式理解:TensorFlow 在前向计算时把你的运算步骤“记了一笔账”,反向时根据这笔账按链式法则把梯度算出来。GradientTape就是那个账本。你不需要手动实现任何反向传播,框架全干了。
3.2 用 Keras 搭模型:别再自己写训练循环了
我在实际项目里见过不少新人的误区:一上来就研究怎么自定义训练循环、自己写 backprop,结果 API 没搞明白,反被一堆底层细节劝退。你只是想快速验证想法,用 Keras 的一行式 API 就够了。
表格化对比三种写法,你就知道自己该从哪边入手:
| 写法 | 适用场景 | 上手难度 |
|---|---|---|
| Sequential(顺序模型) | 简单堆叠的网络,全连接、卷积、RNN 串起来 | 最低 |
| Functional(函数式 API) | 多输入、多输出、分支结构 | 适中 |
| Subclassing(子类化) | 完全自定义前向逻辑 | 较高 |
一个最简可跑的示例,模型是两层全连接:
from tensorflow import keras model = keras.Sequential([ keras.layers.Dense(64, activation='relu', input_shape=(8,)), keras.layers.Dense(1) ]) model.compile(optimizer='adam', loss='mse')然后喂数据训练:
import numpy as np x_train = np.random.randn(1000, 8).astype('float32') y_train = np.random.randn(1000, 1).astype('float32') model.fit(x_train, y_train, epochs=20, batch_size=32)为什么推荐你先用 Keras?因为compile帮你配好了优化器和损失函数,fit帮你处理了 batch 循环、梯度下降、日志打印。这一套对应到 PyTorch 里,至少得手写二十多行训练代码,还要自己处理 device 和 DataLoader,对新手来说完全没必要。
等你想深入了,再把fit换成自定义训练循环,用GradientTape自己一步步来:
optimizer = keras.optimizers.Adam() for epoch in range(20): with tf.GradientTape() as tape: pred = model(x_train) loss = tf.reduce_mean(tf.square(pred - y_train)) grads = tape.gradient(loss, model.trainable_variables) optimizer.apply_gradients(zip(grads, model.trainable_variables))看到没有,跟 PyTorch 的“清空梯度、前向、算 loss、反向、step”五件套本质一模一样,只是 API 名字不同。
3.3 tf.data 和 tf.function:把性能吃满的关键
如果你只追求跑通,numpy 数组直接喂fit也能活。但数据量一上来,numpy 的瓶颈就出现了。TensorFlow 官方建议用tf.data.Dataset,它支持并行读取、预取、乱序、按批切分,这才是工程上该有的打开方式。
dataset = tf.data.Dataset.from_tensor_slices((x_train, y_train)) dataset = dataset.shuffle(1000).batch(32).prefetch(tf.data.AUTOTUNE) model.fit(dataset, epochs=20)prefetch的作用是让 CPU 预取数据和 GPU 计算并行起来。GPU 在算这一批的时候,CPU 同时准备下一批,流水线不空转。实测下来,数据准备充分的时候训练速度能差出一大截。
再说tf.function。它的工作方式很特别:把一个 Python 函数编译成 TensorFlow 计算图,执行的时候跳过 Python 解释器。我在一个模型推理场景里做过对比,加上@tf.function之后单次推理的耗时下降非常明显,因为省去了反复的 Python 层调度。
@tf.function def predict(inputs): return model(inputs)但这里有个经验之谈:debug 阶段别急着加@tf.function。加了之后报错信息会绕一圈,变量生命周期也变得隐晦,不利于排查。正确做法是先用动态图跑通逻辑,再对稳定模块加装饰做加速。工程里要快,但更快的是定位问题的速度。
3.4 模型保存加载:不同场景选不同格式
我自己吃过亏才记得牢:模型保存的问题,第一次玩 TF 的人必遇到“训练完不知道怎么把模型带走”。
到 2024 年,TF 里的模型格式这几种最常用:
| 格式 | 内容 | 适合场景 |
|---|---|---|
.keras | 模型结构 + 权重 + 优化器状态 | 本机继续训练、快速恢复 |
SavedModel(目录) | 计算图 + 权重 + 签名 | 生产部署、TF Serving |
.h5 | 老式 HDF5 固定权重 | 历史兼容 |
保存和加载代码非常直接:
model.save('my_model.keras') model = keras.models.load_model('my_model.keras') # 如果要部署,导出 SavedModel model.export('saved_model_dir')需要注意,model.save('xx.keras')会把这套训练配置完整保存下来,加载回去可以直接继续fit。而model.export()相当于生成一个冻结好的服务端点,更接近“生产包”的概念,不适合再继续训练。两个别混用。
4. TensorFlow 与 PyTorch 的 2024 年走势:别再为框架站队
4.1 热搜词背后的信号:论文圈和工业圈正在分层
2024 年搜 tensorflow 和 pytorch,热度差异很说明问题。一个直观事实是:新发的论文、开源代码仓库,用 PyTorch 的越来越多。原因也简单——它写起来无拘无束,跟 Python 的原生风格最贴近,适合快速验证想法。这样社区研究者就自发形成了正循环:代码是 PyTorch 的,讨论是 PyTorch 的,新人也跟着学 PyTorch。
但 TensorFlow 没有坐以待毙。它在生产侧的长处依然明显:TF Serving 部署、模型量化、端侧推理的链路成熟度还是很高的。另一个容易被忽略的点是 Keras 3 的多后端能力:同一套 Keras 代码可以在 TensorFlow、JAX、PyTorch 之上运行。也就是说,两个框架在高层 API 层面已经开始“互相兼容”了,争论哪个更好变得越来越没意义。
4.2 拿问题去匹配框架,而不是拿立场去选框架
我给身边人做选型建议的时候,从来不说“你学哪个更有前途”,而是先问几个问题:
| 你的实际需求 | 更顺手的框架 |
|---|---|
| 部署到 Android / iOS / 嵌入式设备 | TensorFlow Lite 经验更厚 |
| 服务端高并发模型推理 | TF Serving 早已大规模验证 |
| 做研究、跑新论文、快速改结构 | PyTorch 更灵活,社区代码多 |
| 团队已有 TF 存量代码 | 继续用 TF,减少重构风险 |
| 入门学习想理解“训练系统”全貌 | TF + Keras 的学习曲线更平缓 |
这套逻辑我个人用了很多年:**技术选型永远是被约束条件逼出来的,不是被流行度投票投出来的。**你没有目标的选型,通常会在学完两个框架之后还是不知道怎么干活。
4.3 如果你想从 PyTorch 切回 TensorFlow,低成本迁移方案
有些朋友可能在 PyTorch 里写过不少代码了,突然被迫回 TF 做项目。这时候别硬啃 TF 1.x 旧教程,直接按 API 对应关系迁移:
torch.nn.Module对应tf.keras.Modeltorch.utils.data.DataLoader对应tf.data.Datasettorch.optim.Adam对应tf.keras.optimizers.Adamloss.backward()对应tape.gradient()+apply_gradients()
我的建议是:先不要学自定义训练循环,老老实实用Sequential或FunctionalAPI 配合compile+fit跑通一个小模型。等模型跑起来了再逐层拆开研究内部机制。这样你看到的不是“另一个框架”,而是“同一套深度学习流程换了层皮”,心理阻力会小很多。
5. 实测经验与一点个人建议
5.1 我从这次回坑中总结的几条“保命”习惯
这次重新捡起 TensorFlow,我给自己立了几条规矩,也算是在几次环境崩溃之后总结出的血泪经验:
- 永远在虚拟环境里装,不用系统 Python。虚拟环境成本几秒钟,删掉重来不心疼,总比把机器弄脏好。
- 不要额外
pip install keras。TensorFlow 自带tf.keras,如果你想用最新的 Keras 3 做多后端,建议也别在同一个环境里跟 TensorFlow 抢依赖。 - 显存动态增长的代码从第一天就加上,别等 OOM 爆了再补。
- 数据 pipeline 用
tf.data而不是纯 numpy。前期可能觉得多写几行麻烦,但数据量一上来你就知道值了。 - 每个大模型跑完立刻导出 SavedModel,而不是只留在
fit的历史记录里。部署的时候你会感谢自己。
5.2 一个老用户的真实心态
很坦诚地说,我在 2024 年重新装完 TensorFlow,心里是有点反思的。当年觉得它反人性的那些设计——Graph、Session、占位符——2.x 之后基本消退了。它的更新速度确实没有 PyTorch 那边热闹,论文生态确实没那么活跃,但它把工业部署和端侧推理这一块扎扎实实做深了。
工具选择这种事,真的不必非得站队。我见过只学 TensorFlow 的人顺利落地线上推荐模型,也见过只会 PyTorch 的人把论文复现得飞快。最终让你值钱的,是对训练、推理、部署这条链路整体逻辑的理解,而不是某个框架的 API 背得有多熟。如果你还在犹豫先学哪个,就抓阄吧,先跑通一个再说。框架只是手电筒,你才是那个要摸黑往前走的人。