简体   繁体   中英

Tensorflow:Model was constructed with shape (None, 28, 28) , but it was called on an input with incompatible shape (None, 28)

I am solving the digit recognition task using the MNIST dataset in keras. The task itself runs smoothly but afterwards I have tried to use the same model for some other handwritten digits that I created with 'paint'. Since the original size was (192, 188, 3), I specifically resized to (28, 28). However, once I try the model on this newly created digit (see attachment), this is the Warning message I get:

WARNING:tensorflow:Model was constructed with shape (None, 28, 28) for input KerasTensor(type_spec=TensorSpec(shape=(None, 28, 28), dtype=tf.float32, name='flatten_input'), name='flatten_input', description="created by layer 'flatten_input'"), but it was called on an input with incompatible shape (None, 28)

In addition to this error message:

ValueError: Input 0 of layer dense is incompatible with the layer: expected axis -1 of input shape to have value 784 but received input with shape (None, 28)

Here is my code:

import tensorflow as tf
from tensorflow import keras
import matplotlib.pyplot as plt
# %matplotlib inline
import numpy as np
import pandas as pd
import cv2 as cv

(X_train, y_train),(X_test, y_test)=keras.datasets.mnist.load_data()
# Normalize the train dataset
X_train = tf.keras.utils.normalize(X_train, axis=1)
# Normalize the test dataset
X_test = tf.keras.utils.normalize(X_test, axis=1)

#Build the model object
model = tf.keras.models.Sequential()
# Add the Flatten Layer
model.add(tf.keras.layers.Flatten())
# Build the input and the hidden layers
model.add(tf.keras.layers.Dense(128, activation=tf.nn.relu))
model.add(tf.keras.layers.Dense(128, activation=tf.nn.relu))
# Build the output layer
model.add(tf.keras.layers.Dense(10, activation=tf.nn.softmax))

# Compile the model
model.compile(optimizer="adam", loss="sparse_categorical_crossentropy", 
metrics=["accuracy"]) 
model.fit(x=X_train, y=y_train, epochs=20) # Start training process

# Evaluate the model performance
test_loss, test_acc = model.evaluate(x=X_test, y=y_test)
# Print out the model accuracy 
print('\nTest accuracy:', test_acc)

predictions = model.predict([X_test]) # Make prediction

# TRY SAME MODEL WITH NEW DIGIT 

img_6 =  cv.imread("6.png")
img_7 =  cv.imread("7.png")
img_2 =  cv.imread("2.png")


from tensorflow.keras.preprocessing import image

img =  img_7 

img=cv.resize(img, X_train[0].shape, 
            interpolation = cv.INTER_AREA) 
img = cv.cvtColor(img, cv.COLOR_BGR2GRAY) 

plt.imshow(img)
plt.show()
img=np.invert(np.array([img]))
img=np.reshape(img, ( 784, 1))
print(img.shape,'fghjkljkhjgfgfgcgvhbjnmnbjv')
plt.imshow(img)
plt.show()

img=np.expand_dims(img, axis=0) # will move it to (1,784)
print(img.shape,'fghjkljkhjgfgfgcgvhbjnmnbjv')
plt.imshow(img)
plt.show()
prediction=model.predict(img) # predict
print ('prediction=',np.argmax(prediction))
plt.imshow(img)
plt.show()

6 7 2

The problem with your code is that your model is expecting a 3-dimensional input (batch_size, width, height) , while you're giving it a single 2-dimensional image (width, height) .

You can first reshape your input image to the correct shape, like so:

np.reshape(img_6, (1, 28, 28))

The first layer on your model is tf.keras.layers.Flatten() ie flatten. means it's like an array. what is that array length is 784(28X28X1 ~ length x width x channel). so if you put model.summary() the first layer is:

Layer (type)                 Output Shape              Param #   
=================================================================
flatten (Flatten)            (None, 784)               0   

so it means that predict is expecting input data as (1,784). you are on right track to resize and gray out the input image, few more steps are needed. please refer to the below code and comment against each line:

from tensorflow.keras.preprocessing import image # import image preprocessing
img_6 =  cv.imread("6.png") # shape if (352, 324, 3) for screen snap, this could be different based on read image.
img_6=cv.resize(img_6, X_train[0].shape, 
                interpolation = cv.INTER_AREA) # now its in shape (28, 28, 3) which is~ 2352(28x28x3)
img_6 = cv.cvtColor(img_6, cv.COLOR_BGR2GRAY) # now gray image
img_6=image.img_to_array(img_6) # shape (28, 28, 1) i.e channel 1
img_6= img_6.flatten() # flatten it as model is expecting (None,784) , this will be (784,) i.e 28x28x1 =
img_6=np.expand_dims(img_6, axis=0) # will move it to (1,784)
prediction=model.predict(im1) # predict
print (np.argmax(prediction))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM