tensorflow-server +keras + docker模型导出和部署方法

部署过程主要遇到的坑是签名的问题这里做下记录参考文档地址
https://www.tensorflow.org/tfx/serving/serving_basic
https://www.tensorflow.org/api_docs/python/tf/saved_model/signature_constants
这里的部署方式以windows docker为例子,linux系统也是一样的操作,路径相应改变下就行
github demo地址https://github.com/Caigengliang/exportKerasForTensorflowServer

拉取镜像

安装完docker后,可以用一下命令直接拉取最新的tensorflow server镜像

docker pull tensorflow/serving

导出keras模型保存为tensorflow-server指定格式

先创建一个方法,改方法用于创建指定目录的文件夹,存在则不动作,不存在则创建。如果改目录下存在文件应该删除它,以方便模型更新。

def mkdir(path):
    import os
    import shutil
    path=path.strip()
    path=path.rstrip("\\")
    isExists=os.path.exists(path)
    if not isExists:
        os.makedirs(path) 
        return True
    else:
        filelist=os.listdir(path) 
        for f in filelist:
            filepath = os.path.join( path, f )   #将文件名映射成绝对路劲
            if os.path.isfile(filepath):            #判断该文件是否为文件或者文件夹
                os.remove(filepath)                 #若为文件,则直接删除
                print(str(filepath)+" removed!")
            elif os.path.isdir(filepath):
                shutil.rmtree(filepath,True)        #若为文件夹,则删除该文件夹及文件夹内所有文件
                print("dir "+str(filepath)+" removed!")

模型导出
在prediction_signature定义了一下参数

  • inputs={'images': tensor_info_x} 指定输入张量信息。

  • outputs={'scores': tensor_info_y} 指定分数张量信息。

  • method_name是用于推理的方法。对于预测请求,应将其设置为tensorflow/serving/predict。有关其他方法名称,请参阅signature_constants.py 和相关的 TensorFlow 1.0 API文档

其中method_name映射为api的路径方法名

import tensorflow as tf
import os
import tensorflow.keras.backend as K
from tensorflow.keras.losses import categorical_crossentropy
from tensorflow.keras.optimizers import Adadelta


def export_model(model,
                 export_model_dir,
                 model_version
                 ):
    """
    :param export_model_dir: type string, save dir for exported model    url
    :param model_version: type int best
    :return:no return
    """
    with tf.get_default_graph().as_default():
        # prediction_signature
        tensor_info_input = tf.saved_model.utils.build_tensor_info(model.input)
        tensor_info_output = tf.saved_model.utils.build_tensor_info(model.output)
        print(model.output.shape, '**', tensor_info_output)
        prediction_signature = (
            tf.saved_model.signature_def_utils.build_signature_def(
                inputs={'images': tensor_info_input}, # Tensorflow.TensorInfo
                outputs={'result': tensor_info_output},
                #method_name=tf.saved_model.signature_constants.PREDICT_METHOD_NAME)
                 method_name= "tensorflow/serving/predict")
               
        )
        print('step1 => prediction_signature created successfully')
        # set-up a builder
        mkdir(export_model_dir)
        export_path_base = export_model_dir
        export_path = os.path.join(
            tf.compat.as_bytes(export_path_base),
            tf.compat.as_bytes(str(model_version)))
        builder = tf.saved_model.builder.SavedModelBuilder(export_path)
        builder.add_meta_graph_and_variables(
            # tags:SERVING,TRAINING,EVAL,GPU,TPU
            sess=K.get_session(),
            tags=[tf.saved_model.tag_constants.SERVING],
            signature_def_map={
                'predict':
                    prediction_signature,
                   tf.saved_model.signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY:
              prediction_signature,

            },
            )
        print('step2 => Export path(%s) ready to export trained model' % export_path, '\n starting to export model...')
        #builder.save(as_text=True)
        builder.save()
        print('Done exporting!')

调用导出方法导出,这里假设已经把模型保存为.h5文件了

model = tf.keras.models.load_model('./12308nenghao.h5')
  export_model(
        model,
        'C:/tmp/tfserving/pow',
        1
    )
image.png

可以看到对应目录下生成了如下文件:
其中1这个父目录是版本好,tensorflow-server会识别这个版本号


image.png

在docker中运行

指定好路径


docker run -p 8501:8501 --mount type=bind,source=C:/tmp/tfserving/pow,target=/models/pow -e MODEL_NAME=pow -t tensorflow/serving '&'

server生成两个接口一个restful一个gprc接口


运行结果

验证
直接用postman测试restful

image.png

遇到问题
在测试的时候要特别注意输入的张量的形状,在导出模型的时候查看下。
{ "error": "Serving signature name: "serving_default" not found in signature def" }
该问题是由签名没有设置默认serving_default
检查下signature_def_map是否缺少设置,在里面添加 tf.saved_model.signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY:
prediction_signature,
其中prediction_signature是tf.saved_model.signature_def_utils.build_signature_def的定义。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值