Saving best model with ModelCheckPointer and tf.saved_model - tensorflow

I am training a Unet model, and want to save the model using tf.saved_model to deploy via tf serving. How can the model be saved according to the desired format with a callback?
Following is the snippet of callbacks.
checkpointer = tf.keras.callbacks.ModelCheckpoint('model_for_road_segmentation.h5', verbose=1, save_best_only=True)
log_dir = "logs/fit/" + datetime.now().strftime("%Y%m%d-%H%M%S")
tensorboard_callback = tf.keras.callbacks.TensorBoard(log_dir=log_dir)
callbacks = [
tf.keras.callbacks.EarlyStopping(patience=2, monitor="val_loss"),
tf.keras.callbacks.TensorBoard(log_dir="logs"),
checkpointer,
tensorboard_callback
]
Fitting the model
results = model.fit(train_batches, validation_data=validation_batches, \
batch_size=2, epochs=25, callbacks=callbacks
)

Related

How to provide specific training, validation and test sets in StellarGraph PaddedGraphGenerator -

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)

Can't get summary or weights from loaded keras model

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

Export Tensorflow experiment model with savedmodel

Please how can I save this model using TensorFlow SaveModel.
train_steps = int(0.5 + (1.0 * num_epochs * nusers) / batch_size)
steps_in_epoch = int(0.5 + nusers / batch_size)
print("Will train for {} steps, evaluating once every {} steps".format(train_steps, steps_in_epoch))
def experiment_fn(output_dir):
return tf.contrib.learn.Experiment(
tf.contrib.factorization.WALSMatrixFactorization(
num_rows = nusers,
num_cols = nitems,
embedding_dimension = n_embeds,
model_dir = output_dir),
train_input_fn = read_dataset(tf.estimator.ModeKeys.TRAIN, input_path,batch_size, nitems, nusers, num_epochs,n_embeds, output_dir),
eval_input_fn = read_dataset(tf.estimator.ModeKeys.EVAL, input_path, batch_size, nitems, nusers, num_epochs, n_embeds, output_dir),
train_steps = train_steps,
eval_steps = 1,
min_eval_frequency = steps_in_epoch,
export_strategies = tf.contrib.learn.utils.saved_model_export_utils.make_export_strategy(serving_input_fn = create_serving_input_fn(nitems, nusers))
)
I have tried replacing the export_strategies with export_strategies=tf.export_saved_model(output_dir, serving_input_fn = create_serving_input_fn(nitems, nusers)) and it returns the following error message
AttributeError: module 'tensorflow' has no attribute 'export_saved_model
Also tried export_strategies=tf.saved_model(output_dir, serving_input_fn = create_serving_input_fn(nitems, nusers))
TypeError: 'DeprecationWrapper' object is not callable
The SavedModel format is another way to serialize models. Models saved in this format can be restored using tf.keras.models.load_model and are compatible with TensorFlow Serving. The SavedModel guide goes into detail about how to serve/inspect the SavedModel.
The below code illustrates the steps to save and restore the model.
# Create and train a new model instance.
model = create_model()
model.fit(train_images, train_labels, epochs=5)
# Save the entire model as a SavedModel.
!mkdir -p saved_model
model.save('saved_model/my_model')
# my_model directory
ls saved_model
# Contains an assets folder, saved_model.pb, and variables folder.
ls saved_model/my_model
# Reload a fresh Keras model from the saved model:
new_model = tf.keras.models.load_model('saved_model/my_model')

TensorflowException: Invalid GraphDef (TensorFlow 2.0)

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')

Tensorflow TensorBoard not showing acc, loss, acc_val, and loss_val only only epoch_accuracy and epoch_loss

I am looking to have a TensorBoard display graphs corresponding to acc, loss, acc_val, and loss_val but they do not appear for some reason. Here is what I am seeing.
I am looking to have this:
I am following the instruction here to be able to use tensorboard in a google colab notebook
This is the code used to generate the tensorboard:
opt = tf.keras.optimizers.Adam(lr=0.001, decay=1e-6)
tensorboard = TensorBoard(log_dir="logs/{}".format(NAME),
histogram_freq=1,
write_graph=True,
write_grads=True,
batch_size=BATCH_SIZE,
write_images=True)
model.compile(
loss='sparse_categorical_crossentropy',
optimizer=opt,
metrics=['accuracy']
)
# Train model
history = model.fit(
train_x, train_y,
batch_size=BATCH_SIZE,
epochs=EPOCHS,
validation_data=(validation_x, validation_y),
callbacks=[tensorboard]
)
How do I go about solving this issue? Any ideas? Your help is very much appreciated!
That's the intended behavior. If you want to log custom scalars such as a dynamic learning rate, you need to use the TensorFlow Summary API.
Retrain the regression model and log a custom learning rate. Here's how:
Create a file writer, using tf.summary.create_file_writer().
Define a custom learning rate function. This will be passed to the Keras LearningRateScheduler callback.
Inside the learning rate function, use tf.summary.scalar() to log the custom learning rate.
Pass the LearningRateScheduler callback to Model.fit().
In general, to log a custom scalar, you need to use tf.summary.scalar() with a file writer. The file writer is responsible for writing data for this run to the specified directory and is implicitly used when you use the tf.summary.scalar().
logdir = "logs/scalars/" + datetime.now().strftime("%Y%m%d-%H%M%S")
file_writer = tf.summary.create_file_writer(logdir + "/metrics")
file_writer.set_as_default()
def lr_schedule(epoch):
"""
Returns a custom learning rate that decreases as epochs progress.
"""
learning_rate = 0.2
if epoch > 10:
learning_rate = 0.02
if epoch > 20:
learning_rate = 0.01
if epoch > 50:
learning_rate = 0.005
tf.summary.scalar('learning rate', data=learning_rate, step=epoch)
return learning_rate
lr_callback = keras.callbacks.LearningRateScheduler(lr_schedule)
tensorboard_callback = keras.callbacks.TensorBoard(log_dir=logdir)
model = keras.models.Sequential([
keras.layers.Dense(16, input_dim=1),
keras.layers.Dense(1),
])
model.compile(
loss='mse', # keras.losses.mean_squared_error
optimizer=keras.optimizers.SGD(),
)
training_history = model.fit(
x_train, # input
y_train, # output
batch_size=train_size,
verbose=0, # Suppress chatty output; use Tensorboard instead
epochs=100,
validation_data=(x_test, y_test),
callbacks=[tensorboard_callback, lr_callback],
)