You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

保存为.keras格式后无法加载ResNet50迁移学习模型求助

模型保存后加载失败问题排查

操作流程

  1. 加载预训练ResNet50并冻结层
pretrained = tf.keras.applications.ResNet50(include_top = False, 
                                      input_shape = (224,224,3), 
                                      pooling = 'avg',
                                      classes = 525,
                                      weights = 'imagenet' 
                                           )

for layer in pretrained.layers: # 设置层不参与训练
    layer.trainable = False
  1. 构建自定义Sequential模型
model = keras.Sequential()

model.add(pretrained) 
model.add(keras.layers.Dense(512, activation = 'relu', name = 'capa_1'))
model.add(keras.layers.Dense(525, activation = 'softmax', name = 'capa_de_salida'))
  1. 训练模型(最终准确率达90%)
opt = keras.optimizers.Adam(learning_rate = 5.5e-05)
model.compile(optimizer = opt, loss = 'categorical_crossentropy', metrics = ['accuracy'])

history = model.fit(train_dataset,
               epochs = 10,
               validation_data = val_dor)

保存与加载报错

保存模型后执行加载操作失败:

path_model = './ResNet50_trans_learning_final.keras'
model.save(path_model)

modelo2 = tf.keras.models.load_model(path_model, compile=False)

报错详情

--------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[102], line 5
      1 model.save('ResNet50_trans_learning_final.keras')
      3 path_model = './ResNet50_trans_learning_final.keras'
----> 5 modelo2 = tf.keras.models.load_model(path_model, compile=False)
      6 # 问题出在flatten层,无法读取

File /usr/local/lib/python3.11/dist-packages/keras/src/saving/saving_api.py:176, in load_model(filepath, custom_objects, compile, safe_mode)
    173         is_keras_zip = True
    175 if is_keras_zip:
--> 176     return saving_lib.load_model(
    177         filepath,
    178         custom_objects=custom_objects,
    179         compile=compile,
    180         safe_mode=safe_mode,
    181     )
    182 if str(filepath).endswith((".h5", ".hdf5")):
    183     return legacy_h5_format.load_model_from_hdf5(filepath)

File /usr/local/lib/python3.11/dist-packages/keras/src/saving/saving_lib.py:155, in load_model(filepath, custom_objects, compile, safe_mode)
    153 # 从归档中的配置文件构建模型
    154 with ObjectSharingScope():
--> 155     model = deserialize_keras_object(
    156         config_dict, custom_objects, safe_mode=safe_mode
    157     )
    159 all_filenames = zf.namelist()
    160 if _VARS_FNAME + ".h5" in all_filenames:

File /usr/local/lib/python3.11/dist-packages/keras/src/saving/serialization_lib.py:711, in deserialize_keras_object(config, custom_objects, safe_mode, **kwargs)
    709 with custom_obj_scope, safe_mode_scope:
    710     try:
--> 711         instance = cls.from_config(inner_config)
    712     except TypeError as e:
    713         raise TypeError(
    714             f"{cls}无法正确反序列化,请确保所有Python对象组件(如自定义层、损失函数等)都已正确注册。"
   (...)
    719             f"配置={config}。遇到的异常:{e}"
    720         )

File /usr/local/lib/python3.11/dist-packages/keras/src/models/sequential.py:336, in Sequential.from_config(cls, config, custom_objects)
    331     else:
    332         layer = serialization_lib.deserialize_keras_object(
    333             layer_config,
    334             custom_objects=custom_objects,
    335         )
--> 336     model.add(layer)
    337 if (
    338     not model._functional
    339     and build_input_shape
    340     and isinstance(build_input_shape, (tuple, list))
    341 ):
    342     model.build(build_input_shape)

File /usr/local/lib/python3.11/dist-packages/keras/src/models/sequential.py:117, in Sequential.add(self, layer, rebuild)
    115 self._layers.append(layer)
    116 if rebuild:
--> 117     self._maybe_rebuild()
    118 else:
    119     self.built = False

