使用VGG16预训练模型训练CIFAR10时遇形状不匹配错误求助
问题解决:VGG16训练CIFAR10时logits与labels形状不匹配错误
错误原因
核心问题是损失函数与任务类型不匹配:
- CIFAR10是10分类任务,你已经通过
np_utils.to_categorical将标签转换为One-Hot编码(形状为(None,10)),输出层也使用softmax激活函数输出多分类概率。 - 但你在
model.compile中使用了binary_crossentropy(二分类专用损失函数),该函数默认期望标签形状为(None,1),因此导致模型输出((None,10))与标签((None,10))在损失计算时出现形状不匹配的冲突。
解决步骤
只需将损失函数替换为多分类任务对应的categorical_crossentropy即可:
model.compile(loss='categorical_crossentropy', optimizer=optimizers.Adam(lr=LEARNING_RATE), metrics=['accuracy'])
额外性能优化提示(非当前错误,但影响模型效果)
VGG16预训练模型基于224×224尺寸的ImageNet数据集训练,而CIFAR10图片尺寸仅为32×32。虽然代码中指定input_shape可以正常运行,但小尺寸输入会限制VGG16的特征提取能力。建议在输入模型前将图片resize到224×224:
from tensorflow.keras.preprocessing.image import img_to_array, array_to_img x_train = np.array([img_to_array(array_to_img(img).resize((224, 224))) for img in x_train]) x_test = np.array([img_to_array(array_to_img(img).resize((224, 224))) for img in x_test])
修正后的完整代码
import numpy as np from tensorflow import keras from tensorflow.keras import layers, optimizers from tensorflow.keras.applications import VGG16 from tensorflow.keras.models import Model from tensorflow.keras.utils import to_categorical (x_train, y_train), (x_test, y_test) = keras.datasets.cifar10.load_data() # 可选:将图片resize到VGG16期望的224×224尺寸 from tensorflow.keras.preprocessing.image import img_to_array, array_to_img x_train = np.array([img_to_array(array_to_img(img).resize((224, 224))) for img in x_train]) x_test = np.array([img_to_array(array_to_img(img).resize((224, 224))) for img in x_test]) height = x_train.shape[1] width = x_train.shape[2] channel = x_train.shape[3] BATCH_SIZE = 32 EPOCHS = 2 NUM_CLASSES = 10 LEARNING_RATE = 1e-4 y_train = to_categorical(y_train, NUM_CLASSES) y_test = to_categorical(y_test, NUM_CLASSES) base_model_VGG16 = VGG16(weights='imagenet', include_top=False, input_shape=(height, width, channel)) for layer in base_model_VGG16.layers: layer.trainable = False # 构建自定义分类头 x = base_model_VGG16.output x = layers.GlobalAveragePooling2D()(x) x = layers.BatchNormalization()(x) x = layers.Dense(256, activation='relu')(x) x = layers.Dense(256, activation='relu')(x) x = layers.Dropout(0.6)(x) predictions = layers.Dense(NUM_CLASSES, activation='softmax')(x) model = Model(inputs=base_model_VGG16.input, outputs=predictions) # 使用正确的多分类损失函数 model.compile(loss='categorical_crossentropy', optimizer=optimizers.Adam(learning_rate=LEARNING_RATE), metrics=['accuracy']) callbacks = [ keras.callbacks.ModelCheckpoint("save_at_{epoch}.keras"), ] model.fit( x_train, y_train, epochs=EPOCHS, callbacks=callbacks, batch_size=BATCH_SIZE )
内容的提问来源于stack exchange,提问作者MD Rafsun Sheikh
相关产品推荐
相关产品推荐

