tensorflowを1.12にバージョンアップすると、tf.kerasのmodel.save()が使えるようになるのですが、1.10のままのソースだとエラーになる場合があります。
tf.kerasのmodel.save()は、1.11ではエラーで使えませんでした。
1.12の場合も、同じようなエラーに見えますが内容が違います。
1.12で仕様変更があったみたい
例えば、以下のようなソースです。
import tensorflow as tf mnist = tf.keras.datasets.mnist (x_train, y_train),(x_test, y_test) = mnist.load_data() x_train, x_test = x_train / 255.0, x_test / 255.0 model = tf.keras.models.Sequential([ tf.keras.layers.Flatten(), tf.keras.layers.Dense(512, activation=tf.nn.relu), tf.keras.layers.Dropout(0.2), tf.keras.layers.Dense(10, activation=tf.nn.softmax) ]) model.compile(optimizer=tf.keras.optimizers.Adam(), loss=tf.keras.losses.sparse_categorical_crossentropy, metrics=['accuracy']) model.fit(x_train, y_train, epochs=2) model.evaluate(x_test, y_test) model.save('my_model.h5')
これは。
1.10では問題なく動きます。
1.11ではエラーになって保存できません。(回避もできません)
1.12ではソースによっては動きますが、上記のようなソースの場合だと、以下のようなエラーメッセージでエラーになります。
NotImplementedError: Currently `save` requires model to be a graph network. Consider using `save_weights`, in order to save the weights of the model.
原因は仕様変更のようです。
どうも、1.12で仕様が厳しくなって、modelを定義する最初のレイヤーで、「input_shape」を必ず指定しないと「graph network」と認識されず、上記のエラーがでるようになったみたいです。
これを回避するための方法です。
上記のソースの場合は以下の部分を修正します。
tf.keras.layers.Flatten(),
これを、以下のようにします。
tf.keras.layers.Flatten(input_shape=(28,28)),
このように、modelを定義する最初のレイヤーで、「input_shape」を指定してあれば、エラーがでずに保存できるようになります。
ちょっと したことですし、「input_shape」を指定する方が正しい書き方なのは間違いないのですが、1.10まで普通に動いていたソースがいきなり動かなくなって、上記のようなエラーメッセージをはくと、かなり焦ります。
自分もそうでした。
それにしても。
tensorflowをバージョンアップすると毎回、ドキドキさせられますねえ。
最後に。
1.12で正常動作するソース全文です。
import tensorflow as tf mnist = tf.keras.datasets.mnist (x_train, y_train),(x_test, y_test) = mnist.load_data() x_train, x_test = x_train / 255.0, x_test / 255.0 model = tf.keras.models.Sequential([ tf.keras.layers.Flatten(input_shape=(28,28)), tf.keras.layers.Dense(512, activation=tf.nn.relu), tf.keras.layers.Dropout(0.2), tf.keras.layers.Dense(10, activation=tf.nn.softmax) ]) model.compile(optimizer=tf.keras.optimizers.Adam(), loss=tf.keras.losses.sparse_categorical_crossentropy, metrics=['accuracy']) model.fit(x_train, y_train, epochs=2) model.evaluate(x_test, y_test) model.save('my_model.h5')
ではでは。
2018/12/09追記
上記例では、input_shapeで(28,28)などと固定で書いてます。
でも、毎回こうはいきません。
全結合だけのネットワークの場合は、データ量によって違ったりします。
そういう場合の書き方を補足しておきます。
model.add(tf.keras.layers.Flatten(input_shape=x_train.shape[1:]))
これだと、データ量が変動してもOKです。