我是TensorFlow的新手。我搞不懂tf的区别。占位符和tf.Variable。在我看来,tf。占位符用于输入数据,tf。变量用于存储数据的状态。这就是我所知道的一切。
谁能给我详细解释一下他们的不同之处吗?特别是,什么时候使用tf。变量和何时使用tf.placeholder?
我是TensorFlow的新手。我搞不懂tf的区别。占位符和tf.Variable。在我看来,tf。占位符用于输入数据,tf。变量用于存储数据的状态。这就是我所知道的一切。
谁能给我详细解释一下他们的不同之处吗?特别是,什么时候使用tf。变量和何时使用tf.placeholder?
当前回答
变量
TensorFlow变量是表示程序操纵的共享持久状态的最佳方式。变量是通过tf操作的。变量类。内部是一个tf。变量存储一个持久张量。特定的操作允许你读取和修改这个张量的值。这些修改在多个tf中可见。会话,因此多个工作人员可以看到tf.Variable的相同值。变量在使用前必须初始化。
例子:
x = tf.Variable(3, name="x")
y = tf.Variable(4, name="y")
f = x*x*y + y + 2
这将创建一个计算图。变量(x和y)可以被初始化,函数(f)在一个tensorflow会话中被计算,如下所示:
with tf.Session() as sess:
x.initializer.run()
y.initializer.run()
result = f.eval()
print(result)
42
占位符
占位符是一个节点(与变量相同),其值可以在将来初始化。这些节点基本上在运行时输出分配给它们的值。占位符节点可以使用tf.placeholder()类来分配,你可以为它提供参数,比如变量的类型和/或它的形状。占位符广泛用于表示机器学习模型中的训练数据集,因为训练数据集不断变化。
例子:
A = tf.placeholder(tf.float32, shape=(None, 3))
B = A + 5
注意:维度的“None”表示“任何大小”。
with tf.Session as sess:
B_val_1 = B.eval(feed_dict={A: [[1, 2, 3]]})
B_val_2 = B.eval(feed_dict={A: [[4, 5, 6], [7, 8, 9]]})
print(B_val_1)
[[6. 7. 8.]]
print(B_val_2)
[[9. 10. 11.]
[12. 13. 14.]]
引用:
https://www.tensorflow.org/guide/variables https://www.tensorflow.org/api_docs/python/tf/placeholder O'Reilly:使用Scikit-Learn和Tensorflow进行动手机器学习
其他回答
博士TL;
变量
为了学习参数 价值观可以从培训中获得 初始值是必需的(通常是随机的)
占位符
为数据分配存储(例如在馈送期间用于图像像素数据) 初始值不是必需的(但可以设置,参见tf.placeholder_with_default)
因为张量计算由图组成,所以最好用图来解释这两者。
以简单的线性回归为例
WX+B=Y
其中W和B代表权重和偏差,X代表观测数据的输入,Y代表观测数据的输出。
显然X和Y是同一性质(显变量),而W和B是潜变量。X和Y是样本(观测值)的值,因此需要填充一个位置,而W和B是权重和偏差,图中的变量(前一个值影响后者),应该使用不同的X和Y对进行训练。我们在占位符中放置不同的样本来训练变量。
我们只需要保存或恢复变量(在检查点)来保存或重新构建代码图。
占位符主要是不同数据集的占位符(例如训练数据或测试数据)。然而,变量在训练过程中被训练为特定的任务,即预测输入的结果或将输入映射到所需的标签。它们保持不变,直到你使用不同或相同的样本重新训练或微调模型,通常通过字典填充占位符。例如:
session.run(a_graph, dict = {a_placeholder_name : sample_values})
占位符也作为参数传递给设置模型。
如果你在训练过程中改变了模型的占位符(添加、删除、改变形状等),你仍然可以重新加载检查点,而不需要任何其他修改。但是如果保存的模型的变量发生了变化,您应该相应地调整检查点以重新加载它并继续训练(图中定义的所有变量都应该在检查点中可用)。
总而言之,如果值来自样本(您已经拥有的观察结果),您可以安全地设置一个占位符来保存它们,而如果您需要训练一个参数,则利用一个变量(简单地说,为您想使用TF自动获得的值设置变量)。
在一些有趣的模型中,比如样式转换模型,输入像素将被优化,通常被称为模型变量是固定的,然后我们应该将输入(通常是随机初始化的)作为在该链接中实现的变量。
要了解更多信息,请参考这个简单明了的文档。
区别在于tf。变量,在声明时必须提供初始值。特遣部队。占位符,你不必提供初始值,你可以在运行时在Session.run中使用feed_dict参数指定它
示例代码片段:
import numpy as np
import tensorflow as tf
### Model parameters ###
W = tf.Variable([.3], tf.float32)
b = tf.Variable([-.3], tf.float32)
### Model input and output ###
x = tf.placeholder(tf.float32)
linear_model = W * x + b
y = tf.placeholder(tf.float32)
### loss ###
loss = tf.reduce_sum(tf.square(linear_model - y)) # sum of the squares
### optimizer ###
optimizer = tf.train.GradientDescentOptimizer(0.01)
train = optimizer.minimize(loss)
### training data ###
x_train = [1,2,3,4]
y_train = [0,-1,-2,-3]
### training loop ###
init = tf.global_variables_initializer()
sess = tf.Session()
sess.run(init) # reset values to wrong
for i in range(1000):
sess.run(train, {x:x_train, y:y_train})
顾名思义,占位符是稍后提供一个值的承诺。
变量只是训练参数(W(矩阵),b(偏差),与您在日常编程中使用的正常变量相同,培训师在每次运行/步骤中更新/修改。
虽然占位符不需要任何初始值,当你创建x和y时,TF不分配任何内存,相反,当你在sesss .run()中使用feed_dict提供占位符时,TensorFlow将为它们分配适当大小的内存(x和y) -这种不受约束的特性允许我们提供任何大小和形状的数据。
简而言之:
Variable -是一个你希望训练器(例如GradientDescentOptimizer)在每一步之后更新的参数。
占位符演示-
a = tf.placeholder(tf.float32)
b = tf.placeholder(tf.float32)
adder_node = a + b # + provides a shortcut for tf.add(a, b)
执行:
print(sess.run(adder_node, {a: 3, b:4.5}))
print(sess.run(adder_node, {a: [1,3], b: [2, 4]}))
结果是输出
7.5
[ 3. 7.]
在第一种情况下,3和4.5将分别传递给a和b,然后传递给adder_node输出7。在第二种情况下,有一个提要列表,第一步1和2将被添加,接下来的3和4 (a和b)。
相关阅读:
特遣部队。占位符doc。 特遣部队。变量doc。 变量VS占位符。
想象一个计算图。在这样的图中,我们需要一个输入节点来将数据传递到图中,这些节点应该在tensorflow中定义为占位符。
不要把Python想象成一个通用的程序。你可以写一个Python程序,做所有那些在其他答案中通过变量解释的事情,但对于张量流中的计算图,为了将数据输入到图中,你需要将这些点定义为占位符。