保存 TF 服务的模型

为了服务模型,需要先保存它们。在本节中,我们将从官方 TensorFlow 文档中演示 MNIST 示例的略微修改版本,可从以下链接获得: https://www.tensorflow.org/serving/serving_basic

TensorFlow 团队建议使用 SavedModel 来保存和恢复在 TensorFlow 中构建和训练的模型。根据 TensorFlow 文档:

SavedModel 是一种语言中立的,可恢复的,密集的序列化格式。SavedModel 支持更高级别的系统和工具来生成,使用和转换 TensorFlow 模型。您可以按照 Jupyter 笔记本中的代码ch-11b_Saving_TF_Models_with_SavedModel_for_TF_Serving。我们按照以下方式继续保存模型:

  1. 定义模型变量:
model_name = 'mnist'
model_version = '1'
model_dir = os.path.join(models_root,model_name,model_version)
  1. 像我们在第 4 章中所做的那样获取 MNIST 数据 - MLP 模型:
from tensorflow.examples.tutorials.mnist import input_data
dataset_home = os.path.join('.','mnist')
mnist = input_data.read_data_sets(dataset_home, one_hot=True)
x_train = mnist.train.images
x_test = mnist.test.images
y_train = mnist.train.labels
y_test = mnist.test.labels
pixel_size = 28 
num_outputs = 10 # 0-9 digits
num_inputs = 784 # total pixels
  1. 定义将构建并返回模型的 MLP 函数:
def mlp(x, num_inputs, num_outputs,num_layers,num_neurons):
     w=[]
     b=[]
     for i in range(num_layers):
         w.append(tf.Variable(tf.random_normal( 
             [num_inputs if i==0 else num_neurons[i-1], 
             num_neurons[i]]),name="w_{0:04d}".format(i) 
              ) 
             ) 
         b.append(tf.Variable(tf.random_normal( 
               [num_neurons[i]]), 
               name="b_{0:04d}".format(i) 
              ) 
             ) 
     w.append(tf.Variable(tf.random_normal(
         [num_neurons[num_layers-1] if num_layers > 0 \
         else num_inputs, num_outputs]),name="w_out"))
     b.append(tf.Variable(tf.random_normal([num_outputs]),
            name="b_out"))

     # x is input layer
     layer = x
     # add hidden layers
     for i in range(num_layers):
         layer = tf.nn.relu(tf.matmul(layer, w[i]) + b[i])
     # add output layer
     layer = tf.matmul(layer, w[num_layers]) + b[num_layers]
     model = layer
     probs = tf.nn.softmax(model)

     return model,probs

上述mlp()函数返回模型和概率。概率是应用于模型的 softmax 激活。

  1. 为图像输入和目标输出定义x_py_p占位符:
# input images
serialized_tf_example = tf.placeholder(tf.string, 
        name='tf_example')
feature_configs = {'x': tf.FixedLenFeature(shape=[784], 
        dtype=tf.float32),}
tf_example = tf.parse_example(serialized_tf_example, 
        feature_configs)
# use tf.identity() to assign name
x_p = tf.identity(tf_example['x'], name='x_p') 
# target output
y_p = tf.placeholder(dtype=tf.float32, name="y_p", 
        shape=[None, num_outputs])
  1. 创建模型,以及损失,优化器,准确性和训练函数:
num_layers = 2
num_neurons = []
for i in range(num_layers):
   num_neurons.append(256)

learning_rate = 0.01
n_epochs = 50
batch_size = 100
n_batches = mnist.train.num_examples//batch_size

model,probs = mlp(x=x_p, 
    num_inputs=num_inputs, 
    num_outputs=num_outputs, 
    num_layers=num_layers, 
    num_neurons=num_neurons)

loss_op = tf.nn.softmax_cross_entropy_with_logits
loss = tf.reduce_mean(loss_op(logits=model, labels=y_p))
optimizer = tf.train.GradientDescentOptimizer(learning_rate)
train_op = optimizer.minimize(loss)

