Keras中model.fit报错:Shapes (None,18)与(None,17)不兼容
解决Keras中EfficientNetB0训练时形状不兼容问题
问题背景
基于Keras和TensorFlow,使用ImageNet预训练的EfficientNetB0进行17类图像分类任务,已划分训练/测试集并完成独热编码,模型编译正常,但执行训练代码时触发形状不兼容报错。
模型构建代码:
effnet = EfficientNetB0(weights='imagenet',include_top=False,input_shape=(image_size,image_size,3)) model = effnet.output model = tf.keras.layers.GlobalAveragePooling2D()(model) model = tf.keras.layers.Dropout(rate=0.5)(model) model = tf.keras.layers.Dense(17,activation='softmax')(model) model = tf.keras.models.Model(inputs=effnet.input, outputs = model) model.compile(loss='categorical_crossentropy',optimizer = 'Adam', metrics= ['accuracy'])
训练代码及核心报错:
history = model.fit(X_train,y_train,validation_split=0.1, epochs =10, verbose=1,batch_size=32, callbacks=[tensorboard,checkpoint,reduce_lr])
ValueError: Shapes (None, 18) and (None, 17) are incompatible
报错核心原因
标签的独热编码维度为(None,18),但模型最后一层输出维度是(None,17),二者不匹配。大概率是以下两种情况:
- 实际数据集包含18类,而非你之前认定的17类
- 独热编码时未指定正确的类别数,导致自动生成了18维的标签向量
解决步骤
1. 确认真实类别数
先排查数据集的标签数量,验证真实类别数:
import numpy as np print("训练集标签唯一类别数:", len(np.unique(y_train)))
若输出为18,说明之前的类别统计有误。
2. 修正模型输出维度
如果真实类别数是18,将模型最后一层Dense的单元数改为18:
# 替换原有的Dense层代码 model = tf.keras.layers.Dense(18,activation='softmax')(model)
3. 重新生成正确的独热编码
如果是独热编码参数错误(比如使用to_categorical时未指定num_classes),重新生成标签:
# 假设y_train是整数型标签,真实类别数为18 y_train = tf.keras.utils.to_categorical(y_train, num_classes=18) y_test = tf.keras.utils.to_categorical(y_test, num_classes=18)
4. 验证形状匹配
修改完成后,确认模型输出与标签形状一致:
print("模型输出形状:", model.output_shape) print("训练集标签形状:", y_train.shape)
二者需保持一致(如均为(None,18)),之后重新编译并训练模型即可。
内容的提问来源于stack exchange,提问作者Kenn Sanchez
相关产品推荐
相关产品推荐

