Keras(TensorFlow)反序列化模型报错:name 'array_ops'未定义
array_ops未定义错误 嘿,这个坑我之前在TF 1.x版本里踩过!你遇到的NameError: name 'array_ops' is not defined问题,本质是旧版本TensorFlow的Keras后端内部实现的小bug,加上Lambda层反序列化时的上下文依赖问题导致的。
问题根源
你用Keras Lambda包装的expand_dims调用,其实底层调用了TensorFlow的array_ops.expand_dims,但在你使用的TF版本(对应Python3.6的TF 1.x系列)里,Keras后端的expand_dims函数内部没有正确导入array_ops模块,当模型反序列化时,Lambda层的执行上下文找不到这个命名空间,就抛出了错误。
具体解决方案
这里给你两个靠谱的解决办法,按优先级推荐:
1. 替换为TensorFlow原生的tf.expand_dims(最推荐)
不要用Keras后端的K.expand_dims,直接调用TF的原生函数,这样能绕开Keras后端的内部依赖问题。修改你的Lambda层代码如下:
import tensorflow as tf from keras.layers import Lambda # 原来的错误写法(依赖Keras后端) # expand_layer = Lambda(lambda x: K.expand_dims(x, axis=-1)) # 修改后的正确写法 expand_layer = Lambda(lambda x: tf.expand_dims(x, axis=-1))
这样修改后,模型序列化和反序列化时,Lambda层的代码会直接引用全局的tf模块,不会出现命名空间找不到的问题。
2. 显式导入array_ops模块(hack但有效)
如果你一定要保留Keras后端的调用方式,可以在定义Lambda层的代码里显式导入array_ops,确保反序列化时上下文能找到它:
from keras.layers import Lambda import keras.backend as K from tensorflow.python.ops import array_ops # 显式导入array_ops模块 expand_layer = Lambda(lambda x: K.expand_dims(x, axis=-1))
这个方法是强制把array_ops引入全局作用域,让Keras后端的函数能找到它,但不如第一种方法简洁。
3. 确保训练和加载模型的环境版本一致
另外要注意:训练模型时用的TensorFlow/Keras版本,要和加载模型时的版本完全匹配。版本不兼容也会导致这类奇怪的序列化/反序列化错误,比如你用TF 1.13训练,却用TF 1.15加载,就可能出现依赖问题。
内容的提问来源于stack exchange,提问作者stuart

