TensorFlow 2.0中如何加载含自定义lambda层的旧版Keras模型?
问题原因
你遇到的报错本质是TensorFlow 1.x时代独立Keras保存的Lambda层序列化时,会把当时依赖的全局后端变量K(即keras.backend)的引用直接嵌入序列化数据,迁移到TensorFlow 2.x内置Keras环境后,加载时找不到对应全局变量触发NameError。你之前拆分保存结构和权重无法解决,是因为模型结构序列化结果中依然保留了依赖K的Lambda层字节码配置。
可行解决方案
- 方案一:全局注入K变量(操作最简单,优先尝试)
加载模型前先将TensorFlow 2.x的后端对象注入到全局命名空间,匹配旧模型序列化时的变量依赖:
import tensorflow as tf import sys # 注入全局K变量,适配旧模型Lambda层的调用依赖 sys.modules['__main__'].K = tf.keras.backend def load_efficient_pose_model(): custom_objects = {'BilinearWeights': keras_BilinearWeights, 'Swish': Swish(eswish), 'eswish': eswish, 'swish1': swish1} # 新增compile=False参数,避免加载时不必要的编译校验报错 model = tf.keras.models.load_model('my_location/EfficientPoseII.h5', custom_objects=custom_objects, compile=False) return model
加载成功后建议立即将模型转存为TensorFlow 2.x原生的SavedModel格式,避免后续再出现类似兼容性问题。
- 方案二:权重迁移适配(方案一失效时使用)
如果Lambda层序列化的字节码兼容性问题无法通过注入变量解决,可手动搭建兼容TF2的EfficientPose网络结构,再迁移权重:
- 从EfficientPose官方仓库获取对应版本的网络结构代码,将所有Lambda层的逻辑显式改写为自定义层,所有
keras.backend调用替换为tf.keras.backend - 在TF2环境中初始化该结构得到空白模型
- 用方案一的方式加载旧h5模型后,调用
blank_model.set_weights(old_model.get_weights())完成权重迁移 - 保存新的SavedModel格式模型即可正常使用。
内容的提问来源于stack exchange,提问作者Andrey
相关产品推荐
相关产品推荐

