Entkoppeln Sie es, indem Sie einen Wert für die Variablenspeicherauslagerung erstellen, und hängen Sie dann von dieser Variablen ab, anstatt die Operation aus der Warteschlange zu nehmen. während geschieht assign
Lösung 1 die Warteschlange Advancing: feste Größe Daten verwenden Variablen
(image_batch_live,) = tf.train.batch([image],batch_size=5,num_threads=1,capacity=614)
image_batch = tf.Variable(
tf.zeros((batch_size, image_size, image_size, color_channels)),
trainable=False,
name="input_values_cached")
advance_batch = tf.assign(image_batch, image_batch_live)
Jetzt image_batch
neuesten Wert der Warteschlange gibt, ohne sie zu fort und advance_batch
schreitet die Warteschlange.
Lösung # 2: variable Größe Daten verwenden persistent Tensoren
Hier entkoppeln wir den Workflow von dequeue_op
und dequeue_op2
einzuführen. Die gesamte Berechnung hängt von dequeue_op2
ab, die den gespeicherten Wert von dequeue_op
erhält. Die Verwendung von get_session_tensor/get_session_handle
stellt sicher, dass die tatsächlichen Daten in der TensorFlow-Laufzeit verbleiben und der Wert, der über feed_dict
übergeben wird, eine kurze Zeichenfolge ist. Die API ist ein wenig umständlich, weil dummy_handle
, ich habe dieses Thema angesprochen here
import tensorflow as tf
def create_session():
sess = tf.InteractiveSession(config=tf.ConfigProto(operation_timeout_in_ms=3000))
return sess
tf.reset_default_graph()
sess = create_session()
dt = tf.int32
dummy_handle = sess.run(tf.get_session_handle(tf.constant(1)))
q = tf.FIFOQueue(capacity=20, dtypes=[dt])
enqueue_placeholder = tf.placeholder(dt, shape=[None])
enqueue_op = q.enqueue(enqueue_placeholder)
dequeue_op = q.dequeue()
size_op = q.size()
dequeue_handle_op = tf.get_session_handle(dequeue_op)
dequeue_placeholder, dequeue_op2 = tf.get_session_tensor(dummy_handle, dt)
compute_op1 = tf.reduce_sum(dequeue_op2)
compute_op2 = tf.reduce_sum(dequeue_op2)+1
# fill queue with variable size data
for i in range(10):
sess.run(enqueue_op, feed_dict={enqueue_placeholder:[1]*(i+1)})
sess.run(q.close())
try:
while(True):
dequeue_handle = sess.run(dequeue_handle_op) # advance the queue
val1 = sess.run(compute_op1, feed_dict={dequeue_placeholder: dequeue_handle.handle})
val2 = sess.run(compute_op2, feed_dict={dequeue_placeholder: dequeue_handle.handle})
size = sess.run(size_op)
print("val1 %d, val2 %d, queue size %d" % (val1, val2, size))
except tf.errors.OutOfRangeError:
print("Done")
Sie sollten wie unten etwas sehen, wenn Sie es ausführen
val1 1, val2 2, queue size 9
val1 2, val2 3, queue size 8
val1 3, val2 4, queue size 7
val1 4, val2 5, queue size 6
val1 5, val2 6, queue size 5
val1 6, val2 7, queue size 4
val1 7, val2 8, queue size 3
val1 8, val2 9, queue size 2
val1 9, val2 10, queue size 1
val1 10, val2 11, queue size 0
Done
ich wahrscheinlich, dass die Größe erwähnt haben sollte Mein Eingangstensor ist in der ersten Dimension zwischen den Stapeln variabel. Das liegt daran, dass wir mit molekularen Daten arbeiten und dass die Moleküle im Gegensatz zu Bilddaten, bei denen alle Bilder eine feste Größe haben, unterschiedliche Atomzahlen haben. Also, ich glaube nicht, dass die Verwendung einer tf.Variable funktionieren wird, da diese eine feste Größe haben müssen. – mkmatlock
Hm, wie benutzt du eine Warteschlange? Warteschlangen ähneln Variablen insofern, als sie einen Puffer fester Größe zuweisen. –
Je nachdem, wie genau Ihr Problem strukturiert ist, gibt es viele Lösungen. Diese Frage würde also weitere Details erfordern. Im Allgemeinen sind 1) pad Dinge in eine Variable fester Größe passen, 2) verwenden Strings, die variable Menge von Daten in feste Dimension Tensor setzen können 3) Zwischenspeicher eine Zwischenstufe, die feste Größe ist statt variabler Größe Eingang 4) verwenden persistent Tensoren zum Speichern von Tensor variabler Größe zwischen Laufaufrufen –