拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

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

2024年TensorFlow实战指南:从安装到部署的踩坑经验

2024年TensorFlow实战指南:从安装到部署的踩坑经验 TensorFlow 这个名字估计只要碰过深度学习的朋友都绕不开。2024 年再聊它比前几年有意思多了一边是 PyTorch 在论文复现、学术社区里几乎成了默认选项另一边是 TensorFlow 在工业落地、移动端推理、服务端部署这些场景里依然有很强的存在感。我第一次跑 TensorFlow 是在 2017 年那时还得先建 Graph、定义 placeholder、用 sess.run 手动喂 feed_dict一个 MNIST 分类器都能写出一堆样板代码后来 Keras 进核心、Eager Execution 默认开启又经历了 TensorFlow 2 的 API 大一统说实话每次版本更迭我都要重新学一遍但这也是它的特点太敏捷敏捷到用户经常跟不上。这篇文章不打算像官方教程那样面面俱到我就从安装环境、模型编写、训练调试、部署选型这四个实务角度把这么多年实际踩出来的经验讲清楚适合想从零上手 TensorFlow 的人也适合在 TF 和 PyTorch 之间犹豫到底该学哪个的团队参考。1. TensorFlow 在 2024 年的真实生态位置1.1 学术退潮工业仍然坚挺在 2024 年说 TensorFlow 是“过气框架”的人大概率只在论文复现和 Kaggle 比赛里待过。看看 Arxiv 论文里的引用占比PyTorch 确实强势这没什么好嘴硬的。但换个视角工业界的线上模型推理、嵌入式设备、旧系统维护TensorFlow 的存量依然很大。我前两年接手的推荐系统项目训练部分早换成了 PyTorch但线上推理清一色用 TensorFlow Serving模型是从 PyTorch 转成 ONNX 再转 SavedModel 过去的。这种“训练用着顺手、部署要稳”的混搭状态其实是很多公司内部真实的样子。TensorFlow 真正的护城河在于它把训练、部署、移动端、量化、监控这一整条链路都收在自己体系里。PyTorch 虽然灵活但要凑齐一套工业级部署方案往往要额外接 torchserve、ONNX Runtime、TensorRT 等好几个组件。不能说哪个更好但 TensorFlow 的老用户大多有一种“虽然写 API 别扭但东西放进生产环境就很少闹心”的体感。这种体感很难量化却是团队选型时会真实考虑的因素。1.2 流行趋势热词背后的信号翻看 2024 年搜索热度“TensorFlow 与 PyTorch 的流行趋势”能成为高频热词本身就说明问题大量新人在两个框架之间摇摆。我的观点是趋势不等于适用框架热度这东西有很强的滞后性。PyTorch 热是因为学术社区和开源项目带动的TensorFlow 热度看起来降了但它的工程化沉淀没有消失。对一个初学者来说与其被热门榜牵着走不如先想清楚目标如果目标是发论文、快速验证想法PyTorch 更顺手如果目标是进企业做部署、维护线上模型TensorFlow 的老本行依然很值钱。而且两者知识可以迁移深度学习基础概念不绑定框架真没必要把选框架当成选宗教信仰。2. tensorflow 安装从“一行代码”到“半天折腾”的真实记录2.1 认识你的运行环境Python 版本和虚拟环境先别急着 pip install。TensorFlow 对 Python 版本有硬性要求盲目用系统自带 Python 直接装很容易出现依赖冲突或者装上了 import 就崩。我自己踩过的教训是不要相信“最新 Python 一定兼容最主流框架”这个想法TensorFlow 官方支持的 Python 版本通常落后于最新版本一两年。比如 2.14 之后官方才补上 Python 3.11 支持早期装 3.12 常常只能装预览版或者魔改版。建议先用 conda 或 venv 建一个独立环境Python 版本选官方文档里明确的稳定版本。这一步看起来多余但能挡住一半的玄学报错。建环境具体操作其实很简单。如果你用 condaconda create -n tf python3.11 conda activate tf如果不想装 conda也可以用 venvpython3.11 -m venv tf_env source tf_env/bin/activate # Windows 下是 tf_env\Scripts\activate虚拟环境的重要性怎么说都不为过。我见过不止一个同事直接在 base 环境里装各种包最后因为 opencv、numpy、pandas 互相卡版本把整个环境搞到不可用。TensorFlow 的依赖树非常深尤其牵扯到 numpy、protobuf、absl-py 这些底层库隔离环境能让你随便折腾坏了就删再建一个干净的 env成本几乎为零。2.2 CPU 版安装最稳妥的起步方案没有 NVIDIA GPU 或者只是想先跑通流程的话CPU 版就是最好的起点。安装命令就一行pip install tensorflow可别小看这一行它的两个隐藏问题我都要说一下。第一个是版本选择默认 pip 会给你装最新稳定版但如果你手上代码是老项目直接装最新版可能碰到 API 废弃甚至行为变化。所以老项目先看清楚 requirements 里写的版本再用pip install tensorflow2.15.0这种精确指定方式安装。第二个是 numpy 版本冲突TensorFlow 对新版 numpy 的兼容经常滞后最常见的报错是module numpy has no attribute object或者 dtypes 相关警告这种情况一般把 numpy 降到官方要求的版本就好。安装完先跑一句验证python -c import tensorflow as tf; print(tf.__version__)能打印出版本号只说明 import 成功还不代表你的 CPU 支持更快的指令集。玩到后面如果发现训练速度奇慢可以用python -c print(tf.config.list_physical_devices(CPU))检查一下再关注一下 TensorFlow 有没有输出 oneDNN 相关的日志。2.3 GPU 版安装CUDA 与 cuDNN 版本匹配才是关键CPU 版跑小模型没问题但你要是想训练稍微像样的模型GPU 几乎是必需品。GPU 版安装就是自己配环境的过程我把官方要求和实际经验折中一下给你一个相对稳的版本组合TensorFlow 版本建议 Python可用 CUDA对应 cuDNN2.133.8 - 3.1111.88.62.153.9 - 3.1112.28.92.163.9 - 3.1212.38.9注意我的经验是除非你已经很熟了否则不建议自己一遍一遍试版本组合。最省事的办法是直接看对应 TensorFlow 版本官方文档里的 GPU 说明但也不要被那个很长的配置清单吓到。实际上你只需要三个东西NVIDIA 驱动、CUDA Toolkit、cuDNN。驱动是最底层CUDA 是并行计算库cuDNN 是加速神经网络算子的库三者要形成一种“互相认识”的关系TensorFlow 才能正常用 GPU。有条件的可以用 NVIDIA 官方容器镜像比如tensorflow/tensorflow:2.15.0-gpu这种 Docker 镜像它已经把 CUDA 和 cuDNN 封装好了本地只要装好驱动就能直接用。这比我手动配本地环境省太多时间尤其是团队协作时大家用同一个镜像杜绝“我这边能跑你那边不能跑”的尴尬。如果你坚持裸机装切记不要用 pip 里那个tensorflow-gpu包名TensorFlow 2.0 之后 GPU 支持已经合并进tensorflow主包再装 tensorflow-gpu 只会装到一个没人在维护的旧版本。2.4 安装后验证别让“import 成功”骗了你import tensorflow成功不代表 GPU 真的在工作。见过太多人装完以为万事大吉结果模型训练全在 CPU 上慢慢爬。正确验证姿势是这样python -c import tensorflow as tf; print(tf.config.list_physical_devices(GPU))能看到一长串包含 GPU 名称的列表才说明 TensorFlow 找到设备了。接着跑一个真实的矩阵运算验证一下import tensorflow as tf with tf.device(/GPU:0): a tf.random.normal([1000, 1000]) b tf.matmul(a, a) print(b.device)出来的 device 字符串里写着 GPU 就是正常如果写着 CPU大概率是 CUDA/cuDNN 版本不匹配或者驱动太老。再一个很容易忽略的检查是训练日志开头的 warningTensorFlow 启动时如果检测到设备有问题会打印类似Could not load dynamic library cudnn64_8.dll的信息。遇到这种信息不要觉得“反正程序没崩就无所谓”后面训练的时候你会浪费大量时间早点解决版本问题才是正路。2.5 常见安装问题速查表我把自己和周围同事常碰到的安装问题整理成了张速查表报错/现象常见原因处理建议Could not load dynamic library cudnn64_*.dllcuDNN 缺失或路径不在系统 PATH 里确认 cuDNN 版本并加入环境变量或改用官方 Docker 镜像module numpy has no attribute objectnumpy 版本过高pip install numpy1.24.x或降到官方要求版本Illegal instruction (core dumped)CPU 不支持某些指令集安装旧版本 TensorFlow 或换机器检查容器基础镜像训练很慢但没报错GPU 没被识别按 2.4 的验证命令检查list_physical_devices(GPU)Python 3.12 装不上该版本尚未纳入官方支持换用官方支持的 Python 版本别自己硬刚这份表不用背真正遇到时回来看一眼就够。安装阶段的核心思路就一条版本对齐Python、TensorFlow、CUDA、cuDNN、numpy任何一个不齐都可能出问题而版本对齐没有捷径只能靠官方文档和自己的验证命令。3. 建模与训练从 Keras 到自定义过程的经验3.1 最快跑通Keras Sequential 模型这么写TensorFlow 2 之后默认的建模方式就是 Keras这也是大多数新手接触的第一个 API。Sequential 模型适合线性的网络结构输入从一层流到下一层不分支不交叉。我拿一个最经典的手写数字分类举个例import tensorflow as tf from tensorflow import keras from tensorflow.keras.datasets import mnist (x_train, y_train), (x_test, y_test) mnist.load_data() x_train x_train.astype(float32) / 255.0 x_test x_test.astype(float32) / 255.0 model keras.Sequential([ keras.layers.Flatten(input_shape(28, 28)), keras.layers.Dense(128, activationrelu), keras.layers.Dropout(0.2), keras.layers.Dense(10, activationsoftmax) ]) model.compile(optimizeradam, losssparse_categorical_crossentropy, metrics[accuracy]) model.fit(x_train, y_train, epochs5, batch_size32, validation_data(x_test, y_test))这段代码短但背后几个细节值得细说。sparse_categorical_crossentropy是给整数标签用的如果你的标签是 one-hot 编码就要换成categorical_crossentropy这两者用错是最常见的模型报错来源之一。activationsoftmax加在最后一层输出的是每个类别的概率分布在分类任务里别漏。validation_data直接传测试集虽然方便但正规流程里你应该把训练集再切一部分做验证测试集留到最后只用一次否则模型选型时容易“测试集过拟合”这一点初学者常犯。还有一处容易被忽略mnist.load_data()会从网络下载数据第一次跑可能比较慢。如果你在公司内网或者离线环境记得提前把数据集下载好放到~/.keras/datasets目录下不然会卡在联网下载那一步。这种数据文件的手动预置在团队里跑实验时是节约时间的好习惯。3.2 数据流水线别再把数据一次性读进内存新手用model.fit(x_train, y_train)传 numpy 数组很正常但一到真实项目就会发现内存根本装不下。TensorFlow 官方推荐的做法是用tf.data.Dataset把数据流水线化。它本质上是一个迭代器每次只取一个 batch 的数据进内存配合.map、.batch、.prefetch这些操作可以做到一边读数据一边训练互不等待。dataset tf.data.Dataset.from_tensor_slices((x_train, y_train)) dataset dataset.shuffle(10000).batch(32).prefetch(tf.data.AUTOTUNE)我给新手讲 Dataset 时最常用的比喻是流水线工厂shuffle是产品出库前随机打乱batch是装箱打包prefetch是提前把下一批货拉到出货口这样工人的手不用空等。tf.data.AUTOTUNE让 TensorFlow 自己根据硬件情况决定预取多少比手写一个固定数字更省心。如果你的数据量特别大还可以把数据写成 TFRecord 格式再用tf.data.TFRecordDataset读取。TFRecord 是一种二进制格式磁盘占用小、读取快缺点是写起来稍微麻烦。我的经验是数据量没到几十 GB 级别之前别提前引入 TFRecord 的复杂度用普通文件加 Dataset 管线就行。3.3 自定义训练循环复杂模型里更可控的写法model.fit确实方便但研究型项目的 loss 函数往往不只有一个或者要加自定义梯度惩罚这时候就需要接管训练循环。我建议不要一开始就上自定义等你理解了fit的默认行为再改也不迟。一个自定义训练的骨架长这样optimizer keras.optimizers.Adam(1e-3) loss_fn keras.losses.SparseCategoricalCrossentropy() train_loss keras.metrics.Mean(nametrain_loss) train_acc keras.metrics.SparseCategoricalAccuracy(nametrain_acc) tf.function def train_step(x, y): with tf.GradientTape() as tape: predictions model(x, trainingTrue) loss loss_fn(y, predictions) gradients tape.gradient(loss, model.trainable_variables) optimizer.apply_gradients(zip(gradients, model.trainable_variables)) train_loss(loss) train_acc(y, predictions)GradientTape是这套机制的核心它会自动记录前向传播中所有可微操作然后tape.gradient计算出梯度再将梯度应用到可训练变量上。这里面最大的坑是model(x, trainingTrue)的training参数。如果你忘了传 TrueDropout 和 BatchNorm 会进入推理模式训练结果会莫名其妙地变差而且这种错误通常不报错特别难排查。我一直建议在自定义循环里养成显式传training的习惯不管什么模型都一律写清楚。3.4 性能细节tf.function 和静态图背后的真相TensorFlow 2 默认开启 Eager Execution用起来像普通 Python但性能却可能吃亏。tf.function装饰器会把函数编译成计算图让 TensorFlow 做更多底层优化。我见过一个数据预处理函数Eager 模式下慢得不行加了tf.function之后速度快了将近 3 倍。不过它也不是灵丹妙药最常见的问题是用了 Python 原生控制流。比如tf.function def my_func(x): if x 0: # 这种写法不稳定 return x * 2 return x / 2只要x是 Tensor这个if就不能按普通 Python 逻辑运行。TensorFlow 会把它转换成tf.cond但如果判断条件涉及动态形状或者过于复杂就容易报错或产生不可预期的结果。正确做法是用tf.cond、tf.where、tf.while_loop这类张量级操作。另外tf.function第一次调用时需要做图编译会明显慢一点这是正常的不要误以为优化没生效。我的习惯是能批量向量化的操作写成张量运算实在写不了再用 Python 循环但循环外一定包一个tf.function来减少解释器开销。4. TensorFlow 与 PyTorch2024 年如何选型4.1 设计哲学动态图、静态图、JIT 的路线差异PyTorch 之所以在学术圈那么受欢迎核心原因是它的“动态图”设计你写 Python 的时候代码就是一行一行真的在执行中间可以随时打印、断点、修改张量调试体验非常接近普通 Python 程序。TensorFlow 2 虽然也默认 Eager但它的深层理想仍然是图执行tf.function就是想把 Python 层提速到静态图水平。两套哲学没有绝对优劣但使用感受截然不同PyTorch 像手工小作坊灵活、直观、改起来轻松TensorFlow 更像标准流水线API 约束多一些但约束也换来了部署生态的一致性。这个差异直接影响学习曲线。新手用 PyTorch 往往第一天就能写出能跑的模型因为他可以像写 Python 一样去理解转 TensorFlow 则要先接受 Keras 的封装逻辑、Dataset 的数据流、SavedModel 的导出流程等一堆概念。反过来说如果一个人对计算图和部署不熟悉PyTorch 的灵活性反而容易让他在生产阶段栽跟头因为“能跑”和“能稳定跑线上”之间的距离并不小。4.2 生态对比训练、部署、移动端、量化从我的实际项目体验出发两者的生态差异可以拿一张表讲清楚环节TensorFlowPyTorch模型定义Keras API 封装度高写法规范torch.nn更贴近 Python 习惯调试Eager 下可以但深入后要理解图动态图调试比较舒服模型导出SavedModel 是标准工具链齐全TorchScript / ONNX 需要额外配置线上服务TensorFlow Serving 成熟稳定TorchServe 起步较晚移动端/嵌入式TFLite 生态完善支持量化PyTorch Mobile / ExecuTorch 仍有差距社区资料存量多但更新慢老文章多新论文、新项目资料更活跃部署这个环节我必须多说几句。TensorFlow Serving 可以把 SavedModel 直接拉起一个高并发推理服务内置 batching、监控、版本管理线上运维非常省心。PyTorch 这边虽然有 TorchServe但整体上多模型管理、动态批处理、生产环境稳定性还是差一截。也不是说 PyTorch 不能做而是要拼更多第三方组件。如果你所在团队有专门的部署工程师这些差异可以靠人力补齐如果团队只有两三个算法工程师这些差异就会很实在。4.3 团队选型从人员习惯、项目周期、部署环境三方面看选型这件事我从来不看框架的月度热搜只看三个问题团队里谁写代码项目要做多久最终跑在哪先看人员团队现状是 PyTorch 熟练工多就别硬用 TensorFlow算法工程师的熟悉度直接决定前期开发效率。再看项目周期短期验证型项目选 PyTorch 开发体验更好长期的产品化项目要考虑模型生命周期管理、监控、服务热更新TensorFlow 的工程闭环更完整。最后看部署环境如果线上是 GPU 服务器交给运维统一管理两者差不多如果有大量移动端、嵌入式设备TFLite 成熟度会显著占优。我最近一年见过的真实案例里很多团队是“两边都留一手”新算法快速验证用 PyTorch一旦要上线就把模型转到 TensorFlow Serving 或 ONNX Runtime。流程上多一道转换但换来的是开发和部署两端各自最舒服的状态。这个方案听起来绕实际落地的人却不少。4.4 我的个人建议如果让我给一个刚入行的朋友直接回答“2024 年该学哪个”我会说第一优先学懂深度学习基础第二跟着你所在团队的主流框架走第三如果团队没有框架偏好就根据目标行业选。做纯研究和比赛PyTorch进大厂做搜推广、风控、自动驾驶这类偏工程的业务TensorFlow 依然是高频要求。更重要的是框架本身不是壁垒Epoch、Batch、Loss、梯度这些概念才是。我用 TensorFlow 学的东西换到 PyTorch 上照样通用。与其纠结哪个更流行不如先把一个框架用熟再用迁移学习的方式快速上手另一个。5. 部署与工程化TensorFlow 最能打的部分5.1 SavedModel标准统一的模型交付格式训练完模型交到别人手里时绝不能只给一个 checkpoint 或 h5 文件。TensorFlow 官方推荐的交付格式是 SavedModel它把模型结构、权重、推理函数签名、资产文件全部打包进一个目录方便后续用各种工具直接加载或服务。导出代码很简单传统写法是tf.saved_model.save(model, saved_model/my_model)如果用的是较新的 Keras 3也可以尝试model.export(saved_model/my_model)两者效果类似后者在思路上更贴近“模型即服务”。导出完成后目录里会有saved_model.pb和variables文件夹saved_model.pb是计算图定义variables就是权重。这里有个非常关键但常被忽略的点导出前一定要把模型从训练模式切成推理模式。如果你模型里有 Dropout 或 BatchNorm训练时和推理时的行为不一样。所以要么在导出前通过model.eval()或者设置trainingFalse跑一遍修复状态要么直接用带 signature 的导出函数把推理路径写清楚。否则线上推理结果可能跟离线评测差一大截排查起来特别痛苦。5.2 TensorFlow Serving生产环境推理的常见姿势TensorFlow Serving 是 C 实现的高性能推理服务它最大的卖点是模型版本管理你发布新模型时不用停服务Serving 会自动加载新版本并支持流量切换。部署方式通常是 Dockerdocker pull tensorflow/serving docker run -p 8501:8501 \ --mount typebind,source/path/to/saved_model,target/models/my_model \ -e MODEL_NAMEmy_model -t tensorflow/serving启动后用 REST 接口就能请求curl -d {instances: [[1.0, 2.0, 3.0]]} \ -H Content-Type: application/json \ -X POST http://localhost:8501/v1/models/my_model:predict线上真正高并发时Serving 还支持动态 batch它会把多个并发请求攒在一起合成一个批次送给 GPU显著提升吞吐。这功能在 PyTorch 生态里要自己实现但 TensorFlow Serving 是开箱即用。我踩过的坑是第一次起 Serving 时模型目录的路径和模型名要跟/models/下的子目录保持一致Serving 会扫描/models/模型名/版本号/这种结构如果你目录层级不对它会报“找不到可服务模型”但不一定会告诉你具体错在哪。5.3 移动端与嵌入式设备TFLite 的取舍如果目标端是手机、树莓派、边缘盒子TensorFlow Lite 是绕不开的话题。TFLite 做的事情是把模型压缩、量化、转成更适合移动端推理的格式。转换代码也很短import tensorflow as tf converter tf.lite.TFLiteConverter.from_saved_model(saved_model/my_model) tflite_model converter.convert() open(model.tflite, wb).write(tflite_model)转换后体积可能小不少缺点是有部分算子不支持转换过程可能报错。常见的替代方案是把不支持的算子替换成 TFLite 支持的等价实现或者用converter.target_spec.supported_ops调整算子集合。移动端部署从来不是“模型转一下就能跑”那么简单内存占用、初始化延迟、多线程推理每一项都需要单独调优但方向是对的模型结构设计阶段就要考虑目标硬件否则后面转换会频繁碰壁。5.4 模型量化被忽视的加速手段很多人觉得量化是锦上添花我反而觉得它是工程里最实用的加速手段之一。把 FP32 权重转成 INT8模型体积直接变四分之一推理速度在中低端设备上往往提升明显精度损失通常控制在 1% 到 2% 以内。TFLite 里开后训练量化只需要一个参数converter.optimizations [tf.lite.Optimize.DEFAULT]更精细的做法是量化感知训练在训练时就模拟量化误差导出精度通常更好但实现复杂度更高。我的建议是先试后训练量化如果精度不达标再研究量化感知训练不要一上来就把所有坑都踩一遍。量化不是免费的午餐但你要先吃到免费的甜头再决定要不要付复杂度这个代价。6. 踩坑实录这些年我遇到的 TensorFlow 问题6.1 环境不一致带来的玄学 bug这类问题我排第一因为它们的报错往往伪装成“代码问题”。最典型的是本地能跑、服务器跑不了。我调试过的案子几乎有一半最后指向版本差异本地 TensorFlow 2.15服务器还在 2.10本地 numpy 1.24服务器 numpy 1.22。于是出现了本地训练正常、服务器 loss 直接 NaN 的状况。排查手段其实不复杂先把两边的pip freeze | grep tensorflow、python -c import tensorflow as tf;print(tf.__version__)、CUDA 驱动版本全部打出来对比。让团队统一用 requirements.txt 或 Docker 镜像是成本最低的解决办法没有之一。6.2 训练 OOM 与数据加载瓶颈训练时 GPU 显存不足是我遇到第二多的问题。显存溢出有个特点报错不一定在真正超限的瞬间而是可能在下一个 batch 开始分配内存时才炸。排查顺序我一般这样走先把 batch size 减半确认是不是显存真的不够再用nvidia-smi看是不是有别人的进程占着卡最后再看模型本身是不是有隐藏的显存黑洞比如中间张量保存过多、for 循环里重复建层。数据加载瓶颈则容易被忽略GPU 利用率低但显存没满多半是数据在读入环节拖了后腿。这时候检查model.fit(..., use_multiprocessingTrue)以及 Dataset 里的prefetch有没有开。我之前跑一个 CNN数据增强逻辑写了大量 Python 操作GPU 利用率只有 30%把增强函数里的操作向量化并加了tf.function后直接拉到 80% 以上。6.3 模型输出 NaN 的排查顺序训练过程的 loss 变 NaN新手容易慌但排查是有套路的。我的顺序是第一查学习率如果初始学习率太大梯度爆炸常常导致 NaN先把学习率降到原来的十分之一试试第二查数据看看训练集里有没有 NaN、Inf特征没归一化也可能让数值范围爆炸第三查网络结构尤其是自定义 loss 里有没有除零、log(0) 这类操作加上一个小 epsilon 就能解决第四查优化器状态比如 Adam 的 epsilon 参数有时需要调大一点。绝大多数 NaN 问题出在前两步不需要一上来就去怀疑框架 bug。TensorFlow 的调试精神就是越玄学的问题越要用最简单的变量控制法去破案一次只改一个东西否则永远找不到因果关系。6.4 其他几条值得记下来的实操经验最后再分享几条比较零碎但很实用的经验。第一Keras 的model.summary()不是摆设建模后先看一眼参数总量和每层输出形状能挡住大量低级错误。第二模型保存不要只存model.save(model.h5)最好连model.compile的超参数和训练 history 一起记录下来否则几个月后回来看老模型根本不知道当初用了哪组参数。第三TensorBoard 从第一天就开始用loss 曲线和梯度直方图能帮你守住训练过程的边界不要等项目跑飞了才后悔没记录。第四版本升级后多留一天时间回归测试TensorFlow 每次大版本更新都会带来 API 变化别在线上版本随便升也别因为怕麻烦就永远不升选一个稳定的节奏是更聪明的策略。就我自己而言TensorFlow 给我的职业安全感从来不是来自它最流行而是来自它稳定、成套、经得起生产环境长期考验。如果你正在入门安装阶段遇到坑很正常那不是你笨是它确实有很多隐藏前提如果你正纠结 PyTorch 和 TensorFlow我的建议从来都是先定项目场景再定框架选完后别反复横跳。技术更新再快深度学习底层的东西不会变把时间花在核心能力上框架只是一层随时可以换上的手套而已。
返回列表