我正在看一个示例here。我看到了以下操作顺序:
import tensorflow as tf
v1 = tf.get_variable("v1", shape=[3], initializer = tf.zeros_initializer)
inc_v1 = v1.assign(v1+1)
init_op = tf.global_variables_initializer()
s = tf.Session()
s.run(init_op)
s.run(inc_v1)
结果是:
array([1., 1., 1.], dtype=float32)
我不了解“分配”操作背后的逻辑。特别是,我用看起来更简单的东西代替了它:
import tensorflow as tf
v1 = tf.get_variable("v1", shape=[3], initializer = tf.zeros_initializer)
inc_v1 = v1 + 1
init_op = tf.global_variables_initializer()
s = tf.Session()
s.run(init_op)
s.run(inc_v1)
我得到了完全一样的输出。那么,为什么我们需要分配?
答案 0 :(得分:2)
它采用原始张量和新张量,用新值更新张量的原始值,并返回原始张量的参考。看一下在Tensorboard上生成的图形:
操作assign
返回对原始Tensor的引用:
在没有assign
的情况下,仅创建另一个张量以添加恒定值:
如果打印张量v1
的求值(运行inc_v1
之后),则输出[1. 1. 1.]
作为操作的结果,它已重新分配给原始张量。在第二种情况下,它将保留为[0. 0. 0.]
。
答案 1 :(得分:2)
该示例确实不是很好的说明。重要的部分是assign
将给定值保存到会话中的变量中,因此您可以稍后在下一次对run
的调用中使用它。看到这里:
import tensorflow as tf
v1 = tf.get_variable("v1", shape=[3], initializer = tf.zeros_initializer)
inc_v1 = v1.assign(v1+1)
init_op = tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init_op)
sess.run(inc_v1)
print(sess.run(v1))
# [1. 1. 1.]
sess.run(inc_v1)
print(sess.run(v1))
# [2. 2. 2.]
注意v1
保存分配的值,因此在进一步调用run
时可以使用它。现在比较:
import tensorflow as tf
v1 = tf.get_variable("v1", shape=[3], initializer = tf.zeros_initializer)
inc_v1 = v1+1
init_op = tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init_op)
sess.run(inc_v1)
print(sess.run(v1))
# [0. 0. 0.]
sess.run(inc_v1)
print(sess.run(v1))
# [0. 0. 0.]
这里增量发生在一次调用run
的过程中,但是其结果从未保存在任何地方,并且v1
始终保持值为[0. 0. 0.]
。
变量很重要,因为TensorFlow中的大多数事情都是通过几个步骤完成的,例如神经网络中的每个批次。每个步骤都是对run
的调用,重要的是,将步骤中的模型更改(例如,神经网络中权重的更新)保存用于下一步-否则,您将在的地方,永远不会离开起点!
答案 2 :(得分:0)
当您要分配一个非图形值时需要分配