How to save a TF model for use in another program?

Issue

I am currently building an NLP model but would like to save the trained model somewhere where the bulk of my actual program can just run the predict command without having the rerun the whole model. I have tried the model.save() and model.load() functions but I cant seem to get it to load in my other project.

I would like to run it in another python project and push the results to a database (SQL)

train_dir = "data"
batch_size = 32
seed = 42

raw_train_ds = tf.keras.utils.text_dataset_from_directory(
    'data',
    batch_size=batch_size,
    validation_split=0.2,
    subset="training",
    seed=seed)

raw_val_ds = tf.keras.utils.text_dataset_from_directory(
    'data',
    batch_size=batch_size,
    validation_split=0.2,
    subset='validation',
    seed=seed)


def custom_standardization(input_data):
    lowercase = tf.strings.lower(input_data)
    stripped_html = tf.strings.regex_replace(lowercase, '<br />', ' ')
    return tf.strings.regex_replace(stripped_html,
                                    '[%s]' % re.escape(string.punctuation),
                                    '')


max_features = 10000
sequence_length = 100

vectorize_layer = layers.TextVectorization(
    standardize=custom_standardization,
    max_tokens=max_features,
    output_mode='int',
    output_sequence_length=sequence_length)

# Make a text-only dataset (without labels), then call adapt
train_text = raw_train_ds.map(lambda x, y: x)
vectorize_layer.adapt(train_text)


def vectorize_text(text, label):
    text = tf.expand_dims(text, -1)
    return vectorize_layer(text), label


text_batch, label_batch = next(iter(raw_train_ds))
first_review, first_label = text_batch[0], label_batch[0]
print("Review", first_review)
print("Label", raw_train_ds.class_names[first_label])
print("Vectorized review", vectorize_text(first_review, first_label))

train_ds = raw_train_ds.map(vectorize_text)
val_ds = raw_val_ds.map(vectorize_text)
#test_ds = raw_test_ds.map(vectorize_text)

AUTOTUNE = tf.data.AUTOTUNE

train_ds = train_ds.cache().prefetch(buffer_size=AUTOTUNE)
val_ds = val_ds.cache().prefetch(buffer_size=AUTOTUNE)
#test_ds = test_ds.cache().prefetch(buffer_size=AUTOTUNE)

embedding_dim = 16

model = tf.keras.Sequential([
  layers.Embedding(max_features + 1, embedding_dim),
  layers.Dropout(0.2),
  layers.GlobalAveragePooling1D(),
  layers.Dropout(0.2),
  layers.Dense(1)])

model.summary()

model.compile(loss=losses.BinaryCrossentropy(from_logits=True),
              optimizer='adam',
              metrics=tf.metrics.BinaryAccuracy(threshold=0.0))


epochs = 30
history = model.fit(
    train_ds,
    validation_data=val_ds,
    epochs=epochs)


export_model = tf.keras.Sequential([
  vectorize_layer,
  model,
  layers.Activation('sigmoid')
])

export_model.compile(
    loss=losses.BinaryCrossentropy(from_logits=False), optimizer="adam", metrics=['accuracy']
)

model.save("Crypto NLP", overwrite=True)


examples = ["4 supply. 3.6k holders already. something is brewing at @DecimusDynamic but not much is left. better snap one of these bad boys up if i were you...."]

verdict = export_model.predict(examples)
print(verdict)
for x in range(0, len(examples)):
    print(f"'{examples[x][0]}' has a verdict of {verdict[x][0]} which is classified as {'Negative' if verdict[x][0] <= .5 else 'Positive'}")

Solution

You can add a checkpoint callback (https://www.tensorflow.org/api_docs/python/tf/keras/callbacks/ModelCheckpoint) and save the model to an h5 file. Then, when you need to use that model, you can keras load_weights to load in the data.

Example (not tested):

import tensorflow as tf

"""Training phase"""
#Example Model
model = tf.keras.Sequential([
    tf.keras.layers.Input((64,64,3)),
    tf.keras.layers.Reshape((64*64*3,)),
    tf.keras.layers.Dense((64*64*3),activation="relu"),
    tf.keras.layers.Dense((8*8*3),activation="relu"),
    tf.keras.layers.Reshape((64*64*3,)),
])

#Prepare training data here
train_gen_tensor = ...
val_gen_tensor = ...

model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate = 0.001),loss="sparse_categorical_crossentropy")
callbacks = [
    tf.keras.callbacks.ModelCheckpoint("some_folder/my_model_weights.h5")
]
model.fit(train_gen_tensor,epochs=50,validation_data=val_gen_tensor,callbacks=callbacks)
# Here, your model weights are saved in some_folder/my_model_weights.h5, but not model structure

"""Usage Phase -- Inside a different .py file"""
# You need to recompile the mode before loading in the weights
model = tf.keras.Sequential([
    tf.keras.layers.Input((64,64,3)),
    tf.keras.layers.Reshape((64*64*3,)),
    tf.keras.layers.Dense((64*64*3),activation="relu"),
    tf.keras.layers.Dense((8*8*3),activation="relu"),
    tf.keras.layers.Reshape((64*64*3,)),
])
model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate = 0.001),loss="sparse_categorical_crossentropy")
model.load_weights("some_folder/my_model_weights.h5")

#Some input data
inference_gen_input_tensor = ...

# Apply the model
inference_gen_output_tensor = model(inference_gen_input_tensor)

Answered By – Michael Sohnen

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published