'Tf' Is Not Defined on Load_Model() - Using Lambda

'Tf' Is Not Defined on Load_Model() - Using Lambda

I have a Keras model that I am trying to export and use in a different python code.

Here is my code:

from keras.models import Sequential
from keras.layers import Dense, Embedding, LSTM, GRU, Flatten, Dropout, Lambda
from keras.layers.embeddings import Embedding
import tensorflow as tf


EMBEDDING_DIM = 100

model = Sequential()
model.add(Embedding(vocab_size, 300, weights=[embedding_matrix], input_length=max_length, trainable=False))
model.add(Lambda(lambda x: tf.reduce_mean(x, axis=1)))
model.add(Dense(8, input_dim=4, activation='relu'))
model.add(Dense(3, activation='softmax'))
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
model.fit(X_train_pad, y_train, batch_size=128, epochs=25, validation_data=(X_val_pad, y_val), verbose=2)
model.save('my_model.h5') 

In another file, when I import my_model.h5 :

from keras.models import load_model
from keras.layers import Lambda
import tensorflow as tf


def learning(test_samples):
    model = load_model('my_model.h5')
    #ERROR HERE
    #rest of the code

The error is the following:

  in <lambda>
    model.add(Lambda(lambda x: tf.reduce_mean(x, axis=1)))
NameError: name 'tf' is not defined

After research, I got that the fact that I used lambda in my model is the reason for this problem, but I added these references and it didn't help:

from keras.models import load_model
from keras.layers import Lambda
import tensorflow as tf

What could be the problem?

Thank you

5 Answers

When loading the model, you need to explicitly handle custom objects or custom layers (CTRL+f the docs for Handling custom layers):

import tensorflow as tf
import keras
model = keras.models.load_model('my_model.h5', custom_objects={'tf': tf})
6

It happened to me too. You need to import tensorflow inside your lambda function. So you probably want to put the code in a separate function:

def reduce_mean(x):
    import tensorflow as tf
    return tf.reduce_mean(x, axis=1)

model = Sequential()
model.add(Embedding(vocab_size, 300, weights=[embedding_matrix], input_length=max_length, trainable=False))
model.add(Lambda(reduce_mean))
model.add(Dense(8, input_dim=4, activation='relu'))
model.add(Dense(3, activation='softmax'))
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
model.fit(X_train_pad, y_train, batch_size=128, epochs=25, validation_data=(X_val_pad, y_val), verbose=2)
model.save('my_model.h5') 
3

Besides, when you try to load the model structure from a json file, passing custom objects solves the problem.

model = model_from_json(open("model_structure.json", "r").read(), custom_objects={'tf': tf}) 

One weird solution that has worked for me is to import the module used to create the model. So say you have file you use to create a model and save it.

make_model.py

from keras.models import Sequential
from keras.layers import Dense, Embedding, LSTM, GRU, Flatten, Dropout, Lambda
from keras.layers.embeddings import Embedding
import tensorflow as tf


EMBEDDING_DIM = 100

model = Sequential()
model.add(Embedding(vocab_size, 300, weights=[embedding_matrix], input_length=max_length, trainable=False))
model.add(Lambda(lambda x: tf.reduce_mean(x, axis=1)))
...
model.fit(X_train_pad, y_train, batch_size=128, epochs=25, validation_data=(X_val_pad, y_val), verbose=2)
model.save('my_model.h5') 

If you load the model in another file load_model.py, you may be able to get around the error via import of the first module.

from keras.models import load_model
from keras.layers import Lambda
import tensorflow as tf

import make_model

def learning(test_samples):
    model = load_model('my_model.h5')

This worked for me since the error read

UserWarning: make_model is not loaded, but a Lambda layer uses it. It may cause errors.
...
NameError: name 'tf' is not defined

Happened to me as well - however problem was that the code was refactored and the Lambda layer was replaced by something else. In this case, you can always rollback to the point where it worked.

The simple workaround in case you are not able to restore the previous solution is adding: custom_objects={'tf': tf} to restore_model call

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Alexander Ross
Author

Alexander Ross

Alexander Ross has covered the video game industry for a decade, writing deep dives on game design, esports tournaments, VR developments, and gaming culture.