10
import tensorflow as tf 

mnist = tf.keras.datasets.mnist 

(x_train, y_train), (x_test, y_test) = mnist.load_data()

x_train = tf.keras.utils.normalize(x_train, axis=1)
x_test = tf.keras.utils.normalize(x_test, axis=1)

model = tf.keras.models.Sequential()

model.add(tf.keras.layers.Flatten())
model.add(tf.keras.layers.Dense(128,activation=tf.nn.relu))
model.add(tf.keras.layers.Dense(128,activation=tf.nn.relu))
model.add(tf.keras.layers.Dense(10,activation=tf.nn.softmax))

model.compile(optimizer ='adam',
            loss='sparse_categorical_crossentropy',
             metrics=['accuracy'])
model.fit(x_train, y_train, epochs=3)

When I tried to save the model

model.save('epic_num_reader.model')

I get a NotImplementedError:

NotImplementedError                       Traceback (most recent call last)
<ipython-input-4-99efa4bdc06e> in <module>()
      1 
----> 2 model.save('epic_num_reader.model')

NotImplementedError: Currently `save` requires model to be a graph network. Consider using `save_weights`, in order to save the weights of the model.

So how can I save the model defined in the code?

Evan-Gao
  • 131
  • 1
  • 1
  • 5
  • Ah I see you were also trying the tutorial at https://pythonprogramming.net/introduction-deep-learning-python-tensorflow-keras/. Glad to see you've already found a solution – Anonymous Person Jan 15 '19 at 02:45

5 Answers5

12

You forgot the input_shape argument in the definition of the first layer, which makes the model undefined, and saving undefined models has not been implemented yet, which triggers the error.

model.add(tf.keras.layers.Flatten(input_shape = (my, input, shape)))

Just add the input_shape to the first layer and it should work fine.

Dr. Snoopy
  • 55,122
  • 7
  • 121
  • 140
  • This is a great answer.Thank you. – Evan-Gao Sep 29 '18 at 09:28
  • I follow the same sentdex tutorial and changed the code to `model.add(tf.keras.layers.Flatten(input_shape=x_train.shape))` buI got `expected flatten_1_input to have 4 dimensions, but got array with shape (60000, 28, 28)` when run `model.fit()`. What should the code be exactly? – hanaZ Nov 04 '18 at 19:40
  • @hanaZ Input shape should not contain the batch/samples dimension, and in the future remember that comments are to clarify questions and answers, not to introduce your own. – Dr. Snoopy Nov 04 '18 at 20:48
  • 3
    @Matias. Thanks much for the reply. I tried with `model.add(tf.keras.layers.Flatten(input_shape=x_train[0].shape))` , then it worked. – hanaZ Nov 13 '18 at 23:10
  • 1
    It will work fine, but I found that the performance of my model dropped massively and [asked a question about it](https://stackoverflow.com/questions/54054119/what-is-the-structure-of-a-keras-model-if-input-shape-is-omitted-and-why-does-it) (currently unexplained) – Roman Starkov Jan 06 '19 at 22:55
  • If that's the reason, why doesn't it work after calling `model.build(input_shape)`? – olejorgenb Jan 17 '19 at 10:09
  • Specifically, you have to add the following code. model.add(tf.keras.layers.Flatten(input_shape=(28, 28))) – Tharinda Wicky Jan 24 '19 at 18:09
3

For those who still have not solved the problem even did as Matias suggested, you can consider using tf.keras.models.save_model() and load_model(). In my case, it worked.

Employee
  • 3,109
  • 5
  • 31
  • 50
1
tf.keras.models.save_model

Works here (tensorflow 1.12.0) (even when the input_shape is unspecified)

olejorgenb
  • 1,203
  • 14
  • 25
1

Reason For the Error:

I was getting the same error and tried the above answers but got errors. But I find a solution to the problem that I will share below:

Check whether you passed input_shape at the time of defining the input layer of the model if not you will get an error at the time of saving and loading the model.

How to define input_shape?

Lets consider the one example If you use minst dataset:

mnist = tf.keras.datasets.mnist
(x_train, y_train), (x_test, y_test) = mnist.load_data()

It consists of images of handwritten digits 0-9 of size 28 x 28 resolution each. For this, we can define input shape as (28,28) without mentioning batch size as follows:

model.add(tf.keras.layers.Flatten(input_shape=(28,28)))

In this way, you can give input shape by looking at your input training dataset.

Save your trained model:

Now after training and testing the model we can save our model. Following code worked for me it did not change the accuracy as well after reloading the model:

by using save_model()

import tensorflow as tf    
tf.keras.models.save_model(
    model,
    "your_trained_model.model",
    overwrite=True,
    include_optimizer=True
) 

by using .save()

your_trained_model.save('your_trained_model.model')

del model  # deletes the existing model

Now load the model which we saved :

model2 = tf.keras.models.load_model("your_trained_model.model")

For more details refer to this link: Keras input explanation: input_shape, units, batch_size, dim, etc

Yogesh Awdhut Gadade
  • 2,498
  • 24
  • 19
0

<!-- Success, please check -->

import tensorflow as tf
import matplotlib.pyplot as plt

mnist = tf.keras.datasets.mnist
(x_train, y_train), (x_test, y_test) = mnist.load_data()
plt.imshow(x_train[0], cmap=plt.cm.binary)
x_train = tf.keras.utils.normalize(x_train, axis=1)
x_test = tf.keras.utils.normalize(x_test, axis=1)

plt.imshow(x_train[0], cmap=plt.cm.binary)

model = tf.keras.models.Sequential()
model.add(tf.keras.layers.Flatten(input_shape=x_train[0].shape))
model.add(tf.keras.layers.Dense(128, activation=tf.nn.relu))
model.add(tf.keras.layers.Dense(128, activation=tf.nn.relu))
model.add(tf.keras.layers.Dense(10, activation=tf.nn.softmax))

model.compile(optimizer='adam',
              loss='sparse_categorical_crossentropy', metrics=['accuracy'])
model.fit(x_train, y_train, epochs=3)

val_loss, val_acc = model.evaluate(x_test, y_test)
print(val_loss)
print(val_acc)
model.save('epic_num_reader.model')
ChinhNV
  • 331
  • 2
  • 6