2016-12-06 31 views
1

В настоящее время я пытаюсь отойти от использования каналов и начать использовать очереди, чтобы поддерживать более крупные массивы данных. Использование очередей работает отлично для оптимизаторов в тензорном потоке, так как они только оценивают градиент один раз для каждой операции детекции. Тем не менее, я реализовал интерфейсы с другими оптимизаторами, которые выполняют поиск строк, и мне нужно оценить не только градиент, но и потерю в нескольких точках для той же партии. К сожалению, при нормальной системе очередей каждая оценка потерь будет выполнять декомпрессию, а не вычислять одну и ту же партию несколько раз.Обработка декомпозиции из вычисления градиента/потерь

Есть ли способ отделить операцию декомпозиции от вычисления градиента/потерь таким образом, что я могу выполнить декомпрессию один раз, а затем выполнить вычисление градиента/потерь несколько раз в текущей партии?

Редактировать: Пожалуйста, обратите внимание, что размер моего тензора ввода варьируется между партиями. Мы работаем с молекулярными данными, и каждая молекула имеет различное количество атомов. Это сильно отличается от данных изображения, где все обычно масштабируется, чтобы иметь одинаковые размеры.

ответ

2

Разложите его, создав переменную хранилища, выданную из очереди, а затем зависните от этой переменной вместо dequeue op. Выросшая очередь происходит во время assign

Решения # 1: данные фиксированного размера, используйте переменные

(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) 

Теперь image_batch дает последнее значение из очереди без опережения его и advance_batch продвигается очередь.

Решение # 2: данные переменного размера, используют стойкие Тензоры

Здесь мы расцепить рабочий процесс путем введения dequeue_op и dequeue_op2. Все вычисления зависят от dequeue_op2, который подает сохраненное значение dequeue_op. Использование гарантирует, что фактические данные остаются в среде исполнения TensorFlow, а значение, которое прошло через feed_dict, является коротким идентификатором строки. API немного неудобно из-за dummy_handle, я привел этот вопрос 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") 

Вы должны увидеть что-то, как показано ниже, когда вы запустите его

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 
+0

я, вероятно, следовало бы отметить, что размер мой входной тензор является переменным в первом измерении между партиями. Это связано с тем, что мы работаем с молекулярными данными, а молекулы имеют различное количество атомов, в отличие от данных изображения, где все изображения фиксированного размера. Поэтому я не думаю, что использование tf.Variable будет работать, поскольку они должны быть фиксированными. – mkmatlock

+0

Хм, как вы используете очередь? Очереди похожи на переменные, поскольку они выделяют буфер фиксированного размера. –

+0

Существует множество решений в зависимости от того, как именно структурирована ваша проблема, поэтому для этого вопроса потребуется более подробная информация. В общем случае выбор состоит в том, что 1) накладывать элементы, чтобы они вписывались в переменную фиксированного размера, 2) использовать строки, которые могут помещать переменное количество данных в тензор фиксированного размера; 3) кэшировать промежуточный этап, который является фиксированным размером вместо ввода с переменным размером; 4) использовать постоянный тензоры для сохранения тензора переменного размера между вызовами вызова –

Смежные вопросы