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

基于VGG16迁移学习实现猫狗分类时遇‘Could not deserialize class 'Functional'’错误求助

基于VGG16迁移学习实现猫狗分类时遇‘Could not deserialize class 'Functional'’错误求助

Hey there! 看你贴的代码是在用VGG16做迁移学习实现猫狗分类,现在碰到了「Could not deserialize class 'Functional'」这个错误对吧?我来帮你梳理下可能的问题点和对应的解决思路:

大概率的问题根源:模型序列化/反序列化不兼容

这个错误基本都和模型的保存、加载环节有关,要么是自定义逻辑没做好序列化支持,要么是版本不匹配,咱们一步步来排查:


1. 自定义预处理函数未做序列化处理

你写的manual_preprocess_input是个普通函数,但Keras的Functional模型在保存时,会把整个模型的结构(包括所有层和操作)序列化下来。普通函数没法被Keras正确识别和序列化,等你后续加载模型时就会报错。

修复方案:把预处理逻辑包装成可序列化的层,有两种方式可选:

  • 用Lambda层快速包装(适合简单逻辑):

    # 把自定义函数包装成Lambda层
    manual_preprocess_layer = tf.keras.layers.Lambda(manual_preprocess_input)
    
    # 模型里替换原来的直接调用
    inputs = tf.keras.Input(shape=(224, 224, 3))
    x = data_augmentation(inputs)
    x = manual_preprocess_layer(x)  # 这里改用包装后的层
    x = base_model(x, training=False)
    # ... 后续代码不变
    
  • 自定义Layer类(更规范,适合复杂逻辑):

    class ManualPreprocessLayer(tf.keras.layers.Layer):
        def __init__(self, **kwargs):
            super().__init__(**kwargs)
            # 把均值定义成可序列化的变量
            self.mean = tf.constant([103.939, 116.779, 123.68], dtype=tf.float32)
            
        def call(self, inputs):
            data_format = tf.keras.backend.image_data_format()
            if data_format == 'channels_first':
                inputs = tf.transpose(inputs, perm=[0, 2, 3, 1])
            x = inputs - self.mean
            x = x / 127.5
            return x
            
        def get_config(self):
            # 必须实现这个方法,让Keras能正确序列化层的参数
            config = super().get_config()
            return config
    

    然后在模型中使用这个自定义层:

    x = ManualPreprocessLayer()(x)
    

2. TensorFlow/Keras版本不匹配

如果是保存模型后加载时报错,很大概率是保存和加载时的TF/Keras版本不一致。比如你用TF 2.10保存模型,却用TF 2.8加载,Functional模型的序列化格式可能有差异,导致无法识别。

修复方案:

  • 尽量保证保存和加载模型时使用完全相同版本的TensorFlow;
  • 如果必须跨版本,可以只保存模型权重(model.save_weights('model_weights.h5')),然后重新手动构建模型结构,再用model.load_weights('model_weights.h5')加载权重,绕开模型结构序列化的问题。

3. VGG16基础模型加载是否规范

检查下你加载VGG16的代码,确保是按照迁移学习的正确方式加载的:

base_model = tf.keras.applications.VGG16(
    include_top=False,  # 一定要去掉顶层的分类层
    input_shape=(224, 224, 3),
    weights='imagenet'  # 加载预训练权重
)
base_model.trainable = False  # 冻结基础模型,只训练后面的自定义层

如果没加include_top=False,会把VGG16的顶层分类层也加载进来,可能导致模型结构冲突,间接引发序列化问题。

4. 模型保存格式的尝试

如果用默认的SavedModel格式保存有问题,可以试试切换成HDF5格式,或者反过来:

# 保存为HDF5格式
model.save('cat_dog_model.h5')
# 加载(如果用了自定义层,要在custom_objects里指定)
model = tf.keras.models.load_model('cat_dog_model.h5', custom_objects={'ManualPreprocessLayer': ManualPreprocessLayer})

额外小建议

如果还没解决,可以先跳过模型保存/加载,直接运行训练流程,看看模型能不能正常训练和预测。如果训练没问题,那问题肯定出在保存/加载环节;如果训练时就报错,那得再检查模型结构的拼接是否有问题。另外,把错误的完整堆栈信息贴出来,能更精准地定位问题哦!

备注:内容来源于stack exchange,提问作者Oualid Laib

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.17 11:18:15