I saved a keras model using model.save(model_path). Now when I try to load it and apply model.summary() or model.get_weights() function I am getting following error:
AttributeError: '_UserObject' object has no attribute 'summary'
Tried printing the data type of the model and got following whereas it was a sequential keras model when I had saved it:
<class 'tensorflow.python.saved_model.load.Loader._recreate_base_user_object.<locals>._UserObject'>
I am using tensorflow 2.4.1(cpu). Below sample code can help recreating the error:
def save_model():
model = tf.keras.Sequential()
model_path = "https://tfhub.dev/google/universal-sentence-encoder/4"
hub_layer = hub.KerasLayer(model_path, input_shape=[], dtype=tf.string, trainable=False)
model.add(hub_layer)
model.save('/home/pcadmin/data/models/sentence_embedding/use-4-pre-trained/')
model = tf.keras.models.load_model(model_path)
print(model.summary())
model.get_weights()
The reproducible code above isn't complete I think. However, you need to change the code as follows to make it run. (I've tested on cpu/gpu with tf 2.4/2.7.)
model_path = "https://tfhub.dev/google/universal-sentence-encoder/4"
def save_model(model_path):
model = tf.keras.Sequential()
hub_layer = hub.KerasLayer(model_path,
input_shape=[],
dtype=tf.string, trainable=False)
model.add(hub_layer)
model.save('saved/')
save_model(model_path)
model = tf.keras.models.load_model('/content/saved')
model.summary() # OK
model.get_weights() # OK
Related
I am trying to train a graph convolutional neural network using the StellarGraph library. I would like to run this example https://stellargraph.readthedocs.io/en/stable/demos/graph-classification/gcn-supervised-graph-classification.html
but without the N-Fold Crossvalidation by providing my own training, validation and test sets. This is the code I am using (taken from this post)
generator = PaddedGraphGenerator(graphs=graphs)
train_gen = generator.flow([x for x in range(0, len(graphs_train))],
targets=graphs_train_labels,
batch_size=35)
test_gen = generator.flow([x for x in range(len(graphs_train),len(graphs_train) + len(graphs_test))],
targets=graphs_test_labels,
batch_size=35)
# Stopping criterium
es = EarlyStopping(monitor="val_loss",
min_delta=0,
patience=20,
restore_best_weights=True)
# Model definition
gc_model = GCNSupervisedGraphClassification(layer_sizes=[64, 64],
activations=["relu", "relu"],
generator=generator,
dropout=0.5)
x_inp, x_out = gc_model.in_out_tensors()
predictions = Dense(units=32, activation="relu")(x_out)
predictions = Dense(units=16, activation="relu")(predictions)
predictions = Dense(units=1, activation="sigmoid")(predictions)
# Creating Keras model and preparing it for training
model = Model(inputs=x_inp, outputs=predictions)
model.compile(optimizer=Adam(0.001), loss=binary_crossentropy, metrics=["acc"])
# GNN Training
history = model.fit(train_gen, epochs=10, validation_data=test_gen, verbose=1)
model.fit(x=graphs_train,
y=graphs_train_labels,
epochs=10,
verbose=1,
callbacks=[es])
# Calculate performance on the validation data
test_metrics = model.evaluate(valid_gen, verbose=1)
valid_acc = test_metrics[model.metrics_names.index("acc")]
print(f"Test Accuracy model = {valid_acc}")
But at the end I am getting this error
ValueError: Failed to find data adapter that can handle input: (<class 'list'> containing values of types {"<class 'stellargraph.core.graph.StellarGraph'>"}), <class 'numpy.ndarray'>
What am I missing here? Is it because of the way I have created the graphs? In my case the graphs is a list which contains the stellar graphs
Problem solved. I was calling
model.fit(x=graphs_train,
y=graphs_train_labels,
epochs=10,
verbose=1,
callbacks=[es])
after the line
history = model.fit(train_gen, epochs=10, validation_data=test_gen, verbose=1)
I am working on a sample Neural Network with KFold cross validation using TensorFlow 2.4.1. and sklearn.
Unfortunately, I am not able to save the model.
def my_model(self,):
inputs = keras.Input(shape=(48, 48, 3))
x = layers.Conv2D(filters=4, kernel_size=self.k_size, padding='same', activation="relu")(inputs)
x = layers.BatchNormalization()(x)
x = layers.MaxPool2D()(x)
x = layers.Flatten()(x)
output = layers.Dense(10, activation='softmax')(x)
model = keras.Model(inputs=inputs, outputs=output)
model.compile(optimizer='adam',
loss=[keras.losses.SparseCategoricalCrossentropy(from_logits=True)],
metrics=['accuracy'])
return model
def train_model(self):
try:
os.mkdir('model/saved_models')
except OSError:
pass
try:
os.mkdir('model/saved_graphs')
except OSError:
pass
kf = KFold(n_splits=3)
for train_index, test_index in kf.split(self.x_train):
x_train, x_test = self.x_train[train_index], self.x_train[test_index]
y_train, y_test = self.y_train[train_index], self.y_train[test_index]
model = self.my_model()
print(model.summary())
trained_model = model.fit(x_train, y_train, epochs=self.epochs, steps_per_epoch=10, verbose=2)
trained_model = trained_model.history
print('Model evaluation', model.evaluate(x_test, y_test, verbose = 2))
trained_model.save(f'model/saved_models/dummy_model_{date}')
return trained_model
I am getting a following error:
trained_model.save(f'model/saved_models/dummy_model_{date}')
AttributeError: 'dict' object has no attribute 'save'
I am not able to think of a way to take the trained model out of the for loop. And this might be the possible reason I can think of for this problem.
Can anybody suggest how we can solve this issue? Or is there any other way to build a ANN with KFold?
Thanks.
Yea your code has some typo:
trained_model = trained_model.history # This is your train stats, so your train stats is a dictionary
model.save(f'model/saved_models/dummy_model_{date}') # This is what your saving the actual model
import tensorflow as tf
length = 500
data = tf.transpose([range(length),
tf.random.uniform([length], minval=0, maxval=2, dtype=tf.int32)])
dataset = tf.data.Dataset.from_tensor_slices(data)
dataset.shuffle(length)
train_length = int(length / 5 * 4)
train_data = dataset.take(train_length)
test_data = dataset.skip(train_length)
model = tf.keras.Sequential()
model.add(tf.keras.layers.Dense(10, activation='relu'))
model.add(tf.keras.layers.Dense(1, activation='sigmoid'))
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['binary_accuracy'], run_eagerly=True)
model.fit(train_data.batch(10), validation_data=test_data.batch(10), epochs=10)
Why does it throw error
ValueError: No gradients provided for any variable: ['dense/kernel:0', 'dense/bias:0', 'dense_1/kernel:0', 'dense_1/bias:0'].
I just want to use some random data to train the model in order to learn tensorflow. How do I fix the code?
Dataset shape is incorrect in the OP's code. I will suggest to add the following check before model.fit
assert isinstance(train_data.element_spec, tuple) and len(train_data.element_spec) > 0, \
'When x is dataset, its members must be a tuple of either (inputs, targets) or (inputs, targets, sample_weights). Currently your tuple size is 0.'
Your code fails with the assert because the examples in your dataset is one element instead of two.
The minimal change is to create dataset like this
dataset = tf.data.Dataset.from_tensor_slices((features, labels))
I'm building a model using tf.keras.models.Sequential and saving it as a SavedModel object which contains a saved_model.pb file. The model is then going to be used in a C# service using ML.net.
Here is the code (pulled and adapted from docs)
(train_images, train_labels), (test_images, test_labels) = tf.keras.datasets.mnist.load_data()
train_labels = train_labels[:1000]
test_labels = test_labels[:1000]
train_images = train_images[:1000].reshape(-1, 28 * 28) / 255.0
test_images = test_images[:1000].reshape(-1, 28 * 28) / 255.0
# Define a simple sequential model
def create_model():
model = tf.keras.models.Sequential([
keras.layers.Dense(512, activation='relu', input_shape=(784,)),
keras.layers.Dropout(0.2),
keras.layers.Dense(10)
])
model.compile(optimizer='adam',
loss=tf.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=['accuracy'])
return model
# Create a basic model instance
model = create_model()
model.fit(train_images, train_labels, epochs=5)
# Save model
#model.save('/Users/fco/Desktop/saved_model/test.h5', save_format='tf')
tf.saved_model.save(model, '/Users/fco/Desktop/saved_model')
# Load model
new_model = tf.keras.models.load_model('/Users/fco/Desktop/saved_model')
print(new_model.predict(test_images).shape)
When loading the saved_model.pb file in ML.NET I get the following exception.
TensorflowException: Invalid GraphDef
When I search for this error - it references freezing weights on model, but the solutions are for TF1. TF2 seems to have a more streamlined method of saving model, but I cannot understand what is wrong.
Does anyone know what I'm missing?
I don't know answer for you problem but you can save your model in .h5 format and load it easily.
Example:
save your model using
model.save('/content/saved_model.h5')
and load it using
loaded_model= models.load_model('/content/saved_model.h5')
I get the following error for the code snippet below:
You must feed a value for placeholder tensor
'bidirectional_1/keras_learning_phase' with dtype bool
If I add the dropout layer model.add(Dropout(dropout)), it works. Anyone knows why? The back-end is Tensorflow, Keras 2.0.1
def prep_model1(embedding_layer1, embedding_layer2, dropout=0.5):
model0 = Sequential()
model0.add(embedding_layer1)
model0.add(Bidirectional(LSTM(128, return_sequences=False, dropout=dropout)))
model1 = Sequential()
model1.add(embedding_layer2)
model1.add(Bidirectional(LSTM(128, return_sequences=False, dropout=dropout)))
model = Sequential()
model.add(Merge([model0, model1], mode='concat', concat_axis=1))
#model.add(Dropout(dropout))
model.add(Dense(1, activation='sigmoid'))
return model
Try to import K and set learning phase before your model.
from keras import backend as K
K.set_learning_phase(1) #set learning phase
From this issue