4

Я просто пытался кое-что попробовать для кватернионной нейронной сети, когда понял, что даже если я закрою свой текущий сеанс в цикле for, моя программа медленно замедляется, и я получаю утечку памяти, вызванную созданием ops. Это мой код:Tensorflow: утечка памяти даже при закрытии сеанса?

for step in xrange(0,200):#num_epochs * train_size // BATCH_SIZE): 
338 
339   with tf.Session() as sess: 
340 
341    offset = (BATCH_SIZE) % train_size 
342    #print "Offset : %d" % offset 
343 
344    batch_data = [] 
345    batch_labels = [] 
346    batch_data.append(qtrain[0][offset:(offset + BATCH_SIZE)]) 
347    batch_labels.append(qtrain_labels[0][offset:(offset + BATCH_SIZE)] 
352    retour = sess.run(test, feed_dict={x: batch_data}) 
357 
358    test2 = feedForwardStep(retour, W_to_output,b_output) 
367    #sess.close() 

Проблема, похоже, исходит от test2 = feedForward(..). Мне нужно объявить эти операторы после выполнения retour один раз, потому что retour не может быть заполнителем (мне нужно перебирать его). Без этой линии программа работает очень хорошо, быстро и без утечки памяти. Я не могу понять, почему это, кажется, как TensorFlow пытается «спасти» test2 даже если закрыть сессию ...

ответ

8

TL; DR: Закрытие сеанса не освобождает структуру tf.Graph данных в программе Python , и если каждая итерация цикла добавляет узлы к графику, у вас будет утечка.

Поскольку ваша функция feedForwardStep создает новые операции TensorFlow, и вы называете его в петле for, то является утечкой в ​​вашем коде — хотя тонко.

Если вы не указали иначе (используя блок with tf.Graph().as_default():), все операции TensorFlow добавляются к глобальному графику по умолчанию. Это означает, что каждый вызов tf.constant(), tf.matmul(), tf.Variable() и т. Д. Добавляет объекты в глобальную структуру данных. Есть два способа избежать этого:

  1. Структура вашей программы, так что вы построить график один раз, а затем использовать tf.placeholder() опа кормить в разных значениях в каждой итерации. Вы указываете в своем вопросе, что это может быть невозможно.

  2. Явно создаю новый график в каждом цикле. Это может потребоваться, если структура графика зависит от данных, доступных в текущей итерации. Это можно сделать следующим образом:

    for step in xrange(200): 
        with tf.Graph().as_default(), tf.Session() as sess: 
         # Remainder of loop body goes here. 
    

    Обратите внимание, что в этой версии, вы не можете использовать Tensor или Operation объекты из предыдущей итерации. (Например, из вашего фрагмента кода не видно, где test.)

+0

Спасибо! Я попробую ваше второе предложение, тест - это op, который я могу определить вне цикла for (как вы предлагаете в своей 1 точке). –

+0

К сожалению, я получил хороший «Граф сеанса пуст». Добавляем операции к графику перед вызовом run() »с помощью tf.Graph.as_default() –

+0

Плохо, что это работает! Большое спасибо ! –