如何使用经过训练的模型预测 MNIST 数据(输入形状的预期轴 -1 的值为 784,但收到的输入形状为 (784, 1))
How to predict MNIST data with trained model (expected axis -1 of input shape to have value 784, but received input with shape (784, 1))
我已经学习了 tensorflow2 教程,但现在想使用该模型来预测图像。
我的代码:
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())
最后一行报错:
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
据我所知,模型 operator() 需要一个一维数组,但我为它提供了一个二维数组,其中第二维为 1(本质上是一个 1 维数组)。
我发现了这个问题:
但如果我执行 reshape(1, 784),则错误消息会切换到期望维度 (28,28)。如果我不展平数组,我会收到错误消息,指出 (28, 28) 已提供,但它需要 (784).
检查 images[0].squeeze().flatten()
的形状:
import numpy as np
print(np.shape(images[0].squeeze().flatten()))
(784,)
但是您的输入是 (None, 28, 28)
。因此,您不需要展平(由输入处的 Flatten
处理)。此外,您还需要批量维度。所以你可以这样做:
model(np.expand_dims(images[0, :], axis=0))
请注意,如果您想一次输入更多图像,它可以正常工作:
model(images[0:10, :])
因为批次维度在那里。
我已经学习了 tensorflow2 教程,但现在想使用该模型来预测图像。
我的代码:
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())
最后一行报错:
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
据我所知,模型 operator() 需要一个一维数组,但我为它提供了一个二维数组,其中第二维为 1(本质上是一个 1 维数组)。
我发现了这个问题:
但如果我执行 reshape(1, 784),则错误消息会切换到期望维度 (28,28)。如果我不展平数组,我会收到错误消息,指出 (28, 28) 已提供,但它需要 (784).
检查 images[0].squeeze().flatten()
的形状:
import numpy as np
print(np.shape(images[0].squeeze().flatten()))
(784,)
但是您的输入是 (None, 28, 28)
。因此,您不需要展平(由输入处的 Flatten
处理)。此外,您还需要批量维度。所以你可以这样做:
model(np.expand_dims(images[0, :], axis=0))
请注意,如果您想一次输入更多图像,它可以正常工作:
model(images[0:10, :])
因为批次维度在那里。