ResNet50迁移学习加载权重时形状不匹配问题求助
ResNet50权重形状不匹配问题解决
问题说明
尝试用ResNet50构建自定义人脸识别模型,运行代码时出现权重形状不匹配错误,相关代码、报错信息如下:
原代码
def resnet50tl(input_shape, outclass, sigma='sigmoid'): base_model = None base_model = keras.applications.resnet50.ResNet50(weights='imagenet', include_top=False, input_shape=input_shape) base_model.load_weights(resnet50weight) for layer in base_model.layers: layer.trainable = False top_model = Sequential() top_model.add(Flatten(input_shape=base_model.output_shape[1:])) for i in range(2): top_model.add(Dense(4096, activation='relu')) top_model.add(Dropout(0.5)) top_model.add(Dense(outclass, activation=sigma)) model = Model(inputs=base_model.input, outputs=top_model(base_model.output)) if resnet50weight is not None: model.load_weights(resnet50weight, by_name=True, skip_mismatch=True, reshape=True) return model input_shape = (224, 224, 3) numclasses = 6 model = resnet50tl(input_shape, numclasses, 'softmax') lr = 1e-5 decay = 1e-7 optimizer = RMSprop(lr=lr, decay=decay) model.compile(loss='categorical_crossentropy', optimizer=optimizer, metrics=['accuracy'])
报错信息
File "c:\Users\mahmo\Downloads\test\VGG model.py", line 109, in <module> model = resnet50tl(input_shape, numclasses, 'softmax') File "c:\Users\mahmo\Downloads\test\VGG model.py", line 87, in resnet50tl base_model.load_weights(resnet50weight) File "C:\Users\mahmo\AppData\Local\Programs\Python\Python310\lib\site-packages\keras\src\utils\traceback_utils.py", line 70, in error_handler raise e.with_traceback(filtered_tb) from None File "C:\Users\mahmo\AppData\Local\Programs\Python\Python310\lib\site-packages\keras\src\backend.py", line 4361, in _assign_value_to_variable variable.assign(value) ValueError: Cannot assign value to variable ' conv3_block1_0_conv/kernel:0': Shape mismatch.The variable shape (1, 1, 256, 512), and the assigned value shape (512, 128, 1, 1) are incompatible
错误原因及解决方案
核心问题
- 重复加载权重:初始化
base_model时已指定weights='imagenet'加载官方权重,紧接着又调用base_model.load_weights(resnet50weight)覆盖,两次加载的权重格式/结构不匹配。 - 权重文件不兼容:
resnet50weight对应的权重文件可能与Keras官方ResNet50的层形状、通道顺序(如通道在前/在后)不匹配,或是其他框架导出的权重。
修正代码
def resnet50tl(input_shape, outclass, sigma='sigmoid'): # 直接加载指定权重,无自定义权重时用imagenet base_model = keras.applications.resnet50.ResNet50( weights=resnet50weight if resnet50weight else 'imagenet', include_top=False, input_shape=input_shape ) # 冻结基模型所有层 for layer in base_model.layers: layer.trainable = False # 构建顶层分类器 top_model = Sequential() top_model.add(Flatten(input_shape=base_model.output_shape[1:])) for i in range(2): top_model.add(Dense(4096, activation='relu')) top_model.add(Dropout(0.5)) top_model.add(Dense(outclass, activation=sigma)) # 拼接完整模型 model = Model(inputs=base_model.input, outputs=top_model(base_model.output)) return model input_shape = (224, 224, 3) numclasses = 6 model = resnet50tl(input_shape, numclasses, 'softmax') lr = 1e-5 decay = 1e-7 optimizer = RMSprop(lr=lr, decay=decay) model.compile(loss='categorical_crossentropy', optimizer=optimizer, metrics=['accuracy'])
额外说明
- 若
resnet50weight是自定义训练的权重,确保为Keras兼容的.h5格式,且与当前ResNet50结构完全匹配(输入形状、层名称一致)。 - 若为其他框架(如PyTorch)转换的权重,需调整通道顺序(Keras默认通道最后,PyTorch通道在前),或重新转换权重格式。
- 若必须分两次加载权重,需给
base_model.load_weights()添加by_name=True, skip_mismatch=True参数跳过不匹配层,但不推荐此方式,易引发后续问题。
内容的提问来源于stack exchange,提问作者nariaa 99
相关产品推荐
相关产品推荐

