Home > Software design >  How to predict MNIST data with trained model (expected axis -1 of input shape to have value 784, but
How to predict MNIST data with trained model (expected axis -1 of input shape to have value 784, but

Time:05-16

I have followed the tensorflow2 tutorial but now want to use the model to predict an image.

My code:

import tensorflow
import tensorflow_datasets
import matplotlib.pyplot as plot
import numpy

def normalize_img(img, label):
  return tensorflow.cast(img, tensorflow.float32) / 255., label

(mnist_train, mnist_raw), mnist_info = tensorflow_datasets.load(
    'mnist',
    split=['train', 'test'],
    shuffle_files=True,
    as_supervised=True,
    with_info=True,
)

mnist_train = mnist_train.map(normalize_img, num_parallel_calls=tensorflow.data.AUTOTUNE)
mnist_train = mnist_train.cache()
mnist_train = mnist_train.shuffle(mnist_info.splits['train'].num_examples)
mnist_train = mnist_train.batch(128)
mnist_train = mnist_train.prefetch(tensorflow.data.AUTOTUNE)

mnist_test = mnist_raw.map(normalize_img, num_parallel_calls=tensorflow.data.AUTOTUNE)
mnist_test = mnist_test.batch(128)
mnist_test = mnist_test.cache()
mnist_test = mnist_test.prefetch(tensorflow.data.AUTOTUNE)

model = tensorflow.keras.models.Sequential([
  tensorflow.keras.layers.Flatten(input_shape=(28, 28)),
  tensorflow.keras.layers.Dense(128, activation='relu'),
  tensorflow.keras.layers.Dropout(0.16),
  tensorflow.keras.layers.Dense(10, activation="softmax")
])



model.compile(
    optimizer=tensorflow.keras.optimizers.Adam(0.001), 
    loss=tensorflow.keras.losses.SparseCategoricalCrossentropy(from_logits=True), 
    metrics=["accuracy"]
)

result = model.fit(mnist_train, epochs=6, validation_data=mnist_test)

it = mnist_test.as_numpy_iterator()
first = it.next()
images, labels = first[0], first[1]

plot.imshow(images[0].squeeze())
model(images[0].squeeze().flatten())

The last line gives the error:

ValueError                                Traceback (most recent call last)
ipython-input-87-57d521ba8778> in <module>()
----> 1 model(images[0].squeeze().flatten())
1 frames
/usr/local/lib/python3.7/dist-packages/keras/engine/input_spec.py in assert_input_compatibility(input_spec, inputs, layer_name)
    247         if value is not None and shape_as_list[int(axis)] not in {value, None}:
    248           raise ValueError(
--> 249               f'Input {input_index} of layer "{layer_name}" is '
    250               f'incompatible with the layer: expected axis {axis} '
    251               f'of input shape to have value {value}, '
ValueError: Exception encountered when calling layer "sequential_1" (type Sequential).
Input 0 of layer "dense_2" is incompatible with the layer: expected axis -1 of input shape to have value 784, but received input with shape (784, 1)
Call arguments received:
  • inputs=tf.Tensor(shape=(784,), dtype=float32)
  • training=False
  • mask=None

As far as I can understand, the model operator() expects a 1 dimensional array, but I supply it with a 2 dimensional array, where the second dimension is 1 (which is essentially a 1 dim. array).

I have found this question: Input 0 of layer sequential is incompatible with the layer: expected axis -1 of input shape to have value 784

But if I do reshape(1, 784) the error message switches to expecting dimension (28,28). If I do not flatten the array, I get the error that (28, 28) was supplied, but it wants (784).

CodePudding user response:

Check the shape of images[0].squeeze().flatten():

import numpy as np

print(np.shape(images[0].squeeze().flatten()))
(784,)

Your input is however (None, 28, 28). So, you don't need the flatten (that is taken care of by the Flatten at the input). Also, you need the batch dimension. So you can do:

model(np.expand_dims(images[0, :], axis=0))

Note that if you want to input more images at once, it works fine:

model(images[0:10, :])

Because the batch dimension is there.

  • Related