核心要点

  • 建图时只声明输入的 dtype 和 shape,实际数据延迟到运行时由 feed_dict 注入

  • shape 用 None 占位可变 batch 维,让同一张图复用不同大小的批次

  • placeholder 是输入数据通道,Variable 才是可训练参数,二者不可混淆

  • TF 2.x Eager 已彻底移除,新代码直接传张量;只在维护 1.x 老项目时才需要它

标准回答

PlaceholderTensorFlow 1.x 静态图中的输入占位符

python
# TF 1.x
x = tf.placeholder(tf.float32, shape=[None, 784], name='input')
y_pred = tf.matmul(x, W) + b
with tf.Session() as sess:
    out = sess.run(y_pred, feed_dict={x: batch_numpy})

作用

  • 建图时形状/类型已知,运行时注入
  • 同一图复用不同 batch(None 表示可变 batch 维)
  • 与 Variable(参数)区分:Placeholder 是输入数据

TF 2.x已废弃。Eager 下直接 model(tf.constant(batch))model(batch_tensor)tf.function 用函数参数代替 placeholder。

维护 legacy 代码或读老教程需理解 placeholder + feed_dict + Session 三位一体。新项目勿用。详见 TensorFlow 迁移指南。

常见误区

⚠️ 常见踩坑

在 TF 2.x Eager 模式下调用 tf.placeholder 会直接报错(已移除),必须用 tf.compat.v1 并关闭 Eager 才能运行旧代码;另一个常见错误是把 placeholder 当成可训练参数去优化——它没有值、不参与梯度更新,真正学习的是 Variable。

追问

追问 1placeholder 的 shape 中 None 是什么含义?

None 表示该维度大小在建图时未知、运行时才确定,最常见于 batch 维(如 [None, 784]),这样同一张图既能喂 32 条也能喂 256 条数据,无需为每种 batch 大小重建图。

追问 2feed_dict 除了 placeholder 还能喂什么?

理论上 feed_dict 可以覆盖图中任意张量的值(包括中间结果或 Variable),用于调试时强行替换某个节点的输出;但常规用法只喂 placeholder,覆盖其他节点会绕过计算、容易引入隐藏 bug。

追问 3TF 2.x 如何等价实现可变 batch?

直接定义 forward 函数把输入作为参数即可,batch 维天然可变;若用 @tf.function 编译,可在 input_signature 里用 tf.TensorSpec(shape=[None, 784]) 显式声明可变维,避免不同 batch 大小触发重复 retrace。

延伸学习

与本题相关的知识库文章、术语、工具与行业资讯。

🛠️ AI 工具

  • Pytorch

    Meta 开源的深度学习框架,100K+ stars。以动态计算图和 Pythonic 风格著称,在学术界和工业界都有广泛应用,支持分布式训练、移动端部署和 ONNX 导出

  • Tensorflow

    全球最流行的机器学习框架之一,195K+ stars。Google 开源的端到端 ML 平台,支持 TensorFlow、Keras 等多种 API,覆盖深度学习、强化学习、移动端部署等全场景,是 AI 工程师的必备工具