TensorFlow训练MNIST模型报错:无法将元素转换为Tensor
解决TensorFlow训练MNIST CNN时的TypeError问题
问题根源
你的代码存在两个关键错误触发了该TypeError:
- 损失函数传递方式错误:
model.compile中直接传入了tf.keras.losses.CategoricalCrossentropy类本身,而非该类的实例。TensorFlow要求接收损失函数的实例(或对应的字符串标识符),不能直接传类对象。 - Conv2D层input_shape参数冗余:你在Conv2D层中设置了
input_shape=(None, 28, 28, 1),其中None是多余的——input_shape只需指定单样本的特征维度,批量维度会由TensorFlow自动处理。
修正方案
1. 调整模型定义中的Conv2D层
移除input_shape中的None,或者直接删除该参数(因为call方法中已经手动reshape输入,模型可自动推断输入形状):
class CNN(tf.keras.Model): def __init__(self): super().__init__() self.conv1 = tf.keras.layers.Conv2D(filters=3, kernel_size=3, strides=(1,1), padding="valid", activation="relu", input_shape=(28,28,1)) self.drop1 = tf.keras.layers.Dropout(rate=0.5) self.conv2 = tf.keras.layers.Conv2D(filters=3, kernel_size=3, strides=(1,1), padding="valid", activation="relu") self.drop2 = tf.keras.layers.Dropout(rate=0.5) self.flatten = tf.keras.layers.Flatten() self.dense1 = tf.keras.layers.Dense(units=10, activation="relu") self.dense2 = tf.keras.layers.Dense(units=10, activation="softmax") def call(self, inputs): x = tf.reshape(inputs, [-1, inputs.shape[1], inputs.shape[2], 1]) x = self.conv1(x) x = self.drop1(x) x = self.conv2(x) x = self.drop2(x) x = self.flatten(x) x = self.dense1(x) x = self.dense2(x) return x
2. 修正model.compile的损失函数配置
两种可选修正方式:
# 方式1:使用损失类的实例 model.compile(optimizer="Adam", loss=tf.keras.losses.CategoricalCrossentropy(), metrics=['accuracy', 'AUC']) # 方式2:使用字符串标识符(更简洁,新手推荐) model.compile(optimizer="Adam", loss="categorical_crossentropy", metrics=['accuracy', 'AUC'])
验证修正效果
完成上述调整后,执行训练代码即可正常运行:
hist = model.fit(x_train[:30, :, :], y_train[:30, :], batch_size=1)
额外建议
- 新手优先使用字符串形式指定损失函数、优化器,避免类实例化的语法错误。
- 训练前可打印数据的形状和类型,确认预处理是否正确:
print(x_train.shape, x_train.dtype) print(y_train.shape, y_train.dtype)
内容的提问来源于stack exchange,提问作者Diogo Santos
相关产品推荐
相关产品推荐

