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

自定义L1Dist层导致Siamese模型加载失败问题求助

解决自定义L1Dist层Siamese模型加载报错问题

问题概述

基于TensorFlow/Keras实现包含自定义L1Dist层的Siamese网络,训练完成后将模型保存为siamese_model.h5文件,使用tf.keras.models.load_model加载时触发如下错误:

ValueError: Unexpected object from deserialization, expected a layer or operation, got a <class '__main__.L1Dist'>

报错原因

  1. 自定义L1Dist层的__init__方法未将关键字参数传递给父类Layer的构造函数,导致层的元信息缺失
  2. 自定义层缺少get_config方法,无法在序列化时保存层的配置,反序列化时无法正确重建层对象
  3. 加载模型时,custom_objects参数中存在类名拼写错误(原代码中误写为Siamese_layer,实际应为L1Dist)

代码修改方案

1. 修正自定义L1Dist层

确保__init__传递kwargs给父类,并添加get_config方法:

from tensorflow.keras.layers import Layer

class L1Dist(Layer):
    # 修正__init__方法,传递kwargs给父类
    def __init__(self, **kwargs):
        super(L1Dist, self).__init__(**kwargs)

    def call(self, input_embedding, validation_embedding):
        return tf.math.abs(input_embedding - validation_embedding)
    
    # 添加get_config方法,支持序列化
    def get_config(self):
        # 调用父类的get_config,保留默认配置
        config = super(L1Dist, self).get_config()
        return config

2. 修正模型加载代码

确保custom_objects中的类名正确,同时无需额外指定binary_crossentropy(Keras默认可识别):

# 修正加载时的custom_objects参数
new_model = tf.keras.models.load_model('siamese_model.h5', custom_objects={'L1Dist': L1Dist})

完整修正后的核心代码片段

# 嵌入层定义(假设make_embedding已正确实现)
embedding = make_embedding()

# 修正后的自定义L1Dist层
class L1Dist(Layer):
    def __init__(self, **kwargs):
        super(L1Dist, self).__init__(**kwargs)

    def call(self, input_embedding, validation_embedding):
        return tf.math.abs(input_embedding - validation_embedding)
    
    def get_config(self):
        config = super(L1Dist, self).get_config()
        return config

# Siamese模型构建函数
def make_siamese_model():
    input_image = Input(name='input_img', shape=(100,100,3))
    validation_image = Input(name='validation_img', shape=(100,100,3))

    siamese_layer = L1Dist(name='distance')  # 直接在实例化时指定name,无需手动修改_name属性
    distances = siamese_layer(embedding(input_image), embedding(validation_image))

    classifier = Dense(1, activation='sigmoid')(distances)

    return Model(inputs=[input_image, validation_image], outputs=classifier, name='SiameseNetwork')

# 训练流程(原训练代码可保留,无需修改)
siamese_model = make_siamese_model()
binary_cross_loss = tf.losses.BinaryCrossentropy()
opt = tf.keras.optimizers.Adam(1e-4)

# ...(省略训练步骤代码)

# 保存模型
siamese_model.save('siamese_model.h5')

# 修正后的模型加载代码
new_model = tf.keras.models.load_model('siamese_model.h5', custom_objects={'L1Dist': L1Dist})

验证方法

  1. 使用修正后的代码重新训练模型并保存
  2. 执行加载代码,确认不再报错
  3. 可通过new_model.summary()查看模型结构,验证加载是否成功

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 10:54:54