八. Tensorflow的数据状态

这篇博客记录了Variable/partial_run等关于数据状态的实验。

Variable

首先,我们知道Variable和其他的结点类型的一大不同:就是Variable是可以暂存数据的;其他结点真的把数据当成流,计算过,就没了。
下面试试在同一个session里面,两次访问Vriable,看看数据有没有保存下来:

1
2
3
4
5
6
7
import tensorflow as tf

x = tf.placeholder(tf.int32, name="x")
y = tf.placeholder(tf.int32, name="y")
w = tf.Variable(1, name="w")

print(type(w))
1
2
<class 'tensorflow.python.ops.variables.Variable'>
In [3]:
1
2
3
4
5
give_to_w = w.assign(x + y)

sess = tf.Session()
sess.run(tf.global_variables_initializer())
print(sess.run(w, {x:1, y:2}))
1
1

第一次获取w的值,使其保存值

1
print(sess.run(give_to_w, {x:1, y:2}))
1
3

z的值来自于w,获取z相当于第二次访问w:

1
2
3
z = w * 1

print(type(z))
1
<class 'tensorflow.python.framework.ops.Tensor'>

看看w的值有没有变:

1
print(sess.run(z))
1
3

换一个session看看w还在不在:

1
2
sess_2 = tf.Session()
sess_2.run(z)

错误信息:FailedPreconditionError: Attempting to use uninitialized value w

结论:同一个session下的Variable值会保存,其他tensor不保存值(本身tensor的值只有在计算的时候才有)。

partial_run

有的时候,我们会希望模型的运行分开两步,第一步跑出一些结果出来以后,拿出来做其他运算,再放回去继续跑完。
但这样只有variable的值会保存,其他结点的状态都会丢失,这个时候我们需要partial_run

1
k = w * x

分成两步:

  • 1.partial_run_setup:将所有的fetch和feed以list传入,返回一个handler;
  • 2.partial_run:传入handler,fetch和feed格式和run一样。
1
2
handler = sess.partial_run_setup([w, k], [x, y])
print(sess.partial_run(handler, w, {x:4, y:5}))
1
3
1
print(sess.partial_run(handler, k))
1
12

结论:使用partial_run可以模拟保存tensor值的效果。