创建 Estimator 后更改 Keras 有状态 RNN 模型、层和方法的状态
Changing states of Keras stateful RNN model, layers and methods after creating an Estimator
与独立的 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])
编辑
估计器层数
How can I access individual layers and how can I access the .reset_states() method?
估算器本身是建立在 tf.keras.layers
之上的,这就是您访问图层的方式。
Estimator API 在低级核心 Tensorflow API 上提供高级 API。目的是对最终用户隐藏图形和会话的详细信息。
为什么 tf.estimator
存在?
您可以 运行 在本地主机或分布式多服务器环境中使用基于估计器的模型,而无需更改您的模型。此外,您可以在 CPU、GPU 或 TPU 上 运行 基于 Estimator 的模型,而无需重新编码您的模型。
估算器简化了模型开发人员之间的共享实现。您可以使用高级直观代码开发最先进的模型。简而言之,使用 Estimator 创建模型通常比使用低级 TensorFlow APIs.
容易得多
估算器为您构建图表。
估算器提供了一个安全的分布式训练循环来控制如何以及何时:
构建图表
初始化变量
加载数据
处理异常
创建检查点文件并从故障中恢复
保存 TensorBoard 的摘要
方便的是 the Estimator class 详细信息。
关于 tf.Estimator
好处的几点说明
What is the benefit of using tf.keras.estimator.model_to_estimator over a stand-alone keras model? For example, when we wish to serve the model in real time?
好吧,我宁愿加上我的两分钱也不愿复制文档:
You can run Estimator-based models on a local host or on a distributed multi-server environment without changing your model. Furthermore, you can run Estimator-based models on CPUs, GPUs, or TPUs without recoding your model.
嗯,Keras
模型可以在 CPU 和 GPU "without recoding" 上 运行。分布式训练是有道理的,如果你需要它,也许值得 tf.Estimator
麻烦。此外,作为Tensorflow 2.0 is coming,我不会那么依赖这个高级API。方向比较明确,Tensorflow会变得更加Keras和PyTorch导向(有tf.Eager
high-levelAPI当涉及到第二个框架时),tf.Estimator
与它面向功能的设计并不完全符合要求。
Estimators simplify sharing implementations between model developers.
我能说什么,他们不会,看看SavedModel docs。使用tf.SavedModel
,导出tf.Estimator
创建的模型更好玩,只是让大家看看'easy'是怎样的:
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)
哦,别忘了这个文档不会告诉你如何加载这个模型并在之后使用它(例如,你可以加载到当前会话中,前提是你知道输入和输出节点的名称,很容易分享这些模型,喜欢它)。
You can develop a state of the art model with high-level intuitive code. In short, it is generally much easier to create models with Estimators than with the low-level TensorFlow APIs.
这一点已经涵盖了,确实 tf.Estimator 比低级 Tensorflow 更直观,但我怀疑它在面对 tf.keras
时是否成功。尽管如此,通过三种不同的模式,它毫无意义地以功能为导向的设计(+ 导出的所有乐趣),会让我说它是一个中等水平的 API(拥有多个 API 总是好的)
Estimators are themselves built on tf.keras.layers, which simplifies customization.
好吧,那是 1.9 或 1.8 中的 tf.layers
,但它已被弃用,所以这就是长期 运行.
中 Tensorflow 的良好实践
总而言之: 我不太喜欢服务(不能把我的时间浪费在下一个名字像 tf.estimator.export.build_raw_serving_input_receiver_fn
的不直观的代码上),但是由于设计不佳,您最好避免使用它。
预测也可以用 Keras 模型完成,这会节省你一些时间,但这只是我的意见。
访问各个图层
首先:tf.Estimator
不像Keras模型!
How can I access individual layers and how can I access the .reset_states() method?
好吧,这就是乐趣的开始。您必须在当前会话中获取模型(例如加载导出的 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 状态)。 在获得您的操作和变量后检查 。
虽然这是一个远景,因为不幸的是我还没有看到这样的用例。我认为 'simplified customization'.
就差不多了
预测
好吧,更简单一点(?),您只需在加载模型后将图形输入会话中,就像低级 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 or print the operations and get the ones specifying input. Usually, those will be named like: input_1:0
(for explanation of naming convention you can check ) 作为输入,使用 predictions/Softmax:0
作为输出(如果是多类分类)。您的输出名称将根据导出的模型规格、确切层等而有所不同。
希望这篇post至少能对你有所帮助
PS。我认为你能做的最好的事情就是不理会 tf.Estimator
,据我所知,它无法使用,看起来像是一堆乱七八糟的黑客代码。
与独立的 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])
编辑
估计器层数
How can I access individual layers and how can I access the .reset_states() method?
估算器本身是建立在 tf.keras.layers
之上的,这就是您访问图层的方式。
Estimator API 在低级核心 Tensorflow API 上提供高级 API。目的是对最终用户隐藏图形和会话的详细信息。
为什么 tf.estimator
存在?
您可以 运行 在本地主机或分布式多服务器环境中使用基于估计器的模型,而无需更改您的模型。此外,您可以在 CPU、GPU 或 TPU 上 运行 基于 Estimator 的模型,而无需重新编码您的模型。
估算器简化了模型开发人员之间的共享实现。您可以使用高级直观代码开发最先进的模型。简而言之,使用 Estimator 创建模型通常比使用低级 TensorFlow APIs.
容易得多
估算器为您构建图表。
估算器提供了一个安全的分布式训练循环来控制如何以及何时:
构建图表
初始化变量
加载数据
处理异常
创建检查点文件并从故障中恢复
保存 TensorBoard 的摘要
方便的是 the Estimator class 详细信息。
关于 tf.Estimator
好处的几点说明
What is the benefit of using tf.keras.estimator.model_to_estimator over a stand-alone keras model? For example, when we wish to serve the model in real time?
好吧,我宁愿加上我的两分钱也不愿复制文档:
You can run Estimator-based models on a local host or on a distributed multi-server environment without changing your model. Furthermore, you can run Estimator-based models on CPUs, GPUs, or TPUs without recoding your model.
嗯,Keras
模型可以在 CPU 和 GPU "without recoding" 上 运行。分布式训练是有道理的,如果你需要它,也许值得 tf.Estimator
麻烦。此外,作为Tensorflow 2.0 is coming,我不会那么依赖这个高级API。方向比较明确,Tensorflow会变得更加Keras和PyTorch导向(有tf.Eager
high-levelAPI当涉及到第二个框架时),tf.Estimator
与它面向功能的设计并不完全符合要求。
Estimators simplify sharing implementations between model developers.
我能说什么,他们不会,看看SavedModel docs。使用tf.SavedModel
,导出tf.Estimator
创建的模型更好玩,只是让大家看看'easy'是怎样的:
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)
哦,别忘了这个文档不会告诉你如何加载这个模型并在之后使用它(例如,你可以加载到当前会话中,前提是你知道输入和输出节点的名称,很容易分享这些模型,喜欢它)。
You can develop a state of the art model with high-level intuitive code. In short, it is generally much easier to create models with Estimators than with the low-level TensorFlow APIs.
这一点已经涵盖了,确实 tf.Estimator 比低级 Tensorflow 更直观,但我怀疑它在面对 tf.keras
时是否成功。尽管如此,通过三种不同的模式,它毫无意义地以功能为导向的设计(+ 导出的所有乐趣),会让我说它是一个中等水平的 API(拥有多个 API 总是好的)
Estimators are themselves built on tf.keras.layers, which simplifies customization.
好吧,那是 1.9 或 1.8 中的 tf.layers
,但它已被弃用,所以这就是长期 运行.
总而言之: 我不太喜欢服务(不能把我的时间浪费在下一个名字像 tf.estimator.export.build_raw_serving_input_receiver_fn
的不直观的代码上),但是由于设计不佳,您最好避免使用它。
预测也可以用 Keras 模型完成,这会节省你一些时间,但这只是我的意见。
访问各个图层
首先:tf.Estimator
不像Keras模型!
How can I access individual layers and how can I access the .reset_states() method?
好吧,这就是乐趣的开始。您必须在当前会话中获取模型(例如加载导出的 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 状态)。 在获得您的操作和变量后检查
虽然这是一个远景,因为不幸的是我还没有看到这样的用例。我认为 'simplified customization'.
就差不多了预测
好吧,更简单一点(?),您只需在加载模型后将图形输入会话中,就像低级 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 or print the operations and get the ones specifying input. Usually, those will be named like: input_1:0
(for explanation of naming convention you can check predictions/Softmax:0
作为输出(如果是多类分类)。您的输出名称将根据导出的模型规格、确切层等而有所不同。
希望这篇post至少能对你有所帮助
PS。我认为你能做的最好的事情就是不理会 tf.Estimator
,据我所知,它无法使用,看起来像是一堆乱七八糟的黑客代码。