InvalidArgumentError: ConcatOp : 在使用 Conv2D 预测 X_test 时,输入的维度应该匹配 - 为啥?

Posted

技术标签:

【中文标题】InvalidArgumentError: ConcatOp : 在使用 Conv2D 预测 X_test 时,输入的维度应该匹配 - 为啥?【英文标题】:InvalidArgumentError: ConcatOp : Dimensions of inputs should match when predicting on X_test with Conv2D - why?InvalidArgumentError: ConcatOp : 在使用 Conv2D 预测 X_test 时,输入的维度应该匹配 - 为什么? 【发布时间】:2022-01-01 01:34:35 【问题描述】:

我正在学习 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

【问题讨论】:

【参考方案1】:

使用model.predict,您可以按照here 的说明对批次进行预测:

计算是分批完成的。此方法专为批量处理大量输入而设计。它不适用于迭代数据并一次处理少量输入的循环内部。

但是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]]

【讨论】:

谢谢,这行得通!我对“批量”参数有点困惑——如果我的样本量是质数会发生什么?看来我需要阅读更多关于预测的内容:)

以上是关于InvalidArgumentError: ConcatOp : 在使用 Conv2D 预测 X_test 时,输入的维度应该匹配 - 为啥?的主要内容,如果未能解决你的问题,请参考以下文章

InvalidArgumentError:输入必须是向量,得到形状:[]

Tensorflow 中带有 model.fit 的 InvalidArgumentError

InvalidArgumentError: input_1:0 已输入和提取

InvalidArgumentError:预期维度在 [-1, 1) 范围内,但得到 1

InvalidArgumentError:不兼容的形状:[29] 与 [29,7,7,2]

InvalidArgumentError: 预期 'tf.Tensor(False, shape=(), dtype=bool)' 为真