单个会话中变量的持久性

时间:2016-06-23 02:54:00

标签: python tensorflow

我正在使用强化学习,并希望将我的示例存储在TF图中,以避免在python和TF之间移动数据。我以为我可以使用TF.Variable()因为它应该在整个会话中持续存在,并且只需在需要时添加一个样本。以下是其中一种方法的示例:

import tensorflow as tf

initx = [[1.0, 2.0, 3.0, 4.0],
         [4.0, 5.0, 6.0, 7.0],
         [7.0, 8.0, 9.0, 8.0]]

x = tf.get_variable("x",dtype=tf.float32,validate_shape=False,initializer=tf.constant(initx))
xappend = tf.placeholder(dtype=tf.float32,shape=[None,4])
#xappend = tf.get_variable("xappend",shape=[1,4],dtype=tf.float32,validate_shape=False)

x = tf.concat(0,[x,xappend])

with tf.Session('') as session:
  session.run(tf.initialize_all_variables())    
  print session.run([x],feed_dict={xappend:[[-1.0,98.0,97.0,96.0]] })
  print session.run([x],feed_dict={xappend:[[-2.0,98.0,97.0,96.0]] })
  print session.run([x],feed_dict={xappend:[[-3.0,98.0,97.0,96.0]] })
  print session.run([x],feed_dict={xappend:[[-4.0,98.0,97.0,96.0]] })

我的想法是这应该连接" xappend"价值到张量结束" x"并且随着每次观察的增加而增长。这不是似乎发生的事情。对于每次运行,我得到初始化值加上xappend值,只是xappend的单个实例。我似乎无法将-1,-2,-3,-4附加到会话中张量的末尾。这是输出:

[array([[  1.,   2.,   3.,   4.],  
   [  4.,   5.,   6.,   7.],  
   [  7.,   8.,   9.,   8.],  
   [ -1.,  98.,  97.,  96.]], dtype=float32)]  
[array([[  1.,   2.,   3.,   4.],  
   [  4.,   5.,   6.,   7.],  
   [  7.,   8.,   9.,   8.],  
   [ -2.,  98.,  97.,  96.]], dtype=float32)]  
[array([[  1.,   2.,   3.,   4.],  
   [  4.,   5.,   6.,   7.],  
   [  7.,   8.,   9.,   8.],  
   [ -3.,  98.,  97.,  96.]], dtype=float32)]  
[array([[  1.,   2.,   3.,   4.],  
   [  4.,   5.,   6.,   7.],  
   [  7.,   8.,   9.,   8.],  
   [ -4.,  98.,  97.,  96.]], dtype=float32)]  

我在会话中尝试了另一种方法并获得了相同的意外结果:

...
update = tf.assign(xappend, [[-1.0,98.0,97.0,96.0]], validate_shape=False)
print session.run([update])
print session.run([x])
update = tf.assign(xappend, [[-2.0,98.0,97.0,96.0]], validate_shape=False)
print session.run([update])
print session.run([x])
...

我知道当我有权重时,它们会在同一会话中的呼叫之间保持不变。我确信它与tf.concat()函数的大小更改有关,它不允许持久化" x"此图中的变量。

任何想法这种方法可能出现什么问题?有更好的方法吗?

1 个答案:

答案 0 :(得分:1)

你快到了。如果要修改变量,则必须创建分配操作。此操作将在sess.run()中运行,并将更新变量的内容。

这里的诀窍是,在分配变量时,您可以修改其形状。您必须将tf.assign与参数validate_shape=False一起使用。这在文档中暗示:

  

如果您想稍后更改变量的形状,则必须使用带有validate_shape = False的赋值Op

tf.assign的文档不存在。

initx = [[1.0, 2.0, 3.0, 4.0],
         [4.0, 5.0, 6.0, 7.0],
         [7.0, 8.0, 9.0, 8.0]]

x = tf.get_variable("x",dtype=tf.float32,validate_shape=False,initializer=tf.constant(initx))
xappend = tf.placeholder(dtype=tf.float32,shape=[None,4])

new_x = tf.concat(0, [x, xappend])
append_op = tf.assign(x, new_x, validate_shape=False)

with tf.Session() as sess:
    sess.run(tf.initialize_all_variables())
    sess.run(append_op, feed_dict={xappend:[[-1.0,98.0,97.0,96.0]] })
    sess.run(append_op, feed_dict={xappend:[[-2.0,98.0,97.0,96.0]] })
    sess.run(append_op, feed_dict={xappend:[[-3.0,98.0,97.0,96.0]] })
    sess.run(append_op, feed_dict={xappend:[[-4.0,98.0,97.0,96.0]] })

    sess.run(x)  # should give you the expected result, of shape [7, 4]

但是,由于您不断更改变量的形状,因此此代码可能效率不高。

更好的方法是存储python列表,或者(更好)使用形状[max_length, 4]的固定大小数组,在此预先指定max_lenght参数,并填充数组行行。