File /usr/local/lib/python3.11/dist-packages/keras/src/models/sequential.py:136, in Sequential._maybe_rebuild(self)
    134 if isinstance(self._layers[0], InputLayer) and len(self._layers) > 1:
    135     input_shape = self._layers[0].batch_shape
--> 136     self.build(input_shape)

File /usr/local/lib/python3.11/dist-packages/keras/src/layers/layer.py:224, in Layer.__new__.<locals>.build_wrapper(*args, **kwargs)
    221 @wraps(original_build_method)
    222 def build_wrapper(*args, **kwargs):
    223     with backend.name_scope(obj.name, caller=obj):
--> 224         original_build_method(*args, **kwargs)
    225     # 记录构建配置
    226     signature = inspect.signature(original_build_method)

File /usr/local/lib/python3.11/dist-packages/keras/src/models/sequential.py:177, in Sequential.build(self, input_shape)
    175 for layer in self._layers[1:]:
    176     try:
--> 177         x = layer(x)
    178     except NotImplementedError:
    179         # 形状推断未实现时可能发生
    180         # TODO:考虑还原已处理层的入站节点
    181         return

File /usr/local/lib/python3.11/dist-packages/keras/src/utils/traceback_utils.py:123, in filter_traceback.<locals>.error_handler(*args, **kwargs)
    120     filtered_tb = _process_traceback_frames(e.__traceback__)
    121     # 要获取完整堆栈跟踪,请调用:
    122     # `keras.config.disable_traceback_filtering()`
--> 123     raise e.with_traceback(filtered_tb) from None
    124 finally:
    125     del filtered_tb

File /usr/local/lib/python3.11/dist-packages/keras/src/layers/input_spec.py:202, in assert_input_compatibility(input_spec, inputs, layer_name)
    200 if spec.min_ndim is not None:
    201     if ndim is not None and ndim < spec.min_ndim:
--> 202         raise ValueError(
    203             f'层"{layer_name}"的输入0与该层不兼容:期望最小维度={spec.min_ndim},实际找到维度={ndim}。接收的完整形状:{shape}'
    204         )
    209 # 检查数据类型
    210 if spec.dtype is not None:

ValueError: 层"capa_de_salida"的输入0与该层不兼容:期望最小维度=2,实际找到维度=1。接收的完整形状:(512,)

使用环境

基于TensorFlow 2.16.1的Docker容器:

sudo docker run -it --rm -v ./:/tf/notebooks -p 8888:8888 --runtime=nvidia tensorflow/tensorflow:latest-gpu-jupyter

问题分析与解决办法

问题原因

报错核心是输出层capa_de_salida期望接收2维输入(格式为(批量大小, 特征数)),但模型加载时形状推断异常,实际传入了1维的(512,)张量。这是因为Sequential模型序列化时,没有完整保存输入形状的上下文信息,导致重建时无法正确推断各层的输入维度。

解决办法

1. 构建模型时显式添加输入层

在预训练模型前添加InputLayer,确保模型输入形状被明确记录:

model = keras.Sequential()
model.add(keras.layers.Input(shape=(224,224,3)))  # 显式定义输入形状
model.add(pretrained) 
model.add(keras.layers.Dense(512, activation = 'relu', name = 'capa_1'))
model.add(keras.layers.Dense(525, activation = 'softmax', name = 'capa_de_salida'))

重新训练并保存模型后,加载时就能正确推断各层维度。

2. 加载模型时关闭安全模式

TensorFlow 2.16默认开启safe_mode=True的严格形状检查,尝试关闭该模式加载:

modelo2 = tf.keras.models.load_model(path_model, compile=False, safe_mode=False)

3. 改用Functional API构建模型

Functional API的序列化逻辑更稳定,能避免Sequential模型的形状推断问题:

inputs = keras.Input(shape=(224,224,3))
x = pretrained(inputs)
x = keras.layers.Dense(512, activation='relu', name='capa_1')(x)
outputs = keras.layers.Dense(525, activation='softmax', name='capa_de_salida')(x)
model = keras.Model(inputs=inputs, outputs=outputs)

用此方式构建的模型,保存和加载过程不会出现维度不匹配问题。

内容的提问来源于stack exchange,提问作者Lesim Use

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 05:22:01