我试图理解TensorFlow中占位符和变量之间的区别:
X = tf.placeholder("float")
W = tf.Variable(rng.randn(), name="weight")
我还阅读了下面的Stack Overflow问题 . 当他们是模型的输入时,我理解它们之间的区别 .
InvalidArgumentError:您必须为占位符张量占位符提供值
但是,一般来说,如果我们没有 Build 模型, tf.placeholder()
和 tf.Variable()
之间是否还有区别?
2 回答
占位符
占位符用于将外部数据馈送到Tensorflow计算(图表外部的东西) . 这是一些文档:(https://www.tensorflow.org/versions/r0.10/how_tos/reading_data/#feeding)
我个人会从占位符到标准输入的阅读进行类比 .
从标准输入读取时,需要从外部源“注入数据” . 与占位符相同 . 它允许您“注入”计算图外部的数据 .
如果您正在训练学习算法,那么占位符的明确用例就是提供您的训练数据 . 训练数据不存储在计算图中 . 你打算如何将其纳入图表?通过占位符注入它 . 一个占位符基本上是你告诉图表“我还没有这个 . 但是当我要求你跑的时候我会帮你的 . ”
变量
变量用于在图表中存储状态 . 它需要一个初始值 . 一个用例可以表示神经网络的权重或类似的东西 . 这是文档:(https://www.tensorflow.org/api_docs/python/tf/Variable)
我个人会在Tensorflow变量之间进行类比,并将Python中的变量分配给任何不依赖于外部内容的变量 . 例如,
W
表示计算的某种结果 . 就像你必须在Python中初始化所有变量一样(你不能只运行命令x
,你必须说x = ...something...
),你必须初始化Tensorflow中的所有变量对象 .变量与占位符
在我看来,
tf.Variable
和tf.placeholder
之间并没有多大关系 . 如果需要存储状态,请使用Variable
. 如果需要输入外部数据,请使用placeholder
.如果您没有构建模型,如果要插入未定义图形的外部数据,则仍应使用
tf.placeholder
. 如果您没有构建模型,如果要在运行图形时存储某种计算结果,则仍需要tf.Variable
.为什么两者兼而有之?
我不是Tensorflow的专家,所以我只能猜测为什么设计都有 .
占位符和变量之间的一个很大区别是占位符可以具有可变大小,但在构造图形时必须指定
tf.Variable
的形状 .可变大小的占位符感觉:也许我现在只想输入大小为5的培训批次,但也许我想稍后增加批量大小 . 也许我提前不知道我将获得多少训练样例 .
可变大小的变量没有意义:
tf.Variable
保存模型的学习参数,参数的数量不应改变 . 此外,Tensorflow扩展到分布式计算 . 如果你的形状在整个计算过程中发生了变化,那么在1000台计算机中保持正确分布是非常困难的 .通常,您构建模型并且所有参数都是提前知道的,因此
tf.Variable
可能用于表示 .tf.placeholder
可能适用于模型(或计算图)之外的所有其他内容,因此可以更灵活 .tf.Variable和tf.placeholder之间最明显的区别是
使用
sess.run(tf.global_variables_initializer())
完成变量的初始化 . 同时在创建变量时,您需要将Tensor作为其初始值传递给Variable()构造函数,并且在创建变量时,您始终知道其形状 .另一方面,您无法更新占位符 . 它们也不应该被初始化,但是因为它们是承诺有张量,你需要将它们提供给它们
sess.run(<op>, {a: <some_val>})
. 最后,与变量相比,占位符可能不知道形状 . 您既可以提供部分尺寸,也可以不提供任何尺寸 .There other differences:
可以在优化期间更新变量内的值
变量可以shared,可以是non-trainable
变量内的值可以在训练后存储
创建变量时,3 ops are added to a graph(变量op,初始化程序op,ops表示初始值)
placeholder is a function, Variable is a class(因此大写)
在分布式环境中使用TF时,变量存储在特殊位置(parameter server)并在工作者之间共享 .
有趣的是,不仅可以喂养占位符 . 您可以将值提供给变量甚至是常量 .