入門者に向けてKerasの初歩を解説します。
Google Colaboratoryを使っているのでローカルでの環境準備すらしていません。Google Colaboratoryについては「Google Colaboratory概要と使用手順(TensorFlowもGPUも使える)」の記事を参照ください。
以下のシリーズにしています。
- 【Keras入門(1)】単純なディープラーニングモデル定義
- 【Keras入門(2)】訓練モデル保存(KerasモデルとSavedModel) <- 本記事
- 【Keras入門(3)】TensorBoardで見える化
- 【Keras入門(4)】Kerasの評価関数(Metrics)
- 【Keras入門(5)】単純なRNNモデル定義
- 【Keras入門(6)】単純なRNNモデル定義(最終出力のみ使用)
- 【Keras入門(7)】単純なSeq2Seqモデル定義
#使ったPythonライブラリ
Google Colaboratoryでインストール済の以下のライブラリとバージョンを使っています。KerasはTensorFlowに統合されているものを使っているので、ピュアなKerasは使っていません。Pythonは3.6です。
- tensorflow: 1.13.1
- Numpy: 1.16.3
コールバックとモデル保存
Kerasでモデルを保存する場合には、コールバックという機能を使用します。これは、訓練中に呼び出すことができる仕組みです。
前回の記事「【Keras入門(1)】単純なディープラーニングモデル定義」で使用したfit関数に渡すことで使用できます。
model.fit(data, labels, epochs=300, validation_split=0.2, callbacks=li_cb)
経験ないですが、fit_generator関数にも使えるようです。
fit関数に渡しているli_cbという変数は以下のように定義しています。配列にすることで複数の機能をコールバックで使用できます。今回は、ModelCheckpointを使ったモデルの保存です。save_best_onlyをTrueにすることで、ベストな指標が出たエポックのモデルを保存します。
from tensorflow.keras.callbacks import ModelCheckpoint, Callback
# Callbackを定義し、モデル保存の追加
li_cb = []
li_cb.append(ModelCheckpoint('./model.hdf5', save_best_only=True))
#SavedModelフォーマットでの保存(訓練時)
TensorFlow Servingなどで使用するためにSavedModelフォーマットにしたい場合もあります。その場合は、Kerasのモデルを使ってsave_keras_model関数を呼び出します。
tf.contrib.saved_model.save_keras_model(model, './models/keras_export')
ただし、tf.contribはTensorFlow2.0でなくなるため、TensorFlow2.0ではexport_saved_modelを使う必要がありそうです。
※結構、探しましたがGitHub上で見つけました。
パラメータserving_onlyをTrueにして、モデルを軽くしたかったのですが
tf.contrib.saved_model.save_keras_model(model, './models/keras_export', serving_only=True)
Eager Executionをしろというエラーが出ました。
AssertionError: tf.saved_model.save is not supported when graph building. tf.enable_eager_execution() must run first when calling it from TensorFlow 1.x.
逆にtf.enable_eager_execution()を最初に呼び出して実行すると、fit関数実行時にエラーが起きました。調べていませんが、共存できないのでしょうか。
RuntimeError: Unable to create link (name already exists)
#SavedModelフォーマットでの保存(訓練後にモデル変換)
訓練後にKerasモデルからSavedModelに変換する方法です。モデルをロードして保存するだけの非常に簡単な方法です。
from tensorflow.keras.models import load_model
# モデルを初期化してロード
model = None
model = load_model('./model.hdf5')
tf.contrib.saved_model.save_keras_model(model, './models/keras_export')
これならEager Executionしてserving_onlyをTrueにしても大丈夫です。
from tensorflow.keras.models import load_model
tf.enable_eager_execution()
# モデルを初期化してロード
model = None
model = load_model('./model.hdf5')
tf.contrib.saved_model.save_keras_model(model, './models/keras_export', serving_only=True)
saved_model_cliを使って見てみます。signature_defの"__saved_model_init_op"の部分がおかしい?
ただ、serving_defaultは問題なさそうなので、取り急ぎ無視します。
※saved_model_cliについては、CLI to inspect and execute SavedModel参照
$ saved_model_cli show --all --dir ./models/keras_export/1558534626
MetaGraphDef with tag-set: 'serve' contains the following SignatureDefs:
signature_def['__saved_model_init_op']:
The given SavedModel SignatureDef contains the following input(s):
The given SavedModel SignatureDef contains the following output(s):
outputs['__saved_model_init_op'] tensor_info:
dtype: DT_INVALID
shape: unknown_rank
name: init_1
Method name is:
signature_def['serving_default']:
The given SavedModel SignatureDef contains the following input(s):
inputs['dense_input'] tensor_info:
dtype: DT_FLOAT
shape: (-1, 2)
name: dense_input:0
The given SavedModel SignatureDef contains the following output(s):
outputs['dense_1'] tensor_info:
dtype: DT_FLOAT
shape: (-1, 1)
name: dense_1/Sigmoid:0
Method name is: tensorflow/serving/predict
ちなみにsimple_saveは、今後なくなるようなので、使わない方が無難です。
Warning: THIS FUNCTION IS DEPRECATED. It will be removed in a future version. Instructions for updating: This function will only be available through the v1 compatibility library as tf.compat.v1.saved_model.simple_save.
プログラム全体
プログラム全体をGitHubに置いています。訓練、保存、読み込んでSavedModel保存という順序です。
公式チュートリアルを参考にしました。