Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to save estimator in Tensorflow for later use?

I followed the tutorial "A Guide to TF Layers: Building a Convolutional Neural Network" (here is the code: https://github.com/tensorflow/tensorflow/blob/r1.1/tensorflow/examples/tutorials/layers/cnn_mnist.py).

I adapted the tutorial for my needs, which is hand detection.

As far as I understand, this tutorial creates the estimator (which is a CNN), then does the fitting, and finally, it evaluates the performance of the estimator. Now, my problem is that I want to use the estimator int another file, which is going to be my main program. How do I access the estimator from another file? Do I have to fit the estimator every time I want to use it?? (I hope not)

I was wondering if someone could help me understand how to save the estimator to use it later. (as far as I understand, I cant create a saver with tf.train.Saver, because I don't have a session running).

Here is the code from my train.py file:

def main(unused_argv):

#Load training and eval data (part missing)


# Create the estimator
hand_detector = learn.Estimator(model_fn=cnn_model_fn, model_dir="\cnn_model_fn")

# Set up logging for predictions
# Log the values in the "Softmax" tensor with label "probabilities"
tensors_to_log = {"probabilities": "softmax_tensor"}
logging_hook = tf.train.LoggingTensorHook(
    tensors=tensors_to_log, every_n_iter=50)

# Train the model
hand_detector.fit(
    x=train_data,
    y=train_labels,
    batch_size=100,
    steps=20000,
    monitors=[logging_hook])

# Configure the accuracy metric for evaluation
metrics = {
    "accuracy":
        learn.MetricSpec(
            metric_fn=tf.metrics.accuracy, prediction_key="classes"),
}

# Evaluate the model and print results
eval_results = hand_detector.evaluate(
    x=eval_data, y=eval_labels, metrics=metrics)
print(eval_results)

# Save the model for later use (part missing!)
like image 488
Federico Peccia Avatar asked Jun 09 '17 14:06

Federico Peccia


People also ask

How do I save a trained model in python TensorFlow?

Save the entire modelCall tf.keras.Model.save to save a model's architecture, weights, and training configuration in a single file/folder . This allows you to export a model so it can be used without access to the original Python code*.

What does TensorFlow use to save and restore model parameters on the disk?

The model restoring is done using the tf. saved_model. loader and restores the saved variables, signatures, and assets in the scope of a session.

How do I save the keras model in TensorFlow?

Using save_weights() method It saves the weights of the layers contained in the model. It is advised to use the save() method to save h5 models instead of save_weights() method for saving a model using tensorflow. However, h5 models can also be saved using save_weights() method.


2 Answers

Update to David Valenzuela Urrutia's answer(codes)

David Valenzuela Urrutia's answer was for Python 3.6.3, Tensorflow 1.4.0 so i thought of updating the answer(code samples) to Tensorflow 2.x because some funtionalities like tf.Session is not supported in Tensorflow version 2 so you need to replace it with tf.compat.v1.Session for it to work. Visit this link to know more about the changes added to tensorflow version 2

Training script updated code

def serving_input_receiver_fn():
   serialized_tf_example = tf.compat.v1.placeholder(dtype=tf.string, shape=[None], 
       name='input_tensors')
   receiver_tensors      = {"predictor_inputs": serialized_tf_example}
   feature_spec          = {"words": tf.io.FixedLenFeature([25],tf.int64)}
   features              = tf.io.parse_example(serialized=serialized_tf_example, 
       features=feature_spec)
   return tf.estimator.export.ServingInputReceiver(features, receiver_tensors)

def estimator_spec_for_softmax_classification(logits, labels, mode):
   predicted_classes = tf.argmax(input=logits, axis=1)
   if (mode == tf.estimator.ModeKeys.PREDICT):
      export_outputs = {'predict_output': 
   tf.estimator.export.PredictOutput({"pred_output_classes": predicted_classes, 'probabilities': tf.nn.softmax(logits)})}
   return tf.estimator.EstimatorSpec(mode=mode, predictions={'class': predicted_classes, 'prob': tf.nn.softmax(logits)}, export_outputs=export_outputs) # IMPORTANT!!!
   onehot_labels = tf.one_hot(labels, 31, 1, 0)
   loss        =tf.compat.v1.losses.softmax_cross_entropy(onehot_labels=onehot_labels, logits=logits)
   if (mode == tf.estimator.ModeKeys.TRAIN):
       optimizer = tf.compat.v1.train.AdamOptimizer(learning_rate=0.01)
       train_op  = optimizer.minimize(loss, global_step=tf.compat.v1.train.get_global_step())
       return tf.estimator.EstimatorSpec(mode, loss=loss, train_op=train_op)
   eval_metric_ops = {'accuracy': tf.compat.v1.metrics.accuracy(labels=labels, predictions=predicted_classes)}
   return tf.estimator.EstimatorSpec(mode=mode, loss=loss, eval_metric_ops=eval_metric_ops)

def model_custom(features, labels, mode):
   bow_column           = tf.feature_column.categorical_column_with_identity("words", num_buckets=1000)
   bow_embedding_column = tf.feature_column.embedding_column(bow_column, dimension=50)   
   bow                  = tf.compat.v1.feature_column.input_layer(features, feature_columns=[bow_embedding_column])
   logits               = tf.compat.v1.layers.dense(bow, 31, activation=None)
   return estimator_spec_for_softmax_classification(logits=logits, labels=labels, mode=mode)

def main():
   # ...
   # preprocess-> features_train_set and labels_train_set
   # ...
   classifier     = tf.estimator.Estimator(model_fn = model_custom)
   train_input_fn = tf.compat.v1.estimator.inputs.numpy_input_fn(x={"words": features_train_set}, y=labels_train_set, batch_size=batch_size_param, num_epochs=None, shuffle=True)
   classifier.train(input_fn=train_input_fn, steps=100)
   full_model_dir = classifier.export_savedmodel(export_dir_base="C:/models/directory_base", serving_input_receiver_fn=serving_input_receiver_fn)

Testing script updated code

def main():
   # ...
   # preprocess-> features_test_set
   # ...
   with tf.compat.v1.Session() as sess:
       tf.compat.v1.saved_model.loader.load(sess, [tf.saved_model.SERVING], full_model_dir)
       predictor   = tf.contrib.predictor.from_saved_model(full_model_dir)
       model_input = tf.train.Example(features=tf.train.Features( feature={"words": tf.train.Feature(int64_list=tf.train.Int64List(value=features_test_set)) })) 
       model_input = model_input.SerializeToString()
       output_dict = predictor({"predictor_inputs":[model_input]})
       y_predicted = output_dict["pred_output_classes"][0]
like image 87
Mbah Javis Avatar answered Oct 02 '22 05:10

Mbah Javis


Almost all real applications of machine learning seek to train a model once and then save it for future uses with new data. Most classifiers spend hours in the training stage and just few seconds in the testing stage, so is fundamental learn how to save successfully a trained model.

I'm going to explain how to export "high level" Tensorflow models (using export_savedmodel). The function export_savedmodel requires the argument serving_input_receiver_fn, that is a function without arguments, which defines the input from the model and the predictor. Therefore, you must create your own serving_input_receiver_fn, where the model input type match with the model input in the training script, and the predictor input type match with the predictor input in the testing script. On the other hand, if you create a custom model, you must define the export_outputs, defined by the function tf.estimator.export.PredictOutput, which input is a dictionary that define the name that has to match with the name of the predictor output in the testing script.

For example:

TRAINING SCRIPT

def serving_input_receiver_fn():
    serialized_tf_example = tf.placeholder(dtype=tf.string, shape=[None], name='input_tensors')
    receiver_tensors      = {"predictor_inputs": serialized_tf_example}
    feature_spec          = {"words": tf.FixedLenFeature([25],tf.int64)}
    features              = tf.parse_example(serialized_tf_example, feature_spec)
    return tf.estimator.export.ServingInputReceiver(features, receiver_tensors)
def estimator_spec_for_softmax_classification(logits, labels, mode):
    predicted_classes = tf.argmax(logits, 1)
    if (mode == tf.estimator.ModeKeys.PREDICT):
        export_outputs = {'predict_output': tf.estimator.export.PredictOutput({"pred_output_classes": predicted_classes, 'probabilities': tf.nn.softmax(logits)})}
        return tf.estimator.EstimatorSpec(mode=mode, predictions={'class': predicted_classes, 'prob': tf.nn.softmax(logits)}, export_outputs=export_outputs) # IMPORTANT!!!
    onehot_labels = tf.one_hot(labels, 31, 1, 0)
    loss          = tf.losses.softmax_cross_entropy(onehot_labels=onehot_labels, logits=logits)
    if (mode == tf.estimator.ModeKeys.TRAIN):
        optimizer = tf.train.AdamOptimizer(learning_rate=0.01)
        train_op  = optimizer.minimize(loss, global_step=tf.train.get_global_step())
        return tf.estimator.EstimatorSpec(mode, loss=loss, train_op=train_op)
    eval_metric_ops = {'accuracy': tf.metrics.accuracy(labels=labels, predictions=predicted_classes)}
    return tf.estimator.EstimatorSpec(mode=mode, loss=loss, eval_metric_ops=eval_metric_ops)
def model_custom(features, labels, mode):
    bow_column           = tf.feature_column.categorical_column_with_identity("words", num_buckets=1000)
    bow_embedding_column = tf.feature_column.embedding_column(bow_column, dimension=50)   
    bow                  = tf.feature_column.input_layer(features, feature_columns=[bow_embedding_column])
    logits               = tf.layers.dense(bow, 31, activation=None)
    return estimator_spec_for_softmax_classification(logits=logits, labels=labels, mode=mode)
def main():
    # ...
    # preprocess-> features_train_set and labels_train_set
    # ...
    classifier     = tf.estimator.Estimator(model_fn = model_custom)
    train_input_fn = tf.estimator.inputs.numpy_input_fn(x={"words": features_train_set}, y=labels_train_set, batch_size=batch_size_param, num_epochs=None, shuffle=True)
    classifier.train(input_fn=train_input_fn, steps=100)
    full_model_dir = classifier.export_savedmodel(export_dir_base="C:/models/directory_base", serving_input_receiver_fn=serving_input_receiver_fn)

TESTING SCRIPT

def main():
    # ...
    # preprocess-> features_test_set
    # ...
    with tf.Session() as sess:
        tf.saved_model.loader.load(sess, [tf.saved_model.tag_constants.SERVING], full_model_dir)
        predictor   = tf.contrib.predictor.from_saved_model(full_model_dir)
        model_input = tf.train.Example(features=tf.train.Features( feature={"words": tf.train.Feature(int64_list=tf.train.Int64List(value=features_test_set)) })) 
        model_input = model_input.SerializeToString()
        output_dict = predictor({"predictor_inputs":[model_input]})
        y_predicted = output_dict["pred_output_classes"][0]

(Code tested in Python 3.6.3, Tensorflow 1.4.0)

like image 26
David Valenzuela Urrutia Avatar answered Oct 02 '22 03:10

David Valenzuela Urrutia