我正在使用 keras 中的 MNIST 数据集解决数字识别任务。 任务本身运行顺利,但后来我尝试使用相同的模型 对于我用“paint”创建的其他一些手写数字。 由于原始大小是 (192, 188, 3),所以我特意将大小调整为 (28, 28)。 但是,一旦我在这个新创建的数字上尝试模型(见附件),这是我收到的警告消息:
警告:tensorflow:模型是用形状 (None, 28, 28) 构建的,用于输入 KerasTensor(type_spec=TensorSpec(shape=(None, 28, 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()
答案 0 :(得分:0)
您的代码的问题在于您的模型需要一个 3 维输入 (batch_size, width, height)
,而您给它的是一个二维图像 (width, height)
。
您可以先将输入图像重塑为正确的形状,如下所示:
np.reshape(img_6, (1, 28, 28))
答案 1 :(得分:0)
模型的第一层是 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, 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))