web-dev-qa-db-fra.com

Fuite de mémoire avec TensorFlow

J'ai une fuite de mémoire avec TensorFlow. J'ai fait référence à Tensorflow: fuite de mémoire même lors de la fermeture de la session? pour résoudre mon problème, et j'ai suivi les conseils de la réponse, qui semblait avoir résolu le problème. Cependant, cela ne fonctionne pas ici.

Afin de recréer la fuite de mémoire, j'ai créé un exemple simple. Tout d'abord, j'utilise cette fonction (que j'ai obtenue ici: Comment obtenir le CPU actuel et RAM utilisation en Python? ) pour vérifier l'utilisation de la mémoire du 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)

Ensuite, chaque fois que j'appelle la fonction build_model, L'utilisation de la mémoire augmente.

Voici la fonction build_model Qui a une fuite de mémoire:

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 

J'aurais pensé qu'en utilisant le bloc with tf.Graph().as_default(), tf.Session() as sess: puis fermant la session et appelant tf.reset_default_graph effacerait toute la mémoire utilisée par TensorFlow. Apparemment non.

La fuite de mémoire peut être recréée comme suit:

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

La sortie de ceci est (pour mon ordinateur):

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

Il est clair que nous pouvons voir que toute la mémoire utilisée par TensorFlow n'est pas libérée par la suite. Pourquoi?

J'ai tracé l'utilisation de la mémoire sur 100 itérations d'appels build_model, Et voici ce que j'obtiens:

Memory use over 100 iterations

Je pense que cela montre qu'il y a une fuite de mémoire.

14
Syzygy

Le problème était dû à la version 0.11 de Tensorflow. À ce jour, Tensorflow 0.12 est sorti et le bug est résolu. Mettez à niveau vers une version plus récente et cela devrait fonctionner comme prévu. N'oubliez pas d'appeler tf.contrib.keras.backend.clear_session() à la fin.

2
Syzygy

J'ai eu le même problème. Tensorflow (v2.0.0) consommait environ 0,3 Go à chaque époque d'un modèle LSTM que j'entraînais. J'ai découvert que les crochets de rappel tensorflow étaient le principal coupable. J'ai supprimé le rappel du tensorboard et cela a bien fonctionné après

history = model.fit(
        train_x,
        train_y,
        epochs=EPOCHS,
        batch_size=BATCH_SIZE,
        validation_data=(test_x, test_y)
        ,callbacks=[tensorboard, checkpoint]
)
2
Ravindhran Sankar

J'ai également rencontré quelque chose de similaire dans TF 1.12. Ne créez pas le graphique et la session pour chaque itération. Chaque fois que le graphique est créé et la variable initialisée, vous ne redéfinissez pas l'ancien graphique mais en créez de nouveaux entraînant des fuites de mémoire. J'ai pu résoudre ce problème en définissant le graphique une fois, puis en passant la session à ma logique itérative.

De Comment ne pas programmer Tensorflow

  • Soyez conscient du moment où vous créez des opérations et ne créez que celles dont vous avez besoin. Essayez de garder la création d'opérations distincte de l'exécution d'opérations.
  • Surtout si vous travaillez simplement avec le graphique par défaut et que vous exécutez de manière interactive dans un REPL ou un bloc-notes normal), vous pouvez vous retrouver avec beaucoup d'opérations abandonnées dans votre graphique. exécutez une cellule de bloc-notes qui définit toutes les opérations graphiques, vous ne redéfinissez pas seulement les opérations, vous en créez de nouvelles.

Voir aussi this excellente réponse pour une meilleure compréhension.

0
ug2409

Normalement, nous utilisons la boucle en dehors d'une session. Je pense que ce qui se passe ici est à chaque fois que vous ajoutez de plus en plus de morceaux de mémoire lors de l'exécution de cette init_op = tf.global_variables_initializer (). Parce que si la boucle est en dehors de la session, elle ne sera initialisée qu'une seule fois. Ce qui arrive, c'est qu'il est toujours initialisé et gardé cela en mémoire.

Modification de la réponse car vous avez toujours un problème de mémoire

C'est peut-être le graphique. Parce qu'à chaque fois vous allez créer un graphe qui contiendra la mémoire.Essayez de le supprimer et d'exécuter. En le supprimant, toutes vos opérations seront considérées comme le graphique par défaut. Je pense que vous avez besoin d'une sorte de fonction de vidage de mémoire en dehors du tensorflow. car chaque fois que vous l'exécutez, il empilera un graphique.

0

Ce problème de fuite de mémoire a été résolu dans la récente version stable Tensorflow 1.15.0. J'ai exécuté le code dans la question et je vois presque aucune fuite comme indiqué ci-dessous. Il y a eu de nombreuses améliorations de performances dans la récente version stable de TF1.15 et TF2.0.

memory use: 0.4033699035644531
memory use: 0.4062042236328125
memory use: 0.4088172912597656

Veuillez vérifier la colab Gist here . Merci!

0