【问题标题】:Deploying Keras Models via Google Cloud ML通过 Google Cloud ML 部署 Keras 模型
【发布时间】:2018-08-06 12:09:35
【问题描述】:

我希望使用 Google Cloud ML 来托管我的 Keras 模型,以便我可以调用 API 并进行一些预测。我在 Keras 方面遇到了一些问题。

到目前为止,我已经能够使用 TensorFlow 构建模型并将其部署在 CloudML 上。为了使它工作,我必须对我的基本 TF 代码进行一些更改。此处记录了更改:https://cloud.google.com/ml/docs/how-tos/preparing-models#code_changes

我还能够使用 Keras 训练一个类似的模型。我什至可以将模型保存为与 TF 相同的 export 和 export.meta 格式。

from keras import backend as K

saver = tf.train.Saver()
session = K.get_session()
saver.save(session, 'export')

我缺少的部分是如何将输入和输出的占位符添加到我在 Keras 上构建的图表中?

【问题讨论】:

    标签: tensorflow google-cloud-platform keras google-cloud-ml


    【解决方案1】:

    在 Google Cloud ML Engine 上训练您的模型后(请查看 this awesome tutorial),我将图表的输入和输出命名为

    signature = predict_signature_def(inputs={'NAME_YOUR_INPUT': new_Model.input},
                                      outputs={'NAME_YOUR_OUTPUT': new_Model.output})
    

    您可以在下面查看已训练的 keras 模型“model.h5”的完整导出示例。

    import keras.backend as K
    import tensorflow as tf
    from keras.models import load_model, Sequential
    from tensorflow.python.saved_model import builder as saved_model_builder
    from tensorflow.python.saved_model import tag_constants, signature_constants
    from tensorflow.python.saved_model.signature_def_utils_impl import predict_signature_def
    
    # reset session
    K.clear_session()
    sess = tf.Session()
    K.set_session(sess)
    
    # disable loading of learning nodes
    K.set_learning_phase(0)
    
    # load model
    model = load_model('model.h5')
    config = model.get_config()
    weights = model.get_weights()
    new_Model = Sequential.from_config(config)
    new_Model.set_weights(weights)
    
    # export saved model
    export_path = 'YOUR_EXPORT_PATH' + '/export'
    builder = saved_model_builder.SavedModelBuilder(export_path)
    
    signature = predict_signature_def(inputs={'NAME_YOUR_INPUT': new_Model.input},
                                      outputs={'NAME_YOUR_OUTPUT': new_Model.output})
    
    with K.get_session() as sess:
        builder.add_meta_graph_and_variables(sess=sess,
                                             tags=[tag_constants.SERVING],
                                             signature_def_map={
                                                 signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY: signature})
        builder.save()
    

    你也可以看到我的full implementation

    编辑:如果我的回答解决了您的问题,请在此处给我留言 :)

    【讨论】:

    • 完整的实现链接已损坏。我认为this 可能是它现在应该在的地方,但我什至找不到任何 Python 代码。
    【解决方案2】:

    我发现为了在谷歌云上使用 keras,必须使用 setup.py 脚本安装它,并将其放在运行 gcloud 命令的同一位置文件夹中:

    ├── setup.py
    └── trainer
        ├── __init__.py
        ├── cloudml-gpu.yaml
        ├── example5-keras.py
    

    并在 setup.py 中放置以下内容:

    from setuptools import setup, find_packages
    
    setup(name='example5',
      version='0.1',
      packages=find_packages(),
      description='example to run keras on gcloud ml-engine',
      author='Fuyang Liu',
      author_email='fuyang.liu@example.com',
      license='MIT',
      install_requires=[
          'keras',
          'h5py'
      ],
      zip_safe=False)
    

    然后您可以开始在 gcloud 上运行您的作业,例如:

    export BUCKET_NAME=tf-learn-simple-sentiment
    export JOB_NAME="example_5_train_$(date +%Y%m%d_%H%M%S)"
    export JOB_DIR=gs://$BUCKET_NAME/$JOB_NAME
    export REGION=europe-west1
    
    gcloud ml-engine jobs submit training $JOB_NAME \
      --job-dir gs://$BUCKET_NAME/$JOB_NAME \
      --runtime-version 1.0 \
      --module-name trainer.example5-keras \
      --package-path ./trainer \
      --region $REGION \
      --config=trainer/cloudml-gpu.yaml \
      -- \
      --train-file gs://tf-learn-simple-sentiment/sentiment_set.pickle
    

    要使用 GPU,请在您的模块中添加一个文件,例如 cloudml-gpu.yaml,其内容如下:

    trainingInput:
      scaleTier: CUSTOM
      # standard_gpu provides 1 GPU. Change to complex_model_m_gpu for 4 
    GPUs
      masterType: standard_gpu
      runtimeVersion: "1.0"
    

    【讨论】:

    • 这些是关于跑步训练的很好的指导,但最初的问题是关于发球的。您介意发布一个关于如何在 CloudML 上训练 Keras 模型并使用这些有价值的信息进行自我回答的新问题吗?
    • 哦,这完全有道理。我会这样做的:)
    【解决方案3】:

    我对 Keras 了解不多。我咨询了一些专家,以下应该可行:

    from keras import backend as k
    
    # Build the model first
    model = ...    
    
    # Declare the inputs and outputs for CloudML
    inputs = dict(zip((layer.name for layer in model.input_layers),
                      (t.name for t in model.inputs)))
    tf.add_to_collection('inputs', json.dumps(inputs))
    
    outputs = dict(zip((layer.name for layer in model.output_layers),
                       (t.name for t in model.outputs)))
    tf.add_to_collection('outputs', json.dumps(outputs))
    
    # Fit/train the model
    model.fit(...)
    
    # Export the model
    saver = tf.train.Saver()
    session = K.get_session()
    saver.save(session, 'export')
    

    一些要点:

    • 您必须在创建模型后调用 tf.add_to_collection 但在你调用 K.get_session()、fit 等之前,
    • 你应该确保设置输入和输出层的名称,当 您将它们添加到图表中,因为您需要参考它们 当您发送预测请求时。

    【讨论】:

    • 由于 keras 学习阶段,我在进行预测时也遇到了问题,我训练了模型(学习阶段 = 1)然后在保存之前我做了 K.set_learning_phase(0) 但我仍然得到错误:错误:(gcloud.beta.ml.local.predict)错误:根:运行图期间出现异常:您必须使用 dtype bool [[节点:keras_learning_phase = Placeholder[dtype= DT_BOOL, shape=[], _device="/job:localhost/replica:0/task:0/cpu:0"]()]]
    • 您可以将 {"keras_learning_phase": 0, ...} 作为每个实例的输入的一部分。这行得通吗?
    • 你的意思是上面代码的输入吗?如果是这样,它没有工作。预测抱怨 keras_learning_phase 的输入张量由于第一维而具有错误的形状,即可能有多个输入。不知道如何只传递一个标量。
    • 我将输入添加为inputs['keras_learning_phase'] = K.learning_phase().name,并将{'keras_learning_phase': 0} 包含在我的云机器学习预测输入数据中。我收到错误:InvalidArgumentError(请参阅上面的回溯):第二个输入必须是标量,但它的形状为 [2],其中 2 是数据点的数量。
    • 嗨,很抱歉很久没有回复你了。 CloudML 发生了变化,所以我有很多工作要重做!无论如何,我终于能够让辍学的事情发生了。非常感谢您的所有帮助。
    【解决方案4】:

    这是另一个可能有帮助的答案。假设您已经有一个 keras 模型,您应该能够将其附加到脚本的末尾并获得模型的 ML Engine 兼容版本(协议缓冲区)。请注意,您需要将 saved_model.pb 文件和带有变量的同级目录上传到 ML Engine 以使其工作。另请注意,.pb 文件必须命名为 saved_model.pbsaved_model.pbtxt

    假设您的模型是名称model

    from tensorflow import saved_model
    
    model_builder = saved_model.builder.SavedModelBuilder("exported_model")                                                     
    inputs = {                                                                          
        'input': saved_model.utils.build_tensor_info(model.input)                    
    }                                                                                   
    outputs = {                                                                         
        'earnings': saved_model.utils.build_tensor_info(model.output)                
    }                                                                                                                                                
    signature_def = saved_model.signature_def_utils.build_signature_def(             
        inputs=inputs,                                                                  
        outputs=outputs,                                                                
        method_name=saved_model.signature_constants.PREDICT_METHOD_NAME              
    )                                                                            
    model_builder.add_meta_graph_and_variables(                                         
        K.get_session(),                                                                
        tags=[saved_model.tag_constants.SERVING],                                    
        signature_def_map={saved_model.signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY: signature_def
        })                                                                                                                                                                       
    model_builder.save()   
    

    将模型导出到目录/exported_model

    【讨论】:

      猜你喜欢
      • 2018-01-30
      • 2018-12-24
      • 2019-03-20
      • 2018-10-03
      • 2019-11-25
      • 2020-07-20
      • 2018-12-15
      • 1970-01-01
      • 2021-12-13
      相关资源
      最近更新 更多