tensorflow-server +keras + docker模型導(dǎo)出和部署方法

部署過程主要遇到的坑是簽名的問題這里做下記錄參考文檔地址
https://www.tensorflow.org/tfx/serving/serving_basic
https://www.tensorflow.org/api_docs/python/tf/saved_model/signature_constants
這里的部署方式以windows docker為例子,linux系統(tǒng)也是一樣的操作,路徑相應(yīng)改變下就行
github demo地址https://github.com/Caigengliang/exportKerasForTensorflowServer

拉取鏡像

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

docker pull tensorflow/serving

導(dǎo)出keras模型保存為tensorflow-server指定格式

先創(chuàng)建一個方法,改方法用于創(chuàng)建指定目錄的文件夾,存在則不動作,不存在則創(chuàng)建。如果改目錄下存在文件應(yīng)該刪除它,以方便模型更新。

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)        #若為文件夾,則刪除該文件夾及文件夾內(nèi)所有文件
                print("dir "+str(filepath)+" removed!")

模型導(dǎo)出
在prediction_signature定義了一下參數(shù)

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

  • outputs={'scores': tensor_info_y} 指定分?jǐn)?shù)張量信息。

  • method_name是用于推理的方法。對于預(yù)測請求,應(yīng)將其設(shè)置為tensorflow/serving/predict。有關(guān)其他方法名稱,請參閱signature_constants.py 和相關(guān)的 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!')

調(diào)用導(dǎo)出方法導(dǎo)出,這里假設(shè)已經(jīng)把模型保存為.h5文件了

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

可以看到對應(yīng)目錄下生成了如下文件:
其中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接口


運行結(jié)果

驗證
直接用postman測試restful

image.png

遇到問題
在測試的時候要特別注意輸入的張量的形狀,在導(dǎo)出模型的時候查看下。
{ "error": "Serving signature name: "serving_default" not found in signature def" }
該問題是由簽名沒有設(shè)置默認(rèn)serving_default
檢查下signature_def_map是否缺少設(shè)置,在里面添加 tf.saved_model.signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY:
prediction_signature,
其中prediction_signature是tf.saved_model.signature_def_utils.build_signature_def的定義。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容