【问题标题】:How to save estimator in Tensorflow for later use?如何在 Tensorflow 中保存估算器以备后用?
【发布时间】:2020-11-10 19:33:35
【问题描述】:

我按照教程“TF 层指南:构建卷积神经网络”(这里是代码:https://github.com/tensorflow/tensorflow/blob/r1.1/tensorflow/examples/tutorials/layers/cnn_mnist.py)。

我根据自己的需要调整了本教程,即手部检测。

据我了解,本教程创建估计器(这是一个 CNN),然后进行拟合,最后评估估计器的性能。现在,我的问题是我想在另一个文件中使用估计器,这将是我的主程序。如何从另一个文件访问估算器?每次我想使用估算器时都必须拟合它吗? (希望不会)

我想知道是否有人可以帮助我了解如何保存估算器以供以后使用。 (据我了解,我无法使用tf.train.Saver 创建保护程序,因为我没有正在运行的会话)。

这是我的train.py 文件中的代码:

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

【问题讨论】:

    标签: python tensorflow


    【解决方案1】:

    几乎所有机器学习的实际应用都试图训练一次模型,然后将其保存起来以备将来使用新数据。大多数分类器在训练阶段花费数小时,而在测试阶段只花费几秒钟,因此基本了解如何成功保存经过训练的模型。

    我将解释如何导出“高级”Tensorflow 模型(使用 export_savedmodel)。 export_savedmodel 函数需要参数 serving_input_receiver_fn,这是一个没有参数的函数,它定义了模型和预测器的输入。因此,您必须创建自己的 serving_input_receiver_fn,其中模型输入类型与训练脚本中的模型输入匹配,预测器输入类型与测试脚本中的预测器输入匹配。 另一方面,如果您创建自定义模型,则必须定义 export_outputs,由函数 tf.estimator.export.PredictOutput 定义,该输入是定义必须匹配的名称的字典带有测试脚本中预测器输出的名称。

    例如:

    培训脚本

    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)
    

    测试脚本

    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]
    

    (在 Python 3.6.3、Tensorflow 1.4.0 中测试的代码)

    【讨论】:

    • 没有tf.contrib.predictor怎么办?使用输入元图?
    • 您确实需要在代码中添加一些间距... ;)
    【解决方案2】:

    Estimator 有一个用于此目的的 export_savedmodel 成员函数。您将找到文档here

    【讨论】:

      【解决方案3】:

      更新到David Valenzuela Urrutia's 答案(代码)

      David Valenzuela Urrutia 的答案是针对 Python 3.6.3、Tensorflow 1.4.0,所以我想将答案(代码示例)更新到 Tensorflow 2.x,因为像 tf.Session 这样的一些功能不是在 Tensorflow 版本 2 中受支持,因此您需要将其替换为 tf.compat.v1.Session 才能正常工作。访问此link 以了解有关添加到 tensorflow 版本 2 中的更改的更多信息

      训练脚本更新代码

      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)
      

      测试脚本更新代码

      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]
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-03-03
        • 2019-10-05
        • 1970-01-01
        • 1970-01-01
        • 2018-03-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多