与独立的Keras模型相比,使用tf.keras.estimator.model_to_estimator
有什么好处?例如,当我们希望实时提供模型时?
让我们举一个例子。我有一个Keras RNN,它是stateful
模型。这意味着当实时数据用于预测时,我需要执行以下步骤:
predict(x=x)
并保存输出的状态,以供该用户将来使用。 在Keras中,我使用以下步骤进行操作:
old_states = [state_h, state_c]
lstm_layer = model.get_layer('lstm')
lstm_layer.reset_states(states=old_states)
pred = model.predict(x=x)
new_states_to_save = [pred[1], pred[2]]
但是,如何使用估计器执行此过程?也就是说,在:
tf.keras.estimator.model_to_estimator(model)
个对象?
如何访问各个图层以及如何访问.reset_states()
方法?
num_input = tf.keras.layers.Input(shape=(None, no_of_features), name='num_input', batch_size=1)
lstm, state_h, state_c = tf.keras.layers.LSTM(units=320,
return_sequences=True,
return_state=True,
stateful=True,
name='lstm')(num_input)
dense = tf.keras.layers.Dense(1, activation='sigmoid', name='main_output')(lstm_3)
model = tf.keras.models.Model(num_input, [dense, state_h, state_c])
答案 0 :(得分:4)
tf.Estimator
与独立的keras模型相比,使用tf.keras.estimator.model_to_estimator有什么好处?例如,当我们希望实时提供模型时?
好吧,我宁愿加两美分而不是复制文档:
您可以在本地主机或分布式多服务器环境上运行基于Estimator的模型,而无需更改模型。此外,您可以在CPU,GPU或TPU上运行基于Estimator的模型,而无需重新编码模型。
好的,Keras
模型也可以“无需重新编码”在CPU和GPU上运行。分布式培训是有道理的,如果您需要它,那么tf.Estimator
的麻烦可能是值得的。此外,作为Tensorflow 2.0 is coming,我不会指望这个高级API。方向很明确, Tensorflow 将变得更加面向 Keras和PyTorch (在第二个框架中使用tf.Eager
高级API), tf.Estimator
面向功能的设计并不能真正满足要求。
估计器简化了模型开发人员之间的共享实现。
我只能说SavedModel docs,但他们不能说。使用tf.SavedModel
,导出通过tf.Estimator
创建的模型更加有趣,只是为了让您看清楚它有多么“简单”:
feature_spec = {'foo': tf.FixedLenFeature(...),
'bar': tf.VarLenFeature(...)}
def serving_input_receiver_fn():
"""An input receiver that expects a serialized tf.Example."""
serialized_tf_example = tf.placeholder(dtype=tf.string,
shape=[default_batch_size],
name='input_example_tensor')
receiver_tensors = {'examples': serialized_tf_example}
features = tf.parse_example(serialized_tf_example, feature_spec)
return tf.estimator.export.ServingInputReceiver(features, receiver_tensors)
哦,别忘了本文档不会告诉您如何加载此模型并在以后使用它(例如,您可以加载到当前会话中,前提是您知道输入的名称和输出节点,因此很容易共享这些模型,喜欢它。)
您可以使用高级直观代码来开发最新模型。简而言之,与低级TensorFlow API相比,使用Estimators创建模型通常要容易得多。
这点已经涵盖了,确实是tf。Estimator比底层的Tensorflow更直观,但是我怀疑面对tf.keras
能否成功。尽管如此,通过三种不同的模式,它是毫无意义的面向功能的设计(加上导出的所有乐趣),我还是会说这是一个中级API(总是有多个API)
估算器本身建立在tf.keras.layers上,从而简化了自定义。
好吧,这是1.9或1.8中的tf.layers
,但是已经过时了,所以从长远来看,这就是Tensorflow的良好实践。
总而言之::我不太愿意提供服务(不能将时间浪费在名称为tf.estimator.export.build_raw_serving_input_receiver_fn
之类的下一个不直观的代码上),但是您会更好避免由于设计不佳而可能的情况。
也可以使用Keras模型进行预测,这可以为您节省一些时间,但这只是我的看法。
首先: tf.Estimator
与Keras模型不同!
如何访问各个图层以及如何访问.reset_states()方法?
好吧,这就是乐趣的开始。您必须在当前会话中获取模型(例如,加载导出的tf.Estimator
)并遍历图形中的操作。
示意性地看起来像这样:
with tf.Session() as session:
# Of course, your tag can be different
tf.saved_model.loader.load(session,
tf.saved_model.tag_constants.SERVING,
"/here/is/mymodel/exported/with/SavedModel")
graph = tf.get_default_graph()
# Here are all the layers of your tf.Estimator, sorted in the order they exist
# At least they were two versions back
operations = graph.get_operations()
# https://www.tensorflow.org/api_docs/python/tf/contrib/framework/get_variables this should work...
variables = tf.contrib.get_variables()
您可以使用这些操作做什么?那些名称具有可读性,也许您可以用这种方式进行修改(并重置rnn状态)。 获取操作和变量后检查here 。
这是一个长镜头,因为不幸的是我还没有看到这样的用例。我认为就“简化定制”而言就可以了。
好一点(?),您只需在加载模型后在会话内提供图形,就像低级Tensorflow:
output_names = "your_output_operation"
input_names = "your_input_operation"
with tf.Session() as session:
# Of course, your tag can be different
tf.saved_model.loader.load(session,
tf.saved_model.tag_constants.SERVING,
"/here/is/mymodel/exported/with/SavedModel")
x = obtain_your_example_as_numpy_array()
results = session.run(output_names, feed_dict={input_names: x})
据我回忆,您可以指定多个输出名称,这个方向可能是一个可行的解决方案。要获取输入和输出名称,可以使用SavedModel CLI或打印操作并获取指定输入的名称。通常,它们的命名方式如下:input_1:0
(用于命名约定的说明,您可以检查this)用于输入,predictions/Softmax:0
用于输出(如果是多类分类)。输出的名称会根据导出的模型规格,确切的图层等而有所不同。
PS。我认为您最好的办法就是让tf.Estimator
独自一人,据我所知这是不可用的,并且看起来像是一堆脏乱的代码。
答案 1 :(得分:2)
如何访问各个图层以及如何访问.reset_states()方法?
估算器本身是建立在tf.keras.layers
上的,这是您访问图层的方式。
Estimator API在底层Tensorflow API核心上提供了高层API。目的是向最终用户隐藏图表和会话的详细信息。
为什么tf.estimator
存在?
您可以在本地主机或分布式多服务器环境上运行基于Estimator的模型,而无需更改模型。此外,您可以在CPU,GPU或TPU上运行基于Estimator的模型,而无需重新编码模型。
估计器简化了模型开发人员之间的共享实现。您可以使用高级直观代码来开发最新模型。简而言之,与低级TensorFlow API相比,使用Estimators创建模型通常要容易得多。
估算器为您构建图形。
估计器提供了一个安全的分布式训练循环,用于控制如何以及何时执行以下操作:
构建图形
初始化变量
加载数据
处理异常
创建检查点文件并从故障中恢复
为TensorBoard保存摘要
方便的the Estimator class详细信息。