TensorFlow 使用 tf.while_loop() 陷入无限循环
TensorFlow stuck into endless loop using tf.while_loop()
重现步骤
我正在使用TensorFlow实现一个需要使用tf.while_loop()
的网络
import tensorflow as tf
import numpy as np
class model(object):
def __init__(self):
self.argmax_ep_gate_array = [ tf.placeholder(tf.int32, [None]) for _ in range(10)]
argmax_ep_gate_array_concat = tf.concat(0, self.argmax_ep_gate_array)
story_len = tf.constant(7)
starter = tf.constant(0)
z = []
def body(hops):
hops = tf.add(hops,1)
z.append(hops)
return hops
def condition(hops):
return tf.logical_and(tf.less(tf.gather(argmax_ep_gate_array_concat, hops),story_len),tf.less(hops,tf.constant(20)))
self.gate_index = tf.while_loop(condition,body,[starter])
self.z=tf.concat(0,z)
def step(self, sess):
feed={}
for i in range(10):
feed[self.argmax_ep_gate_array[i].name]=[i]
print (sess.run([self.gate_index,self.z],feed))
with tf.Session() as sess:
while_loop = model()
sess.run(tf.initialize_all_variables())
while_loop.step(sess)
你试过什么?
我发现如果我想 sess.run() body() 中未返回的任何变量,tensorflow 将陷入无限循环。
上面的例子很简单,但它揭示了一些东西。在实际情况下,我正在使用 tf.while_loop()
运行ning 一个包含 y= wx+b 之类的 RNN,但是 w
和 b
不会在一段时间后返回环形。在前向网络中,它工作正常。但是,如果我 运行 反向传播,程序将陷入死循环。我想上面的代码重现了我的问题,因为反向传播确实需要修改 w
和 b
。或者有什么办法可以处理这个问题?
TL;DR: 您不能存储在循环体中创建的张量供以后使用,因为这会破坏有关循环结构的一些假设。
一般来说,condition()
和body()
函数一定不能有副作用。
实际上,您的程序不太可能具有预期的行为:TensorFlow 将执行 body()
函数 一次 ,以构建必要的图形结构,因此 z
只会在 运行 model.__init__()
.
之后包含一个元素
相反,您必须在循环体中逐步构造 z
,使用 tf.concat()
并将值生成为循环变量:
starter = tf.constant(0)
z_initial = tf.constant([], dtype=tf.int32)
def body(hops, z_prev):
hops = tf.add(hops, 1)
z_next = tf.concat(0, [z_prev, tf.expand_dims(hops, 0)])
return hops, z_next
def condition(hops, z):
return tf.logical_and(tf.less(tf.gather(
argmax_ep_gate_array_concat, hops), story_len), tf.less(hops, tf.constant(20)))
self.gate_index, self.z = tf.while_loop(condition,body,[starter, z_initial])
重现步骤
我正在使用TensorFlow实现一个需要使用tf.while_loop()
import tensorflow as tf
import numpy as np
class model(object):
def __init__(self):
self.argmax_ep_gate_array = [ tf.placeholder(tf.int32, [None]) for _ in range(10)]
argmax_ep_gate_array_concat = tf.concat(0, self.argmax_ep_gate_array)
story_len = tf.constant(7)
starter = tf.constant(0)
z = []
def body(hops):
hops = tf.add(hops,1)
z.append(hops)
return hops
def condition(hops):
return tf.logical_and(tf.less(tf.gather(argmax_ep_gate_array_concat, hops),story_len),tf.less(hops,tf.constant(20)))
self.gate_index = tf.while_loop(condition,body,[starter])
self.z=tf.concat(0,z)
def step(self, sess):
feed={}
for i in range(10):
feed[self.argmax_ep_gate_array[i].name]=[i]
print (sess.run([self.gate_index,self.z],feed))
with tf.Session() as sess:
while_loop = model()
sess.run(tf.initialize_all_variables())
while_loop.step(sess)
你试过什么?
我发现如果我想 sess.run() body() 中未返回的任何变量,tensorflow 将陷入无限循环。
上面的例子很简单,但它揭示了一些东西。在实际情况下,我正在使用 tf.while_loop()
运行ning 一个包含 y= wx+b 之类的 RNN,但是 w
和 b
不会在一段时间后返回环形。在前向网络中,它工作正常。但是,如果我 运行 反向传播,程序将陷入死循环。我想上面的代码重现了我的问题,因为反向传播确实需要修改 w
和 b
。或者有什么办法可以处理这个问题?
TL;DR: 您不能存储在循环体中创建的张量供以后使用,因为这会破坏有关循环结构的一些假设。
一般来说,condition()
和body()
函数一定不能有副作用。
实际上,您的程序不太可能具有预期的行为:TensorFlow 将执行 body()
函数 一次 ,以构建必要的图形结构,因此 z
只会在 运行 model.__init__()
.
相反,您必须在循环体中逐步构造 z
,使用 tf.concat()
并将值生成为循环变量:
starter = tf.constant(0)
z_initial = tf.constant([], dtype=tf.int32)
def body(hops, z_prev):
hops = tf.add(hops, 1)
z_next = tf.concat(0, [z_prev, tf.expand_dims(hops, 0)])
return hops, z_next
def condition(hops, z):
return tf.logical_and(tf.less(tf.gather(
argmax_ep_gate_array_concat, hops), story_len), tf.less(hops, tf.constant(20)))
self.gate_index, self.z = tf.while_loop(condition,body,[starter, z_initial])