在Google ml-engine中使用经过训练的keras模型

时间:2019-02-22 17:15:52

标签: python tensorflow keras google-cloud-ml

我正在尝试使用带有tensorflow的gcloud ml-engine,更确切地说,我想使用已经受过训练的keras模型。

我设法用sciktlearn模型做到了这一点,但这在这里不一样...

首先我用Keras训练一个简单的模型

final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
            WindowManager.LayoutParams.WRAP_CONTENT,
            WindowManager.LayoutParams.WRAP_CONTENT,
            getWindowFlag(),
            WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,
            PixelFormat.TRANSLUCENT);

params.gravity = Gravity.CENTER_HORIZONTAL|Gravity.BOTTOM;

windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
windowManager.addView(frameLayout, params);

LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rootView = layoutInflater.inflate(R.layout.overlay_labels_list_layout, frameLayout);

linearLayout = rootView.findViewById(R.id.overlay_labels_layout);
linearLayout.setVisibility(View.GONE);

Animation in = AnimationUtils.loadAnimation(context, 
android.R.anim.fade_in);
in.setDuration(500);
linearLayout.setVisibility(VISIBLE);
linearLayout.startAnimation(in);

我读到我需要一个SavedModel才能在https://cloud.google.com/ml-engine/docs/tensorflow/deploying-models

的ml-engine中使用它

似乎我必须将其转换为估计量

import numpy as np
from tensorflow import keras

# Creating the dataset
X = np.random.random((500,9))
y = (np.random.random(500)>0.5).astype(int)

# Splitting 
idx_train, idx_test = np.arange(400), np.arange(400,500)
X_train, X_test = X[idx_train], X[idx_test]
y_train, y_test = y[idx_train], y[idx_test]



def define_model():    
    input1 = keras.layers.Input(shape=(9,),name="values")
    hidden = keras.layers.Dense(50, activation='relu', name="hidden")(input1)

    preds = keras.layers.Dense(1, activation='sigmoid', name="labels")(hidden)

    model = keras.models.Model(inputs=input1, 
                  outputs=preds)

    model.compile(loss='binary_crossentropy',
                  optimizer='adam', 
                  metrics=["accuracy"])
    model.summary()

    return model

model = define_model()
model.fit(X_train, y_train,
          batch_size=10, 
          epochs=10, validation_split=0.2)

我设法用这个估算器进行预测

model.save("./model_trained_test.h5")
estimator_model = keras.estimator.model_to_estimator(keras_model_path="./model_trained_test.h5")

为了将其导出到SavedModel,我需要serving_input_receiver_fn。在网上找不到我的情况的例子,这对我来说似乎很简单,因此我尝试了此功能,然后将模型保存在“ here_are_estimators”文件夹中

def input_function(features,labels=None,shuffle=False):
    input_fn = tf.estimator.inputs.numpy_input_fn(
        x={"values": features},
        y=labels,
        shuffle=shuffle
    )
    return input_fn
score = estimator_model.evaluate(input_function(X_test, labels=y_test.reshape(-1,1)))

我的input.json看起来像这样

feature_spec = {'values': tf.FixedLenFeature(9, dtype=tf.float32)}

def serving_input_receiver_fn():

    serialized_tf_example = tf.placeholder(dtype=tf.string,
                                           shape=[None],
                                           name='input_tensors')
    receiver_tensors = {'examples': serialized_tf_example}
    features = tf.parse_example(serialized_tf_example, feature_spec)
    return tf.estimator.export.ServingInputReceiver(features, receiver_tensors)

estimator_model.export_savedmodel("./here_are_estimators",
                                  serving_input_receiver_fn=serving_input_receiver_fn)

我将生成的文件,变量文件夹和saved_model.pb文件的内容上载到目录DEPLOYMENT_SOURCE的GCS中

当我尝试使用以下命令使用gcloud运行本地预测时:

{"examples":[{"values":[[0.2,0.3,0.4,0.5,0.9,1.5,1.6,7.3,1.5]]}]}

我遇到此错误

gcloud ml-engine local predict --model-dir $DEPLOYMENT_SOURCE --json-instances="input.json" --verbosity debug --framework tensorflow

我想我的input.json或serve_input_receiver_fn或这两者都存在问题,但是我找不到原因。如果有人可以告诉我哪里出了问题,将不胜感激:)

1 个答案:

答案 0 :(得分:1)

您不应该尝试解析tf.Example,因为您正在发送JSON。尝试将其导出:

def serving_input_receiver_fn(): 
    inputs = {"values": tf.placeholder(dtype=tf.float32,
                                       shape=[None, 9],
                                       name='input_tensors')}
    return tf.estimator.export.ServingInputReceiver(inputs, inputs) 

estimator_model.export_savedmodel("./here_are_estimators", serving_input_receiver_fn=serving_input_receiver_fn)

输入应如下所示:

{"values":[0.2,0.3,0.4,0.5,0.9,1.5,1.6,7.3,1.5]}

还有一个更简洁的“速记”:

[0.2,0.3,0.4,0.5,0.9,1.5,1.6,7.3,1.5]