How to save estimator in Tensorflow for later use?

后端 未结 3 1666
没有蜡笔的小新
没有蜡笔的小新 2021-02-05 18:23

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/exampl

相关标签:
3条回答
  • 2021-02-05 18:49

    Estimator has an export_savedmodel member function for that purpose. You will find the docs here.

    0 讨论(0)
  • 2021-02-05 19:00

    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]
    
    0 讨论(0)
  • 2021-02-05 19:02

    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)

    0 讨论(0)
提交回复
热议问题