TensorFlow : Guide : Estimators : チェックポイント (翻訳/解説)
翻訳 : (株)クラスキャット セールスインフォメーション
更新日時 : 07/14/2018
作成日時 : 03/09/2018
* TensorFlow 1.9 でドキュメント構成が変わりましたので調整しました。
* 本ページは、TensorFlow の本家サイトの Get Started – Details – Checkpoints を翻訳した上で適宜、補足説明したものです:
* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。
このドキュメントは Estimator で構築された TensorFlow モデルをどのようにセーブしてリストアするかを考察します。TensorFlow は2つのモデル・フォーマットを提供します :
- checkpoint, これはモデルを作成したコードに依存するフォーマットです。
- SavedModel, これはモデルを作成したコードから独立したフォーマットです。
このドキュメントは checkpoint に焦点を当てます。SavedModel の詳細のためには、TensorFlow Programmer’s Guide の Saving and Restoring 章を見てください。
サンプル・コード
このドキュメントは TensorFlow から始める Getting Started で詳述されたものと同じ アイリス分類サンプル に依拠します。 ダウンロードしてサンプルにアクセスするためには、次の2つのコマンドを発行します :
git clone https://github.com/tensorflow/models/ cd models/samples/core/get_started
このドキュメントの殆どのコードスニペットは premade_estimator.py の僅かのバリエーションです。
不十分に訓練されたモデルをセーブする
Estimator は自動的に以下をディスクに書きます :
- チェックポイント, これは訓練中に作成されたモデルのバージョンです。
- イベントファイル, これは視覚化を作成するために TensorBoard が使用する情報を含みます。
Estimator がその情報をストアするトップレベル・ディレクトリを指定するには、任意の Estimator のコンストラクタのオプションの model_dir 引数に値を割り当てます。例えば、次のコードは model_dir 引数を models/iris ディレクトリに設定します :
classifier = tf.estimator.DNNClassifier( feature_columns=my_feature_columns, hidden_units=[10, 10], n_classes=3, model_dir='models/iris')
Estimator の train メソッドを呼び出すと仮定します。例えば :
classifier.train( input_fn=lambda:train_input_fn(train_x, train_y, batch_size=100), steps=200)
次の図で示されるように、train への最初の呼び出しはチェックポイントと他のファイルを model_dir ディレクトリに追加します :
作成された model_dir ディレクトリのオブジェクトを UNIX ベース・システムで見るには、次のように単に ls を呼び出します :
$ ls -1 models/iris checkpoint events.out.tfevents.timestamp.hostname graph.pbtxt model.ckpt-1.data-00000-of-00001 model.ckpt-1.index model.ckpt-1.meta model.ckpt-200.data-00000-of-00001 model.ckpt-200.index model.ckpt-200.meta
上の ls コマンドは Estimator がステップ 1 (訓練の開始) と 200 (訓練の最後) でチェックポイントを作成したことを示します。
デフォルトのチェックポイント・ディレクトリ
Estimator のコンストラクタで model_dir を指定しない場合は、Estimator はチェックポイント・ファイルを Python の tempfile.mkdtemp 関数により選択された一時ディレクトリに書きます。例えば、次の Estimator コンストラクタは model_dir 引数を指定しません :
classifier = tf.estimator.DNNClassifier( feature_columns=my_feature_columns, hidden_units=[10, 10], n_classes=3) print(classifier.model_dir)
tempfile.mkdtemp 関数は貴方のオペレーティング・システムに適切な安全な、一時ディレクトリを選択します。例えば、macOS 上の典型的な一時ディレクトリは次のようなものでしょう :
/var/folders/0s/5q9kfzfj3gx2knj0vj8p68yc00dhcr/T/tmpYm1Rwa
チェックポイントする頻度
デフォルトでは、Estimator は次のスケジュールに従って model_dir に チェックポイント をセーブします :
- 10 分 (600 秒) 毎にチェックポイントを書く。
- train メソッドが開始されて (最初の iteration) 完了する (最後の iteration) ときにチェックポイントを書く。
- ディレクトリに5つの最も最近のチェックポイントだけを保持する。
次のステップを取ることによりデフォルトのスケジュールを変更することもできます :
- 望まれるスケヂュールを定義する RunConfig オブジェクトを作成します。
- Estimator をインスタンス化するときに、Estimator の config 引数に RunConfig オブジェクトを渡します。
例えば、次のコードはチェックポイントするスケジュールを 10 分毎に変更して 10 の最も最近のチェックポイントを保持します :
my_checkpointing_config = tf.estimator.RunConfig( save_checkpoints_secs = 20*60, # Save checkpoints every 20 minutes. keep_checkpoint_max = 10, # Retain the 10 most recent checkpoints. ) classifier = tf.estimator.DNNClassifier( feature_columns=my_feature_columns, hidden_units=[10, 10], n_classes=3, model_dir='models/iris', config=my_checkpointing_config)
貴方のモデルをリストアする
最初に Estimator の train メソッドを呼び出すとき、TensorFlow はチェックポイントを model_dir にセーブします。Estimator の train, eval, または predict メソッドへの続く呼び出しの各々は次を引き起こします :
- Estimator は model_fn() を実行することによりモデルの グラフ を構築します。(model_fn() の詳細は、Creating Custom Estimators を見てください。)
- Estimator は新しいモデルの重みを最も最近のチェックポイントにストアされたデータから初期化します。
換言すれば、次の図が示すように、チェックポイントがひとたび存在すれば、TensorFlow は train(), evaluate(), または predict() を呼び出すたびにモデルを再構築します。
間違ったレストレーションを回避する
チェックポイントからモデルの状態をリストアすることはモデルとチェックポイントとが互換である場合にのみ動作します。例えば、貴方は2つの隠れ層、各々が 10 ノードを持つような DNNClassifier Estimator を訓練したと仮定します :
classifier = tf.estimator.DNNClassifier( feature_columns=feature_columns, hidden_units=[10, 10], n_classes=3, model_dir='models/iris') classifier.train( input_fn=lambda:train_input_fn(train_x, train_y, batch_size=100), steps=200)
訓練 (そして、それゆえに、models/iris にチェックポイントを作成) した後に、各隠れ層のニューロンの数を 10 から 20 に変更してそれからモデルの再訓練を試みたと想像してください :
classifier2 = tf.estimator.DNNClassifier( feature_columns=my_feature_columns, hidden_units=[20, 20], # Change the number of neurons in the model. n_classes=3, model_dir='models/iris') classifier.train( input_fn=lambda:train_input_fn(train_x, train_y, batch_size=100), steps=200)
チェックポイント内の状態は classifier2 で記述されたモデルと非互換ですから、再訓練は次のエラーで失敗します :
... InvalidArgumentError (see above for traceback): tensor_name = dnn/hiddenlayer_1/bias/t_0/Adagrad; shape in shape_and_slice spec [10] does not match the shape stored in checkpoint: [20]
モデルの僅かに異なるバージョンを訓練して比較する実験を行なうためには、多分各バージョンのために分離した git branch を作成することにより各 model-dir で作成されたコードのコピーをセーブします。この分離は貴方のチェックポイントをリカバー可能に保持するでしょう。
以上