将Keras Tensor转换为TensorFlow Tensor时遇属性错误求助
我尝试将Hugging Face的Informer模型与Keras模型结合,但该Hugging Face模型不支持Keras Tensor。我试图将Keras Tensor转换为TensorFlow Tensor,再转为NumPy数组,最后转为Torch Tensor,但在Keras Tensor转TensorFlow Tensor的步骤中遇到问题。我试过K.eval(),也开启了Eager模式、重装过TensorFlow和Keras,但转换后张量还是Keras Tensor类型,还出现了AttributeError: 'KerasTensor' object has no attribute 'numpy'错误。
模型输入代码:
input_layer = Input(shape=input_shape)
尝试的转换代码:
k_array = K.eval(k_tensor) # Convert the Keras tensor to a NumPy array n_array = np.array(k_array) # Convert the NumPy array to a TensorFlow tensor with tf.convert_to_tensor tf_tensor = tf.convert_to_tensor(n_array)
报错信息:
Traceback (most recent call last):
File "/Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/pydevconsole.py", line 364, in runcode
coro = func()
File "", line 1, in File "/Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydev_bundle/pydev_umd.py", line 198, in runfile
pydev_imports.execfile(filename, global_vars, local_vars)execute the scriptFile "/Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydev_imps/_pydev_execfile.py", line 18, in execfile
exec(compile(contents+"\n", file, 'exec'), glob, loc)
File "/Users/myname/Apple Prediction.py", line 292, in
k_array = K.eval(input_layer2)
File "/Users/myname/opt/anaconda3/envs/Prediction/lib/python3.10/ site-packages/keras/backend.py", line 1634, in eval
return get_value(to_dense(x))
File "/Users/myname/opt/anaconda3/envs/Prediction/lib/python3.10/site-packages/keras/backend.py", line 4208, in get_value
return x.numpy()
AttributeError: 'KerasTensor' object has no attribute 'numpy'
Input层生成的是符号KerasTensor,它只是模型的输入占位符,没有实际数值。numpy()或K.eval()这类方法只对包含实际数据的Eager Tensor有效,即使开启Eager模式,符号张量依然是图构建的一部分,不会自动转化为Eager Tensor。
方法1:用Lambda层在Keras模型中嵌入PyTorch模型
通过tf.py_function将PyTorch模型的调用包装成Keras可识别的操作,自动完成张量格式转换:
import tensorflow as tf import torch from transformers import InformerModel # 预加载Hugging Face Informer模型,切换到推理模式 informer_model = InformerModel.from_pretrained("your-informer-model-name") informer_model.eval() def pytorch_informer_wrapper(x): # TensorFlow张量 → NumPy数组 → PyTorch张量 torch_tensor = torch.from_numpy(x.numpy()).float() # 推理时禁用梯度计算 with torch.no_grad(): outputs = informer_model(torch_tensor) # PyTorch输出 → NumPy数组 → TensorFlow张量 return tf.convert_to_tensor(outputs.last_hidden_state.numpy()) # 构建Keras模型 input_layer = tf.keras.layers.Input(shape=input_shape) # 用Lambda层包装PyTorch模型调用 informer_output = tf.keras.layers.Lambda(pytorch_informer_wrapper)(input_layer) # 后续接Keras的其他层 output_layer = tf.keras.layers.Dense(1)(informer_output) model = tf.keras.Model(inputs=input_layer, outputs=output_layer)
注意:这种方法在训练阶段会有性能损耗,因为涉及多次跨框架张量转换;若需训练,优先选择方法2。
方法2:直接加载TensorFlow版Hugging Face模型
Hugging Face Transformers支持直接加载TensorFlow版本的模型,可与Keras无缝兼容,无需手动转换张量:
from transformers import TFAutoModel # 加载TensorFlow版本的Informer模型 tf_informer_model = TFAutoModel.from_pretrained("your-informer-model-name") # 构建Keras模型 input_layer = tf.keras.layers.Input(shape=input_shape) # 直接调用TensorFlow版模型,输出为KerasTensor informer_output = tf_informer_model(input_layer)[0] # 取last_hidden_state output_layer = tf.keras.layers.Dense(1)(informer_output) model = tf.keras.Model(inputs=input_layer, outputs=output_layer)
若官方无TensorFlow版Informer,可先通过transformers.convert_graph_to_onnx转成ONNX格式,再用TensorFlow的ONNX导入工具转为Keras层,或用torch2tf工具手动转换。
方法3:推理阶段手动处理数据
如果仅在推理时结合两个模型,可在Eager模式下先运行Keras模型得到实际输出,再转为PyTorch张量传给Informer:
# 定义Keras模型 keras_model = tf.keras.Model(inputs=input_layer, outputs=some_keras_output) # 运行Keras模型得到TensorFlow张量 tf_output = keras_model.predict(your_input_data) # 转为PyTorch张量 torch_input = torch.from_numpy(tf_output).float() # 运行Informer模型 with torch.no_grad(): informer_output = informer_model(torch_input)
内容的提问来源于stack exchange,提问作者Joe

