web-dev-qa-db-ja.com

TensorFlowでのメモリリーク

TensorFlowでメモリリークが発生しました。問題を解決するために Tensorflow:セッションを閉じているときにもメモリリークはありますか? を参照して、問題の解決策と思われる回答のアドバイスに従いました。ただし、ここでは機能しません。

メモリリークを再現するために、簡単な例を作成しました。最初に、この関数(ここで取得したもの: 現在のCPUとRAM 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関数は次のとおりです。

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によって使用されたすべてのメモリが後で解放されないことがわかります。どうして?

私はbuild_modelを呼び出す100回を超えるメモリの使用をプロットしましたが、これが私が得たものです。

Memory use over 100 iterations

これは、メモリリークがあることを示していると思います。

14
Syzygy

問題はTensorflowバージョン0.11が原因でした。本日より、Tensorflow 0.12がリリースされ、バグが解決されました。新しいバージョンにアップグレードすると、期待どおりに動作するはずです。最後にtf.contrib.keras.backend.clear_session()を呼び出すことを忘れないでください。

2
Syzygy

私も同じ問題を抱えていました。 Tensorflow(v2.0.0)は、私がトレーニングしていたLSTMモデルのすべてのエポックで約0.3GBを消費していました。私は、tensorflowコールバックフックが主な原因であることを発見しました。私はテンソルボードのコールバックを削除しましたが、その後うまくいきました

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

TF 1.12でも同様の問題に直面しました。反復ごとにグラフとセッションを作成しないでください。グラフが作成され、変数が初期化されるたびに、古いグラフを再定義するのではなく、新しいグラフを作成してメモリリークを引き起こします。これを解決するには、グラフを1回定義してから、セッションを反復ロジックに渡します。

から Tensorflowをプログラムしない方法

  • Opを作成するときは意識し、必要なopのみを作成してください。 opの実行から、opの作成distinctを維持しようとします。
  • 特に、デフォルトのグラフを使用していて、通常のREPLまたはノートブックでインタラクティブに実行している場合は、グラフに多数の破棄された演算が含まれる可能性があります。任意のグラフ演算を定義するノートブックセルを実行します。演算を再定義するだけでなく、新しい演算を作成します。

また、理解を深めるために this すばらしい回答を参照してください。

0
ug2409

通常、何が起こったかは、セッションの外でループを使用することです。ここで起こっていることは、これを実行するときにメモリチャンクを追加するたびに発生すると思いますinit_op = tf.global_variables_initializer()。ループがセッションの外にある場合は、一度だけ初期化されるためです。何が起こるかというと、それは常に初期化され、それをメモリに保持するということです。

まだメモリの問題があるため、回答を編集します

おそらくそれはグラフです。毎回、メモリを保持するグラフを作成するからです。削除して実行してみてください。削除すると、すべての操作がデフォルトのグラフになります。テンソルフローの外にある種のメモリフラッシュ関数が必要だと思います。これを実行するたびにグラフが積み上げられるからです。

このメモリリークの問題は、最近の安定バージョンのTensorflow 1.15.0で解決されました。質問のコードを実行したところ、以下に示すようにリークはほとんど発生していません。 TF1.15とTF2.0の最近の安定バージョンでは、パフォーマンスが大幅に改善されました。

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

コラボをチェックしてください ここに要点 。ありがとう!