Tensorflow while_loop训练
问题描述:
在我的问题,我需要运行GD与每个训练步骤的数据1例。这是已知的问题,session.run()具有开销,因此训练模型的时间太长。 为了避免开销,我尝试使用while_loop并使用一次run()调用来训练所有数据的模型。但它的方法不工作,train_op甚至不执行。下面是我在做什么的简单例子:Tensorflow while_loop训练
data = [k*1. for k in range(10)]
tf.reset_default_graph()
i = tf.Variable(0, name='loop_i')
q_x = tf.FIFOQueue(100000, tf.float32)
q_y = tf.FIFOQueue(100000, tf.float32)
x = q_x.dequeue()
y = q_y.dequeue()
w = tf.Variable(0.)
b = tf.Variable(0.)
loss = (tf.add(tf.mul(x, w), b) - y)**2
gs = tf.Variable(0)
train_op = tf.train.GradientDescentOptimizer(0.05).minimize(loss, global_step=gs)
s = tf.Session()
s.run(tf.initialize_all_variables())
def cond(i):
return i < 10
def body(i):
return tf.tuple([tf.add(i, 1)], control_inputs=[train_op])
loop = tf.while_loop(cond, body, [i])
for _ in range(1):
s.run(q_x.enqueue_many((data,)))
s.run(q_y.enqueue_many((data,)))
s.run(loop)
s.close()
我在做什么错了?或者还有另外一个解决这个问题的开销太高的问题?
谢谢!
答
该模型不出现训练的原因是因为输入读数,梯度计算和minimize()
呼叫都被定义外(且因此,在数据流而言,之前)的tf.while_loop()
的主体。这意味着在循环执行之前,模型的所有这些部分只运行一次,而循环本身不起作用。
轻微重构—移动dequeue()
操作,梯度计算,minimize()
呼叫内环路—修复问题,并允许程序训练:
optimizer = tf.train.GradientDescentOptimizer(0.05)
def cond(i):
return i < 10
def body(i):
# Dequeue a new example each iteration.
x = q_x.dequeue()
y = q_y.dequeue()
# Compute the loss and gradient update based on the current example.
loss = (tf.add(tf.mul(x, w), b) - y)**2
train_op = optimizer.minimize(loss, global_step=gs)
# Ensure that the update is applied before continuing.
return tf.tuple([tf.add(i, 1)], control_inputs=[train_op])
loop = tf.while_loop(cond, body, [i])
UPDATE:这里有一个完成程序执行while循环,根据您的问题中的代码:
import tensorflow as tf
# Define a single queue with two components to store the input data.
q_data = tf.FIFOQueue(100000, [tf.float32, tf.float32])
# We will use these placeholders to enqueue input data.
placeholder_x = tf.placeholder(tf.float32, shape=[None])
placeholder_y = tf.placeholder(tf.float32, shape=[None])
enqueue_data_op = q_data.enqueue_many([placeholder_x, placeholder_y])
gs = tf.Variable(0)
w = tf.Variable(0.)
b = tf.Variable(0.)
optimizer = tf.train.GradientDescentOptimizer(0.05)
# Construct the while loop.
def cond(i):
return i < 10
def body(i):
# Dequeue a single new example each iteration.
x, y = q_data.dequeue()
# Compute the loss and gradient update based on the current example.
loss = (tf.add(tf.multiply(x, w), b) - y) ** 2
train_op = optimizer.minimize(loss, global_step=gs)
# Ensure that the update is applied before continuing.
with tf.control_dependencies([train_op]):
return i + 1
loop = tf.while_loop(cond, body, [tf.constant(0)])
data = [k * 1. for k in range(10)]
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
for _ in range(1):
# NOTE: Constructing the enqueue op ahead of time avoids adding
# (potentially many) copies of `data` to the graph.
sess.run(enqueue_data_op,
feed_dict={placeholder_x: data, placeholder_y: data})
print (sess.run([gs, w, b])) # Prints before-loop values.
sess.run(loop)
print (sess.run([gs, w, b])) # Prints after-loop values.
我应该在外面定义** w **和** b **吗?所以我正在尝试类似的东西(现在我尝试了你提供的东西),但是我得到了错误*所有输入到节点,而/ GradientDescent/update_while/w/ApplyGradientDescent必须来自同一帧。* –
我添加了完整的程序我用TensorFlow 0.10rc0运行。 (您可能需要升级;'tf.while_loop()'实现中存在各种错误,在前几个版本中已修复。 – mrry
是的,我在0.9上启动它,谢谢,更新后它工作!还有一个关于你的解决方案的问题 - 它看起来像新的优化器创建的每一步,以及如果我想使用Ftrl优化器(它有一些更新的插槽)会怎么样?它会像训练过程中的一个优化器一样工作吗? –