pred_check = tf.equal(tf.argmax(probs,1), tf.argmax(y_p,1))
accuracy_op = tf.reduce_mean(tf.cast(pred_check, tf.float32))

values, indices = tf.nn.top_k(probs, 10)
table = tf.contrib.lookup.index_to_string_table_from_tensor(
        tf.constant([str(i) for i in range(10)]))
prediction_classes = table.lookup(tf.to_int64(indices))
  1. 在 TensorFlow 会话中,像以前一样训练模型,但使用构建器对象来保存模型:
from tf.saved_model.signature_constants import \
        CLASSIFY_INPUTS
from tf.saved_model.signature_constants import \
        CLASSIFY_OUTPUT_CLASSES
from tf.saved_model.signature_constants import \
        CLASSIFY_OUTPUT_SCORES
from tf.saved_model.signature_constants import \
        CLASSIFY_METHOD_NAME
from tf.saved_model.signature_constants import \
        PREDICT_METHOD_NAME
from tf.saved_model.signature_constants import \
        DEFAULT_SERVING_SIGNATURE_DEF_KEY
with tf.Session() as tfs:
    tfs.run(tf.global_variables_initializer())
    for epoch in range(n_epochs):
        epoch_loss = 0.0
  for batch in range(n_batches):
            x_batch, y_batch = mnist.train.next_batch(batch_size)
            feed_dict = {x_p: x_batch, y_p: y_batch}
            _,batch_loss = tfs.run([train_op,loss], 
                            feed_dict=feed_dict)
            epoch_loss += batch_loss
        average_loss = epoch_loss / n_batches
        print("epoch: {0:04d}   loss = {1:0.6f}" .format(epoch,average_loss))
    feed_dict={x_p: x_test, y_p: y_test}
    accuracy_score = tfs.run(accuracy_op, feed_dict=feed_dict)
    print("accuracy={0:.8f}".format(accuracy_score))

    # save the model

 # definitions for saving the models  builder = tf.saved_model.builder.SavedModelBuilder(model_dir)
    # build signature_def_map
    bti_op = tf.saved_model.utils.build_tensor_info
    bsd_op = tf.saved_model.utils.build_signature_def

  classification_inputs = bti_op(serialized_tf_example)
    classification_outputs_classes = bti_op(prediction_classes)
    classification_outputs_scores = bti_op(values)
    classification_signature = (bsd_op(
        inputs={CLASSIFY_INPUTS: classification_inputs},
        outputs={CLASSIFY_OUTPUT_CLASSES:
                    classification_outputs_classes,
                 CLASSIFY_OUTPUT_SCORES:
                    classification_outputs_scores
                },
        method_name=CLASSIFY_METHOD_NAME))

    tensor_info_x = bti_op(x_p)
    tensor_info_y = bti_op(probs)

    prediction_signature = (bsd_op(
            inputs={'inputs': tensor_info_x},
            outputs={'outputs': tensor_info_y},
            method_name=PREDICT_METHOD_NAME))

    legacy_init_op = tf.group(tf.tables_initializer(), 
        name='legacy_init_op')
    builder.add_meta_graph_and_variables(
        tfs, [tf.saved_model.tag_constants.SERVING],
        signature_def_map={
            'predict_images':prediction_signature,
            DEFAULT_SERVING_SIGNATURE_DEF_KEY:
                classification_signature,
        },
        legacy_init_op=legacy_init_op)

    builder.save()

一旦看到以下输出,就会保存模型:

accuracy=0.92979997
INFO:tensorflow:No assets to save.
INFO:tensorflow:No assets to write.
INFO:tensorflow:SavedModel written to: b'/home/armando/models/mnist/1/saved_model.pb'

接下来,我们运行 ModelServer 并提供刚刚保存的模型。

results matching ""

    No results matching ""