Утечка памяти с помощью TensorFlow

У меня утечка памяти с TensorFlow. Я ссылался на Tensorflow: утечка памяти даже при закрытии сессии? чтобы решить мою проблему, и я последовал советам ответа, который, казалось, решил проблему. Однако это не работает здесь.

Чтобы воссоздать утечку памяти, я создал простой пример. Во-первых, я использую эту функцию (которую я получил здесь: Как узнать текущее использование процессора и оперативной памяти в Python?), Чтобы проверить использование памяти процессом python:

def memory():
    import os
    import psutil
    pid = os.getpid()
    py = psutil.Process(pid)
    memoryUse = py.memory_info()[0]/2.**30  # memory use in GB...I think
    print('memory use:', memoryUse)

Затем, каждый раз, когда я build_model функцию build_model, использование памяти увеличивается.

Вот функция build_model с утечкой памяти:

def build_model():

    '''Model'''

    tf.reset_default_graph()


    with tf.Graph().as_default(), tf.Session() as sess:
        tf.contrib.keras.backend.set_session(sess)

        labels = tf.placeholder(tf.float32, shape=(None, 1))
        input = tf.placeholder(tf.float32, shape=(None, 1))

        x = tf.contrib.keras.layers.Dense(30, activation='relu', name='dense1')(input)
        x1 = tf.contrib.keras.layers.Dropout(0.5)(x)
        x2 = tf.contrib.keras.layers.Dense(30, activation='relu', name='dense2')(x1)
        y = tf.contrib.keras.layers.Dense(1, activation='sigmoid', name='dense3')(x2)


        loss = tf.reduce_mean(tf.contrib.keras.losses.binary_crossentropy(labels, y))

        train_step = tf.train.AdamOptimizer(0.004).minimize(loss)

        #Initialize all variables
        init_op = tf.global_variables_initializer()
        sess.run(init_op)

        sess.close()

    tf.reset_default_graph()

    return 

Я бы подумал, что использование блока with tf.Graph().as_default(), tf.Session() as sess: а затем закрытие сессии и вызов tf.reset_default_graph очистит всю память, используемую TensorFlow. Видимо это не так.

Утечка памяти может быть воссоздана следующим образом:

memory()
build_model()
memory()
build_model()
memory()

Вывод этого (для моего компьютера):

memory use: 0.1794891357421875
memory use: 0.184417724609375
memory use: 0.18923568725585938

Ясно видно, что вся память, используемая TensorFlow, впоследствии не освобождается. Зачем?

Я составил график использования памяти за 100 итераций вызова build_model, и вот что я получаю:

Memory use over 100 iterations

Я думаю, что это показывает, что есть утечка памяти.

Ответ 1

Проблема была связана с Tensorflow версии 0.11. На сегодняшний день вышел Tensorflow 0.12, и ошибка устранена. Обновитесь до новой версии, и она должна работать как положено. Не забудьте в tf.contrib.keras.backend.clear_session() вызвать tf.contrib.keras.backend.clear_session().

Ответ 2

Обычно то, что произошло, мы используем цикл за пределами сеанса. Я думаю, что здесь происходит каждый раз, когда вы добавляете все больше и больше блоков памяти при запуске этого init_op = tf.global_variables_initializer(). Потому что, если цикл находится вне сеанса, он будет инициализирован только один раз. Слушайте, это всегда инициализируется и сохраняет это в памяти.

Редактирование ответа, поскольку все еще есть проблема с памятью

Возможно, это граф. Потому что каждый раз, когда вы создадите график, который будет хранить память. Попробуйте удалить его и запустить. Удалив его, вы будете считать все операции графиком по умолчанию. Я думаю, вам нужна какая-то функция флеш-памяти за пределами тензорного потока. потому что каждый раз, когда вы запускаете это, он складывает график.

Ответ 3

Я столкнулся с чем-то похожим в TF 1.12. Не создавайте график и сессию для каждой итерации. Каждый раз, когда создается граф и инициализируется переменная, вы не переопределяете старый граф, а создаете новый, что приводит к утечкам памяти. Я смог решить эту проблему, определив граф один раз, а затем передав сессию в свою итеративную логику.

Как не программировать Tensorflow

  • Будьте внимательны, когда создаете операции, и создавайте только те, которые вам нужны. Старайтесь отличать создание операции от операции.
  • Особенно, если вы просто работаете с графиком по умолчанию и работаете в интерактивном режиме в обычном REPL или записной книжке, вы можете получить множество заброшенных операций на графике. Каждый раз, когда вы перезапускаете ячейку блокнота, которая определяет какие-либо графические операции, вы не просто переопределяете операции - вы создаете новые.

Также, посмотрите этот отличный ответ для лучшего понимания.