微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Tensorflow:Model 是用形状 (None, 28, 28) 构建的,但它在形状不兼容的输入上被调用 (None, 28)

如何解决Tensorflow:Model 是用形状 (None, 28, 28) 构建的,但它在形状不兼容的输入上被调用 (None, 28)

我正在使用 keras 中的 MNIST 数据集解决数字识别任务。 任务本身运行顺利,但后来我尝试使用相同的模型 对于我用“paint”创建的其他一些手写数字。 由于原始大小是 (192,188,3),所以我特意将大小调整为 (28,28)。 但是,一旦我在这个新创建的数字上尝试模型(见附件),这是我收到的警告消息:

警告:tensorflow:模型是用形状 (None,28,28) 构建的,用于输入 KerasTensor(type_spec=TensorSpec(shape=(None,28),dtype=tf.float32,name='flatten_input'),name='flatten_input',description="created by layer 'flatten_input'"),但它在形状不兼容的输入上被调用(无,28)

除此错误消息外:

ValueError:输入 0 层密集与层不兼容:输入形状的预期轴 -1 具有值 784,但接收到形状为 (None,28) 的输入

这是我的代码

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

解决方法

您的代码的问题在于您的模型需要一个 3 维输入 (batch_size,width,height),而您给它的是一个二维图像 (width,height)

您可以先将输入图像重塑为正确的形状,如下所示:

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

模型的第一层是 tf.keras.layers.Flatten(),即展平。意味着它就像一个数组。数组长度是 784(28X28X1 ~ 长 x 宽 x 通道)是多少。所以如果你把 model.summary() 放在第一层是:

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

所以这意味着 predict 期望输入数据为 (1,784)。您可以调整输入图像的大小并使其变灰,但还需要更多步骤。请参考以下代码并对每一行进行注释:

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,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,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))

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。