Tensorflow 步骤数不';使用tf.estimator.estimator时不匹配
我正在研究张量流估计框架。我终于有了一个训练模型的代码。我使用一个简单的MNIST自动编码器进行测试。我有两个问题。第一个问题是,为什么训练报告的步数与我在estimator train()方法中指定的步数不同?第二个问题是如何使用培训挂钩来做一些事情,比如定期评估、每X步损失输出等?文档似乎说要使用培训挂钩,但我似乎找不到任何实际的例子来说明如何使用这些挂钩 这是我的密码:Tensorflow 步骤数不';使用tf.estimator.estimator时不匹配,tensorflow,Tensorflow,我正在研究张量流估计框架。我终于有了一个训练模型的代码。我使用一个简单的MNIST自动编码器进行测试。我有两个问题。第一个问题是,为什么训练报告的步数与我在estimator train()方法中指定的步数不同?第二个问题是如何使用培训挂钩来做一些事情,比如定期评估、每X步损失输出等?文档似乎说要使用培训挂钩,但我似乎找不到任何实际的例子来说明如何使用这些挂钩 这是我的密码: from __future__ import absolute_import from __future__ impor
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import time
import shutil
import numpy as np
import tensorflow as tf
import matplotlib.pyplot as plt
from IPython import display
from tensorflow.examples.tutorials.mnist import input_data
data = input_data.read_data_sets('.')
display.clear_output()
def _model_fn(features, labels, mode=None, params=None):
# define inputs
image = tf.feature_column.numeric_column('images', shape=(784, ))
inputs = tf.feature_column.input_layer(features, [image, ])
# encoder
e1 = tf.layers.dense(inputs, 512, activation=tf.nn.relu)
e2 = tf.layers.dense(e1, 256, activation=tf.nn.relu)
# decoder
d1 = tf.layers.dense(e2, 512, activation=tf.nn.relu)
model = tf.layers.dense(d1, 784, activation=tf.nn.relu)
# training ops
loss = tf.losses.mean_squared_error(labels, model)
train = tf.train.AdamOptimizer().minimize(loss, global_step=tf.train.get_global_step())
if mode == tf.estimator.ModeKeys.TRAIN:
return tf.estimator.EstimatorSpec(mode=mode,
loss=loss,
train_op=train)
_train_input_fn = tf.estimator.inputs.numpy_input_fn({'images': data.train.images},
y=np.array(data.train.images),
batch_size=100,
shuffle=True)
shutil.rmtree("logs", ignore_errors=True)
tf.logging.set_verbosity(tf.logging.INFO)
estimator = tf.estimator.Estimator(_model_fn,
model_dir="logs",
config=tf.contrib.learn.RunConfig(save_checkpoints_steps=1000),
params={})
estimator.train(_train_input_fn, steps=1000)
这里是我得到的输出(注意训练如何在550步停止,代码明确地调用1000步)
信息:tensorflow:使用配置:{“任务类型”:无,“\u任务id”:0,“\u集群规格”:,“\u主节点”:“,”,“\u数量ps\u副本”:0,“\u数量工作者\u副本”:0,“\u环境”:本地”,“u是首席节点”:真,“\u评估\u主节点”:“,”,“u tf\u配置”:gpu选项{
每处理器gpu内存分数:1
}
“无”、“保存检查点摘要”步骤:100、“保存检查点摘要”步骤:无、“会话配置”步骤:无、“保存检查点”步骤:1000、“保留检查点最多”:5、“保留检查点每小时”:10000、“模型目录”:“日志”
信息:tensorflow:创建检查点SaveRhook。
信息:tensorflow:将1的检查点保存到logs/model.ckpt中。
信息:tensorflow:损失=0.102862,步长=1
信息:tensorflow:global_step/sec:41.8119
信息:tensorflow:损耗=0.0191228,步长=101(2.393秒)
信息:tensorflow:global_step/sec:39.9923
信息:tensorflow:损耗=0.0141014,步长=201(2.500秒)
信息:tensorflow:全局步长/秒:40.9806
信息:tensorflow:损耗=0.0116138,步长=301(2.440秒)
信息:tensorflow:全局步长/秒:40.0043
信息:tensorflow:损耗=0.00998991,步长=401(2.500秒)
信息:tensorflow:global_step/sec:39.2571
信息:tensorflow:损耗=0.0124132,步长=501(2.548秒)
信息:tensorflow:将550的检查点保存到logs/model.ckpt中。
信息:tensorflow:最后一步损失:0.00940801。
更新#1我找到了第一个问题的答案。在步骤550停止训练的原因是numpy_input_fn()默认为num_epochs=1。不过,我仍在寻求有关训练挂钩的帮助。看起来您已经通过了550个步骤查看了所有数据。 numpy_input_fn默认的'num_epochs'参数为1,因此您只能运行数据一次。
因此,您应该将num_epochs设置为None以满足步骤要求。估计器可以在3种模式下运行
def _model_fn(features, labels, mode=None, params=None):
# define inputs
image = tf.feature_column.numeric_column('images', shape=(784, ))
inputs = tf.feature_column.input_layer(features, [image, ])
# encoder
e1 = tf.layers.dense(inputs, 512, activation=tf.nn.relu)
e2 = tf.layers.dense(e1, 256, activation=tf.nn.relu)
# decoder
d1 = tf.layers.dense(e2, 512, activation=tf.nn.relu)
model = tf.layers.dense(d1, 784, activation=tf.nn.relu)
# training ops
loss = tf.losses.mean_squared_error(labels, model)
train = tf.train.AdamOptimizer().minimize(loss, global_step=tf.train.get_global_step())
if mode == tf.estimator.ModeKeys.TRAIN:
return tf.estimator.EstimatorSpec(mode=mode,
loss=loss,
train_op=train)
prec, prec_update_op = tf.metrics.precision(labels=labels,predictions=model), name='precision_op')
recall, recall_update_op = tf.metrics.recall(labels=labels, predictions=model, name='recall_op')
metrics={'recall':(recall, recall_update_op), \
'precision':(prec, prec_update_op)}
if mode==tf.estimator.ModeKeys.EVAL:
return tf.estimator.EstimatorSpec(mode, loss=loss, eval_metric_ops=metrics)
现在每10步进行一次评估和打印损耗输出
configuration = tf.estimator.RunConfig(
model_dir = 'logs',
keep_checkpoint_max=5,
save_checkpoints_steps=1500,
log_step_count_steps=10) # set the frequency of logging steps for loss function
estimator = tf.estimator.Estimator(model_fn = _model_fn, params = {}, config=configuration)
train_spec = tf.estimator.TrainSpec(input_fn=_train_input_fn, steps=5000)
eval_spec = tf.estimator.EvalSpec(input_fn=_train_input_fn, steps=100, throttle_secs=600)
tf.estimator.train_and_evaluate(classifier, train_spec, eval_spec)
注:
以上内容将在同一个数据集上进行训练和评估,如果您希望在不同的数据集上进行训练和评估,那么将其(数据集的)合适的输入函数传递给参数input\fnattf.estimator.EvalSpec对于定期验证,我暂时同意。它已被弃用,因为它使用的是较旧的父类,因此您可能会收到警告,但目前还没有基于SessionRunHook的ValidationMonitor替代品。您可以随意添加一些表情符号。通过剪切/粘贴StepCounterHook类实现中的一些代码,似乎可以将SessionRunHook子类化,并使其在特定步骤中运行。我想我会同意的,但我希望事情能有更好的文档记录,我希望会话挂钩的现有子类更有用。是的,事情肯定会得到改进。如果你建立了你喜欢的东西,它可以提出一个很好的拉请求。。。您可能需要ping@ispirmustafa进行协调。首先,我将尝试实施我自己的定期评估,并将其作为答案发布在此处。@MadWombat您成功地使其工作了吗?如果是,你能用你的结果回答你的问题吗?
configuration = tf.estimator.RunConfig(
model_dir = 'logs',
keep_checkpoint_max=5,
save_checkpoints_steps=1500,
log_step_count_steps=10) # set the frequency of logging steps for loss function
estimator = tf.estimator.Estimator(model_fn = _model_fn, params = {}, config=configuration)
train_spec = tf.estimator.TrainSpec(input_fn=_train_input_fn, steps=5000)
eval_spec = tf.estimator.EvalSpec(input_fn=_train_input_fn, steps=100, throttle_secs=600)
tf.estimator.train_and_evaluate(classifier, train_spec, eval_spec)