在使用hub.KerasLayer层加载模型时出现问题…… NameError:在调用Lambda.call() 时遇到异常
我在做一些NLP练习。我无法在一个hub.KerasLayer层中使用已保存的模型 :(
下面是我完成的步骤:
- 创建模型 - OK
- 编译模型 - OK
- 拟合/训练模型 - OK
import tensorflow as tf
from tensorflow.keras import layers
import tensorflow_hub as hub
# Create a Keras layer using the USE pretrained layer from tensorflow hub
sentence_encoder_layer = hub.KerasLayer("https://www.kaggle.com/models/google/universal-sentence-encoder/TensorFlow2/universal-sentence-encoder/2",
input_shape=[],
dtype=tf.string,
trainable=False,
name="USE")
# Create model using the Sequential API
model_6 = tf.keras.Sequential([
# sentence_encoder_layer, # take in sentences and then encode them into an embedding
layers.Lambda(lambda x: sentence_encoder_layer(x)),
layers.Dense(64, activation="relu"),
layers.Dense(1, activation="sigmoid"),
], name="model_6_USE")
# Compile the model
model_6.compile(loss="binary_crossentropy",
optimizer=tf.keras.optimizers.Adam(),
metrics=["accuracy"])
# Train and fit the model
history_6 = model_6.fit(train_sentences,
train_labels,
epochs=5,
validation_data=(val_sentences, val_labels))
- 对模型进行预测 - OK
# Make model predictions
model_6_pred_prods = model_6.predict(val_sentences)
model_6_pred_prods[:10]
- 保存模型 - OK
# Save model_6 to native Keras format
model_6.save("model_6_saved.keras")
- 加载模型 - OK
# Re-initialize the hub keraslayer
sentence_encoder_layer = hub.KerasLayer("https://www.kaggle.com/models/google/universal-sentence-encoder/TensorFlow2/universal-sentence-encoder/2",
input_shape=[],
dtype=tf.string,
trainable=False,
name="USE")
# Load the model
loaded_model_6 = tf.keras.models.load_model("model_6_saved.keras",
custom_objects={'KerasLayer':hub.KerasLayer,
'tf':tf,
'sentence_encoder_layer': sentence_encoder_layer,
},
safe_mode=False)
# Verify the loaded model
print(loaded_model_6.summary())
- 评估加载后的模型 - 失败。
# Evaluate the loaded_model
loaded_model_pred_probs = loaded_model_6.evaluate(val_sentences, val_labels)
下面是错误信息..它说hub层未定义,尽管我在同一个代码单元中已经重新初始化过...在加载模型时它也被定义过...
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
/tmp/ipykernel_2313/2915160527.py in <cell line: 0>()
1 # Evaluate the loaded_model
----> 2 loaded_model_pred_probs = loaded_model_6.evaluate(val_sentences, val_labels)
1 frames
/usr/local/lib/python3.12/dist-packages/keras/src/utils/python_utils.py in <lambda>(x)
13 model_6 = tf.keras.Sequential([
14 # sentence_encoder_layer, # take in sentences and then encode them into an embedding
---> 15 layers.Lambda(lambda x: sentence_encoder_layer(x)),
16 layers.Dense(64, activation="relu"),
17 layers.Dense(1, activation="sigmoid"),
NameError: Exception encountered when calling Lambda.call().
name 'sentence_encoder_layer' is not defined
Arguments received by Lambda.call():
• inputs=tf.Tensor(shape=(None,), dtype=string)
• mask=None
• training=False
解决方案
名称错误的原因是Keras无法序列化被Lambda层包装的外部变量。你可以通过去掉Lambda包装,将 hub.KerasLayer 直接输入到你的模型中来修复它。同时使用 tf_keras 以保持与更新的TensorFlow版本的兼容性。我已经用示例数据复现实验过代码,请告诉我这是否对你有用。
import os
os.environ["TF_USE_LEGACY_KERAS"] = "1"
import tensorflow as tf
import tf_keras as keras
from tf_keras import layers
import tensorflow_hub as hub
import numpy as np
# Dummy Data for testing
train_sentences = np.array(["I loved it", "Terrible movie", "It was okay"])
train_labels = np.array([1, 0, 0])
val_sentences = np.array(["Best thing ever", "I hated it"])
val_labels = np.array([1, 0])
# Define the TF Hub Layer
sentence_encoder_layer = hub.KerasLayer(
"https://www.kaggle.com/models/google/universal-sentence-encoder/TensorFlow2/universal-sentence-encoder/2",
input_shape=[],
dtype=tf.string,
trainable=False,
name="USE"
)
# Build Model (Pass the layer DIRECTLY to tf_keras Sequential)
model_6 = keras.Sequential([
sentence_encoder_layer,
layers.Dense(64, activation="relu"),
layers.Dense(1, activation="sigmoid"),
], name="model_6_USE")
# Compile the model
model_6.compile(
loss="binary_crossentropy",
optimizer=keras.optimizers.Adam(),
metrics=["accuracy"]
)
# Train the model
history_6 = model_6.fit(
train_sentences,
train_labels,
epochs=5,
validation_data=(val_sentences, val_labels)
)
# Predict & Save (Use the native SavedModel format)
model_6_pred_prods = model_6.predict(val_sentences)
model_6.save("model_6_saved")
# Load the model
loaded_model_6 = keras.models.load_model(
"model_6_saved",
custom_objects={'KerasLayer': hub.KerasLayer}
)
loaded_model_pred_probs = loaded_model_6.evaluate(val_sentences, val_labels)
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。