2017-04-13 47 views
0

考慮這個簡單的例子:Tensorflow出列內while_loop

l = [1,2,324,3,12,1,2,3] 
q = tf.train.input_producer(l, shuffle=False) 
x = q.dequeue() 

t = tf.TensorArray(dtype=tf.int32, size=5, dynamic_size=True, clear_after_read=True) 

_, t = tf.while_loop(cond=lambda i, a: tf.less(i, 5, name='less_op'), 
body=lambda i, a: [i+1, a.write(i, [x])], 
loop_vars=[0, t]) 

它輸出[1 1 1 1 1],由於出隊()被調用一次。請告訴我如何在每次迭代中觸發出列操作。

謝謝!

乾杯,克里斯

回答

1

問題的出現是因爲tf.while_loop()體捕獲張x作爲不變的一個循環的 ,而你要出隊要在循環內進行的副作用

的解決方案是將呼叫轉移到q.dequeue()身體內部,如下所示:

import tensorflow as tf 

l = [1, 2, 324, 3, 12, 1, 2, 3] 
q = tf.train.input_producer(l, shuffle=False) 
t = tf.TensorArray(dtype=tf.int32, size=5, dynamic_size=True, clear_after_read=True) 

# N.B. set `parallel_iterations=1` to ensure that values are dequeued in a 
# deterministic FIFO order. 
_, t = tf.while_loop(cond=lambda i, a: tf.less(i, 5, name='less_op'), 
        body=lambda i, a: [i+1, a.write(i, [q.dequeue()])], 
        loop_vars=[0, t], 
        parallel_iterations=1) 

result = t.stack() 

sess = tf.Session() 
tf.train.start_queue_runners(sess) 
print(sess.run(result)) # ==> '[[1], [2], [324], [3], [12]]' 
print(sess.run(result)) # ==> '[[1], [2], [3], [1], [2]]' 
+0

確定,所以在情況下,我使用的讀取器(任何種類的),I只需調用reader.read(Q )以同樣的精神(而不是q.dequeue()))。但是在身體內使用批量數據呢?我可以考慮將批量加載到新隊列中,但這有點髒。這件事還有其他解決方法嗎?非常感謝你以前的迴應(:! –

+1

是的,同樣的原則適用於任何潛在的有狀態的操作(如從閱讀器讀取或讀取/寫入變量)對於批量數據,您可以使用'reader.read_up_to( n)',並可選擇將批量填充到全尺寸(因爲如果'n'沒有劃分文件中確切的記錄數,'read_up_to()'可以返回一個更小的批次)。 – mrry

+0

一如既往 - 非常豐富的答案。就像你知道我的下一個問題將會是什麼一樣(::最後一個難題是:如果我的.tfrecords文件中有_x_記錄,並且我用_y_> _x_調用reader.read_up_to(y),我會去成爲_x_記錄,還是後續的文件將被取出?我認爲前者是實際情況,但文檔只是指出:_如果需要,將隊列中的工作單元從隊列中取出(例如,當Reader需要從新文件,因爲它已經完成了前一個文件)。它可能會返回更少的t甚至在最後批次之前還有num_records__ –