Jac*_*cob 3 tensorflow tensorflow-serving
我知道"提供Tensorflow模型"页面
https://www.tensorflow.org/serving/serving_basic
但是那些函数假设你正在使用DNNC分类器教程没有使用的tf.Session()...然后我查看了DNNClassifier的api文档,它有一个export_savedmodel函数(导出函数已弃用),看起来很简单但是我得到一个"'NoneType'对象是不可迭代的"错误...这意味着我要传递一个空变量,但我不确定我需要改变什么...我基本上复制和粘贴tensorflow.org上的get_started/tflearn页面中的代码,但随后又添加了
directoryName = "temp"
def serving_input_fn():
print("asdf")
classifier.export_savedmodel(
directoryName,
serving_input_fn
)
Run Code Online (Sandbox Code Playgroud)
在classifier.fit函数调用之后... export_savedmodel的其他参数是可选的我相信......任何想法?
代码教程:https: //www.tensorflow.org/get_started/tflearn#construct_a_deep_neural_network_classifier
export_savedmodel的API文档 https://www.tensorflow.org/api_docs/python/tf/contrib/learn/DNNClassifier#export_savedmodel
Dav*_*tia 14
有两种TensorFlow应用程序:
tf.Session()的函数是来自"低级"Tensorflow示例的函数,以及我将解释如何导出"高级"Tensorflow模型(使用export_savedmodel).
该函数export_savedmodel需要参数serving_input_receiver_fn,即不带参数的函数,它定义模型和预测变量的输入.因此,您必须创建自己serving_input_receiver_fn的模型输入类型与训练脚本中的模型输入匹配,并且预测变量输入类型与测试脚本中的预测变量输入匹配.
另一方面,如果创建自定义模型,则必须定义export_outputs由函数定义的tf.estimator.export.PredictOutput哪个输入是字典,该字典定义必须与测试脚本中的预测器输出的名称匹配的名称.
例如:
def serving_input_receiver_fn():
serialized_tf_example = tf.placeholder(dtype=tf.string, shape=[None], name='input_tensors')
receiver_tensors = {"predictor_inputs": serialized_tf_example}
feature_spec = {"words": tf.FixedLenFeature([25],tf.int64)}
features = tf.parse_example(serialized_tf_example, feature_spec)
return tf.estimator.export.ServingInputReceiver(features, receiver_tensors)
def estimator_spec_for_softmax_classification(logits, labels, mode):
predicted_classes = tf.argmax(logits, 1)
if (mode == tf.estimator.ModeKeys.PREDICT):
export_outputs = {'predict_output': tf.estimator.export.PredictOutput({"pred_output_classes": predicted_classes, 'probabilities': tf.nn.softmax(logits)})}
return tf.estimator.EstimatorSpec(mode=mode, predictions={'class': predicted_classes, 'prob': tf.nn.softmax(logits)}, export_outputs=export_outputs) # IMPORTANT!!!
onehot_labels = tf.one_hot(labels, 31, 1, 0)
loss = tf.losses.softmax_cross_entropy(onehot_labels=onehot_labels, logits=logits)
if (mode == tf.estimator.ModeKeys.TRAIN):
optimizer = tf.train.AdamOptimizer(learning_rate=0.01)
train_op = optimizer.minimize(loss, global_step=tf.train.get_global_step())
return tf.estimator.EstimatorSpec(mode, loss=loss, train_op=train_op)
eval_metric_ops = {'accuracy': tf.metrics.accuracy(labels=labels, predictions=predicted_classes)}
return tf.estimator.EstimatorSpec(mode=mode, loss=loss, eval_metric_ops=eval_metric_ops)
def model_custom(features, labels, mode):
bow_column = tf.feature_column.categorical_column_with_identity("words", num_buckets=1000)
bow_embedding_column = tf.feature_column.embedding_column(bow_column, dimension=50)
bow = tf.feature_column.input_layer(features, feature_columns=[bow_embedding_column])
logits = tf.layers.dense(bow, 31, activation=None)
return estimator_spec_for_softmax_classification(logits=logits, labels=labels, mode=mode)
def main():
# ...
# preprocess-> features_train_set and labels_train_set
# ...
classifier = tf.estimator.Estimator(model_fn = model_custom)
train_input_fn = tf.estimator.inputs.numpy_input_fn(x={"words": features_train_set}, y=labels_train_set, batch_size=batch_size_param, num_epochs=None, shuffle=True)
classifier.train(input_fn=train_input_fn, steps=100)
full_model_dir = classifier.export_savedmodel(export_dir_base="C:/models/directory_base", serving_input_receiver_fn=serving_input_receiver_fn)
Run Code Online (Sandbox Code Playgroud)
def main():
# ...
# preprocess-> features_test_set
# ...
with tf.Session() as sess:
tf.saved_model.loader.load(sess, [tf.saved_model.tag_constants.SERVING], full_model_dir)
predictor = tf.contrib.predictor.from_saved_model(full_model_dir)
model_input = tf.train.Example(features=tf.train.Features( feature={"words": tf.train.Feature(int64_list=tf.train.Int64List(value=features_test_set)) }))
model_input = model_input.SerializeToString()
output_dict = predictor({"predictor_inputs":[model_input]})
y_predicted = output_dict["pred_output_classes"][0]
Run Code Online (Sandbox Code Playgroud)
(在Python 3.6.3中测试的代码,Tensorflow 1.4.0)
有两个可能的问题和可能的答案。首先,您会遇到 DNNClassifier 缺少会话,该会话使用更高级别的估计器 API(而不是您自己操作操作的低级别 API)。Tensorflow 的好处在于,所有高级和低级 API 或多或少都是可互操作的,因此,如果您想要一个会话并使用该会话执行某些操作,只需添加以下内容即可:
sess = tf.get_default_session()
Run Code Online (Sandbox Code Playgroud)
您可以开始学习本教程的其余部分。
您问题的第二种解释是,export_savedmodel 怎么样?实际上,export_savedmodel 和服务教程中的示例代码试图实现相同的目标。当您训练图表时,您会设置一些基础设施来向图表提供输入(通常是来自训练数据集的批次),但是当您切换到“服务”时,您通常会从其他地方读取输入,并且您需要一些单独的基础设施替换用于训练的图的输入。最重要的是,serving_input_fn()您用 print 填充的内容本质上应该返回一个输入操作。文档中也提到了这一点:
serving_input_fn:一个不带参数并返回InputFnOps的函数。
因此,print("asdf")它应该做一些类似于添加输入链的事情(这应该类似于 builder.add_meta_graph_and_variables 也添加的内容)。
例如,可以找到serving_input_fn()的示例(在cloudml示例中)[ https://github.com/GoogleCloudPlatform/cloudml-samples/blob/master/census/customestimator/trainer/model.py#L240]。例如以下内容提供来自 JSON 的输入:
def json_serving_input_fn():
"""Build the serving inputs."""
inputs = {}
for feat in INPUT_COLUMNS:
inputs[feat.name] = tf.placeholder(shape=[None], dtype=feat.dtype)
return tf.estimator.export.ServingInputReceiver(inputs, inputs)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6291 次 |
| 最近记录: |