tf中checkpoint文件转saved_model,并通过tfserving请求

# ckpt转saved_model并自定义输入输出tensor名字
input_node = tf.placeholder(tf.float32, shape=(None, None, None, 3),name="input") logits_tf = network.deeplab_v3(input_node, args, is_training=False, reuse=False) print(logits_tf.shape) saver = tf.train.Saver() with tf.Session() as sess: # Create a saver. sess.run(tf.local_variables_initializer()) sess.run(tf.global_variables_initializer()) # Restore variables from disk. saver.restore(sess, checkpoint_file) builder = tf.saved_model.builder.SavedModelBuilder(export_dir) signature = predict_signature_def(inputs={'input': input_node}, outputs={'output': logits_tf}) builder.add_meta_graph_and_variables(sess=sess, tags=[tag_constants.SERVING], signature_def_map={'predict': signature}) builder.save()

通过saved_model_cli显示的结果来看:

signature_def['predict']:
  The given SavedModel SignatureDef contains the following input(s):
    inputs['input'] tensor_info:
        dtype: DT_FLOAT
        shape: (-1, -1, -1, 3)
        name: input:0
  The given SavedModel SignatureDef contains the following output(s):
    outputs['output'] tensor_info:
        dtype: DT_FLOAT
        shape: (-1, -1, -1, 2)
        name: DeepLab_v3/ResizeBilinear:0
  Method name is: tensorflow/serving/predict

有一个坑,自定义输入输出tensor名字,是tf_serving使用时才有效的,而如果直接加载图的话,还是得取tensor原本的名字

from matplotlib import pyplot as plt
%matplotlib inline

import numpy as np
import cv2
import albumentations as A
with tf.Session(graph=tf.Graph()) as sess:
    tf.saved_model.loader.load(sess, ["serve"], export_dir)
    graph = tf.get_default_graph()

    img = cv2.imread("/home/ground_train/test/20112201814-1_00000036_img.png")
    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    img = A.PadIfNeeded(p=1,min_height=1088, min_width=1920)(image=img)['image']
    img = img.astype(np.float32)
    img_x = np.expand_dims(img, 0)
    x = sess.graph.get_tensor_by_name('input:0')
    y = sess.graph.get_tensor_by_name('DeepLab_v3/ResizeBilinear:0')
    logits_tf = sess.run(y,feed_dict={x: img_x})
    print(logits_tf.shape)
    predictions_tf = np.argmax(logits_tf, axis=3)
    pred_image = predictions_tf[0]
    print(pred_image.shape)
    f, (ax1, ax2) = plt.subplots(1, 2, figsize=(8, 8))

    ax1.imshow(img.astype(np.uint8))
    ax2.imshow(pred_image)
    plt.show()

直接tf-serving请求:

启动:

docker run -p port:8500 -e MODEL_NAME=ground_segmentation --name tfserving-ground-segmentation -e NVIDIA_VISIBLE_DEVICES=1 -v /model_path_in_machine:/models/ground_segmentation docker_images:tag --per_process_gpu_memory_fraction=0.2

需要注意的是:/model_path_in_machine下应该是版本号,例如0,0下一级目录是saved_model

请求代码:

import grpc
import numpy as np
import tensorflow as tf
from PIL import Image
from tensorflow_serving.apis import predict_pb2
from tensorflow_serving.apis import prediction_service_pb2_grpc
import cv2
import matplotlib.pyplot as plt
 
def request_tfserving(inputs, server_url, model_name, signature_name, input_names, output_names):
    # 建立连接
    channel = grpc.insecure_channel(server_url)
    stub = prediction_service_pb2_grpc.PredictionServiceStub(channel)
    # 开始设置请求数据
    request = predict_pb2.PredictRequest()
    request.model_spec.name = model_name  # 模型名称
    request.model_spec.signature_name = signature_name  # 签名名称(默认 serving_default)
    # 设置输入数据
    for input, input_name in zip(inputs, input_names):
        request.inputs[input_name].CopyFrom(tf.make_tensor_proto(input, shape=list(input.shape)))
        
    response = stub.Predict(request, 5.0)  # 其中第2个参数为请求的 timeout 时长
    res_from_server_np = []
    for output_name in output_names:
        res_from_server_np.append(tf.make_ndarray(response.outputs[output_name]))
    print(np.argmax(res_from_server_np[0][0,:],axis=2).shape)
    f, (ax1, ax2) = plt.subplots(1, 2, figsize=(8, 8))

    ax1.imshow(input[0,:].astype(np.uint8))
    ax2.imshow(np.argmax(res_from_server_np[0][0,:],axis=2))
    plt.show()
 
if __name__ == "__main__":
    img_path = '/home/ground_train/test/20112201814-1_00000036_img.png'
    img = Image.open(img_path)
    img = img.resize((960, 544), Image.NEAREST).convert('RGB')
    img = image.img_to_array(img)
    img = np.expand_dims(img, axis=0).astype('float32')
    print(img.shape)
    request_tfserving(inputs=[img],#这里一定得是个list
                      server_url='ip:port',
                      model_name='ground_segmentation',
                      signature_name='predict',#与saved_model_cli结果中第一行的key一致,默认是serving_default
                      input_names=['input'],
                      output_names=['output'])

 用restful API请求:

参照https://github.com/tensorflow/serving/blob/master/tensorflow_serving/g3doc/api_rest.md#example

docker run --rm -p port:8501 --mount type=bind,source=/home/work/maleiyuan/deeplab_v3,target=/home/work/maleiyuan/deeplab_v3 -e MODEL_BASE_PATH=/home/work/maleiyuan/deeplab_v3 -e MODEL_NAME=ground_segmentation -t docker_images:tag

其中,MODEL_BASE_PATH+MODEL_NAME是放模型文件的路径,其中MODEL_NAME是ground_segmentation(放模型文件的文件夹名字)

 curl http://localhost:port/v1/models/ground_segmentation,返回结果:

{
 "model_version_status": [
  {
   "version": "0",
   "state": "AVAILABLE",
   "status": {
    "error_code": "OK",
    "error_message": ""
   }
  }
 ]
}

 

posted @ 2021-02-18 18:52  小小马进阶笔记  阅读(507)  评论(0)    收藏  举报