如何为 TensorFlow 变量赋值?
How to assign a value to a TensorFlow variable?
我正在尝试为 python 中的张量流变量分配一个新值。
import tensorflow as tf
import numpy as np
x = tf.Variable(0)
init = tf.initialize_all_variables()
sess = tf.InteractiveSession()
sess.run(init)
print(x.eval())
x.assign(1)
print(x.eval())
但我得到的输出是
0
0
因此值没有改变。我错过了什么?
在TF1中,语句x.assign(1)
does not actually assign the value 1
to x
, but rather creates a tf.Operation
that you have to explicitly run to update the variable.* A call to Operation.run()
or Session.run()
可用于运行操作:
assign_op = x.assign(1)
sess.run(assign_op) # or `assign_op.op.run()`
print(x.eval())
# ==> 1
(*其实就是returns一个tf.Tensor
,对应变量的更新值,方便链式赋值。)
但是,在 TF2 中 x.assign(1)
现在会急切地分配值:
x.assign(1)
print(x.numpy())
# ==> 1
有一个更简单的方法:
x = tf.Variable(0)
x = x + 1
print x.eval()
首先,您可以将值赋给 variables/constants,只需像使用占位符一样将值输入它们即可。所以这是完全合法的:
import tensorflow as tf
x = tf.Variable(0)
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
print sess.run(x, feed_dict={x: 3})
关于您对 tf.assign() 运算符的混淆。在 TF 中,在会话中 运行 之前不会执行任何操作。所以你总是必须做这样的事情:op_name = tf.some_function_that_create_op(params)
然后在会话中你 运行 sess.run(op_name)
。以 assign 为例,您将执行如下操作:
import tensorflow as tf
x = tf.Variable(0)
y = tf.assign(x, 1)
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
print sess.run(x)
print sess.run(y)
print sess.run(x)
此外,必须注意,如果您使用 your_tensor.assign()
,则无需显式调用 tf.global_variables_initializer
,因为赋值操作会在后台为您完成。
示例:
In [212]: w = tf.Variable(12)
In [213]: w_new = w.assign(34)
In [214]: with tf.Session() as sess:
...: sess.run(w_new)
...: print(w_new.eval())
# output
34
然而,这不会初始化所有变量,而只会初始化执行assign
的变量。
您还可以为 tf.Variable
分配一个新值而不向图形添加操作:tf.Variable.load(value, session)
。此函数还可以避免您在从图表外部赋值时添加占位符,并且在图表最终确定时很有用。
import tensorflow as tf
x = tf.Variable(0)
sess = tf.Session()
sess.run(tf.global_variables_initializer())
print(sess.run(x)) # Prints 0.
x.load(1, sess)
print(sess.run(x)) # Prints 1.
更新:这是在 TF2 中描述的,因为默认执行是急切的,图表是 no longer exposed in the user-facing API。
这是完整的工作示例:
import numpy as np
import tensorflow as tf
w= tf.Variable(0, dtype=tf.float32) #good practice to set the type of the variable
cost = 10 + 5*w + w*w
train = tf.train.GradientDescentOptimizer(0.01).minimize(cost)
init = tf.global_variables_initializer()
session = tf.Session()
session.run(init)
print(session.run(w))
session.run(train)
print(session.run(w)) # runs one step of gradient descent
for i in range(10000):
session.run(train)
print(session.run(w))
注意输出将是:
0.0
-0.049999997
-2.499994
这意味着在一开始变量为 0,如定义的那样,然后在梯度下降一步之后变量为 -0.049999997,再经过 10.000 步后我们达到 -2.499994(基于我们的成本函数) .
注意:您最初使用的是交互式会话。当多个不同的会话需要在同一个脚本中 运行 时,交互式会话很有用。但是,为了简单起见,我使用了非交互式会话。
使用最新的Tensorflow eager execution模式
import tensorflow as tf
tf.enable_eager_execution()
my_int_variable = tf.get_variable("my_int_variable", [1, 2, 3])
print(my_int_variable)
我回答了一个类似的问题。我查看了很多总是产生相同问题的地方。基本上,我不想给权重赋值,只是简单地改变权重。上述答案的简短版本是:
tf.keras.backend.set_value(tf_var, numpy_weights)
我正在尝试为 python 中的张量流变量分配一个新值。
import tensorflow as tf
import numpy as np
x = tf.Variable(0)
init = tf.initialize_all_variables()
sess = tf.InteractiveSession()
sess.run(init)
print(x.eval())
x.assign(1)
print(x.eval())
但我得到的输出是
0
0
因此值没有改变。我错过了什么?
在TF1中,语句x.assign(1)
does not actually assign the value 1
to x
, but rather creates a tf.Operation
that you have to explicitly run to update the variable.* A call to Operation.run()
or Session.run()
可用于运行操作:
assign_op = x.assign(1)
sess.run(assign_op) # or `assign_op.op.run()`
print(x.eval())
# ==> 1
(*其实就是returns一个tf.Tensor
,对应变量的更新值,方便链式赋值。)
但是,在 TF2 中 x.assign(1)
现在会急切地分配值:
x.assign(1)
print(x.numpy())
# ==> 1
有一个更简单的方法:
x = tf.Variable(0)
x = x + 1
print x.eval()
首先,您可以将值赋给 variables/constants,只需像使用占位符一样将值输入它们即可。所以这是完全合法的:
import tensorflow as tf
x = tf.Variable(0)
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
print sess.run(x, feed_dict={x: 3})
关于您对 tf.assign() 运算符的混淆。在 TF 中,在会话中 运行 之前不会执行任何操作。所以你总是必须做这样的事情:op_name = tf.some_function_that_create_op(params)
然后在会话中你 运行 sess.run(op_name)
。以 assign 为例,您将执行如下操作:
import tensorflow as tf
x = tf.Variable(0)
y = tf.assign(x, 1)
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
print sess.run(x)
print sess.run(y)
print sess.run(x)
此外,必须注意,如果您使用 your_tensor.assign()
,则无需显式调用 tf.global_variables_initializer
,因为赋值操作会在后台为您完成。
示例:
In [212]: w = tf.Variable(12)
In [213]: w_new = w.assign(34)
In [214]: with tf.Session() as sess:
...: sess.run(w_new)
...: print(w_new.eval())
# output
34
然而,这不会初始化所有变量,而只会初始化执行assign
的变量。
您还可以为 tf.Variable
分配一个新值而不向图形添加操作:tf.Variable.load(value, session)
。此函数还可以避免您在从图表外部赋值时添加占位符,并且在图表最终确定时很有用。
import tensorflow as tf
x = tf.Variable(0)
sess = tf.Session()
sess.run(tf.global_variables_initializer())
print(sess.run(x)) # Prints 0.
x.load(1, sess)
print(sess.run(x)) # Prints 1.
更新:这是在 TF2 中描述的,因为默认执行是急切的,图表是 no longer exposed in the user-facing API。
这是完整的工作示例:
import numpy as np
import tensorflow as tf
w= tf.Variable(0, dtype=tf.float32) #good practice to set the type of the variable
cost = 10 + 5*w + w*w
train = tf.train.GradientDescentOptimizer(0.01).minimize(cost)
init = tf.global_variables_initializer()
session = tf.Session()
session.run(init)
print(session.run(w))
session.run(train)
print(session.run(w)) # runs one step of gradient descent
for i in range(10000):
session.run(train)
print(session.run(w))
注意输出将是:
0.0
-0.049999997
-2.499994
这意味着在一开始变量为 0,如定义的那样,然后在梯度下降一步之后变量为 -0.049999997,再经过 10.000 步后我们达到 -2.499994(基于我们的成本函数) .
注意:您最初使用的是交互式会话。当多个不同的会话需要在同一个脚本中 运行 时,交互式会话很有用。但是,为了简单起见,我使用了非交互式会话。
使用最新的Tensorflow eager execution模式
import tensorflow as tf
tf.enable_eager_execution()
my_int_variable = tf.get_variable("my_int_variable", [1, 2, 3])
print(my_int_variable)
我回答了一个类似的问题
tf.keras.backend.set_value(tf_var, numpy_weights)