私がやっていること
Tensorflow-gpuをバックエンドとして使用してKerasを使用する画像分類のために、畳み込みニューロンネットワーク(CNN)をトレーニングして使用しています。
私が使用しているもの
-PyCharmコミュニティ2018.1.2
-Python 2.7と3.5の両方(一度に両方ではありません)
-Ubuntu 16.04
-Keras 2.2.0
-バックエンドとしてのTensorflow-GPU 1.8.0
知りたいこと
多くのコードで、私は人々が
from keras import backend as K
# Do some code, e.g. train and save model
K.clear_session()
または、使用後にモデルを削除します。
del model
Kerasのドキュメントには、clear_session
に関する説明があります:「現在のTFグラフを破棄し、新しいTFグラフを作成します。古いモデル/レイヤーからの混乱を避けるのに役立ちます。」 - https://keras.io/backend/
それを行う意味は何ですか?私もそれをする必要がありますか?新しいモデルをロードまたは作成するとき、モデルはとにかく上書きされます。
K.clear_session()は、ハイパーパラメーター検索や相互検証時など、複数のモデルを連続して作成する場合に役立ちます。トレーニングする各モデルは、ノードをノードに追加します(潜在的に数千の番号付け)。 TensorFlowは、tf.Session.run()またはtf.Tensor.eval()を呼び出すたびにグラフ全体を実行するため、モデルのトレーニングはますます遅くなり、メモリ不足になる可能性もあります。セッションをクリアすると、以前のモデルから残ったすべてのノードが削除され、メモリが解放され、速度低下が防止されます。
編集21/06/19:TensorFlowはデフォルトで遅延評価されます。 TensorFlow操作はすぐには評価されません。テンソルを作成したり、テンソルに対して何らかの操作を行ったりすると、データフローグラフにノードが作成されます。 tf.Session.run()またはtf.Tensor.eval()を呼び出すと、グラフの関連部分を一度に評価して結果が計算されます。これは、TensorFlowが異なるデバイスに並行して実行できる操作を割り当てる実行計画を構築できるようにするためです。また、隣接するノードを一緒に折り畳んだり、冗長なノードを削除したりすることもできます(たとえば、2つのテンソルを連結し、後で変更せずに再び分割する場合)。詳細については、 https://www.tensorflow.org/guide/graphs を参照してください
TensorFlowモデルはすべて、一連のテンソルとテンソル操作としてグラフに保存されます。機械学習の基本操作はテンソルドット積です。ニューラルネットワークの出力は、入力行列とネットワークの重みのドット積です。単一層のパーセプトロンと1,000個のトレーニングサンプルがある場合、各エポックは少なくとも1,000個のテンソル操作を作成します。エポックが1,000の場合、グラフには、前処理、後処理、およびリカレントネット、エンコーダーデコーダー、アテンションモデルなどのより複雑なモデルを考慮する前に、最後に少なくとも1,000,000個のノードが含まれます。
問題は、最終的にグラフが大きすぎてビデオメモリ(私の場合は6 GB)に収まらないため、TFがグラフの一部をビデオからメインメモリに往復することです。最終的には、メインメモリ(12 GB)には大きすぎて、メインメモリとハードディスクの間を移動し始めます。言うまでもなく、これは物事を信じられないほど、そしてトレーニングが進むにつれてますます遅くしました。このsave-model/clear-session/reload-modelフローを開発する前に、私が経験したエポックごとの減速率では、私のモデルが宇宙の年齢よりも長くかかってトレーニングを完了すると計算しました。免責事項:TensorFlowをほぼ1年も使用していないため、変更された可能性があります。これについてはGitHubでかなりの数の問題があったことを覚えているので、うまくいけば修正されました。
delはpythonの変数を削除します。モデルは変数なので、delモデルはそれを削除しますが、TFグラフには変更がありません(TFはKerasバックエンドです)。つまり、K.clear_session()は現在のTFグラフを破壊し、新しいTFグラフを作成します。新しいモデルの作成は独立したステップのようですが、バックエンドを忘れないでください:)