InvalidArgumentError: ConcatOp : Dimensions of inputs should match when predicting on X_test with Conv2D - why?

InvalidArgumentError: ConcatOp : Dimensions of inputs should match when predicting on X_test with Conv2D - why?

我正在学习 Tensorflow 并尝试在 Fashion MNIST 数据集上构建分类器。我可以拟合模型,但是当我尝试在我的测试集上进行预测时,出现以下错误:

y_pred = model.predict(X_test).argmax(axis=1)

InvalidArgumentError: ConcatOp : Dimensions of inputs should match: shape[0] = [1,32,10] vs. shape[312] = [1,16,10] [Op:ConcatV2] name: concat

如果我在 X_test 上批量预测,我不会收到错误,例如:

y_pred = []
step_size = 10
for i in trange(0, len(X_test), step_size):
  y_pred += model.predict(X_test[i:i+step_size]).argmax(axis=1).tolist()[0]

我花了一些时间在谷歌上搜索并查看了相同错误的其他示例,但仍然无法弄清楚我做错了什么。我尝试了一些不同的方法,例如在构建模型之前将缩放和扩展尺寸步骤手动应用到 X_train 和 X_test,但得到相同的结果。

这是我的完整代码(使用 Python 3.7.12 和 Tensorflow 2.7.0):

import tensorflow as tf # 2.7.0
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

# load data 
mnist = tf.keras.datasets.fashion_mnist
(X_train, y_train), (X_test, y_test) = mnist.load_data()

# Build model 

# Input 
inputs = tf.keras.Input(shape=X_train[0].shape)

# # Scale 
x = tf.keras.layers.Rescaling(scale=1.0/255)(inputs)

# Add extra dimension for use in conv2d
x = tf.expand_dims(x, -1)

# Conv2D
x = tf.keras.layers.Conv2D(filters=32, kernel_size=(3, 3), activation="relu", strides=2)(x)
x = tf.keras.layers.Conv2D(filters=64, kernel_size=(3, 3), activation="relu", strides=2)(x)
x = tf.keras.layers.Conv2D(filters=128, kernel_size=(3, 3), activation="relu", strides=2)(x)

# Flatten
x = tf.keras.layers.Flatten()(x),
x = tf.keras.layers.Dropout(rate=.2)(x)  # 20% chance of dropout  
x = tf.keras.layers.Dense(512, activation='relu')(x)
x = tf.keras.layers.Dropout(rate=.2)(x)   
x = tf.keras.layers.Dense(K, activation='softmax')(x)

model = tf.keras.Model(inputs=inputs, outputs=x)

# Compile
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])

# Fit
r = model.fit(X_train, y_train, validation_data=[X_test, y_test], epochs=10)

# Throws an error
y_pred = model.predict(X_test).argmax(axis=1)

给出

InvalidArgumentError: ConcatOp : Dimensions of inputs should match: shape[0] = [1,32,10] vs. shape[312] = [1,16,10] [Op:ConcatV2] name: concat

对于 model.predict,您正在按照所述 here:

对批次进行预测

Computation is done in batches. This method is designed for batch processing of large numbers of inputs. It is not intended for use inside of loops that iterate over your data and process small numbers of inputs at a time.

但是X_test的大小默认不能被整除batch_size=32。我认为这可能是您遇到问题的原因。例如,您可以将 batch_size 更改为 16,它将起作用:

y_pred = model.predict(X_test, batch_size=16).argmax(axis=1)
print(y_pred)
[[ 8  0  2 ... 14  8  2]
 [15 15  8 ... 10  8 14]
 [ 5 13  4 ...  4  5  6]
 ...
 [11 11 12 ...  7  2  3]
 [ 3  8  0 ... 15  3 14]
 [ 3 13  1 ...  1 15  0]]

您还可以使用 model.predict_on_batch(X_test) 对单批样本进行预测。但是,如果直接使用模型的调用函数,则最灵活:

y_pred = model(X_test[:10])
tf.print(tf.argmax(y_pred, axis=1), summarize=-1)
[[2 8 0 1 1 1 8 2 2 6]]