Tensorflow 步骤数不';使用tf.estimator.estimator时不匹配

Tensorflow 步骤数不';使用tf.estimator.estimator时不匹配,tensorflow,Tensorflow,我正在研究张量流估计框架。我终于有了一个训练模型的代码。我使用一个简单的MNIST自动编码器进行测试。我有两个问题。第一个问题是,为什么训练报告的步数与我在estimator train()方法中指定的步数不同?第二个问题是如何使用培训挂钩来做一些事情,比如定期评估、每X步损失输出等?文档似乎说要使用培训挂钩,但我似乎找不到任何实际的例子来说明如何使用这些挂钩 这是我的密码: from __future__ import absolute_import from __future__ impor

我正在研究张量流估计框架。我终于有了一个训练模型的代码。我使用一个简单的MNIST自动编码器进行测试。我有两个问题。第一个问题是,为什么训练报告的步数与我在estimator train()方法中指定的步数不同?第二个问题是如何使用培训挂钩来做一些事情,比如定期评估、每X步损失输出等?文档似乎说要使用培训挂钩,但我似乎找不到任何实际的例子来说明如何使用这些挂钩

这是我的密码:

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)
    
    注:

  • 保存每个新检查点后(即每1500个步骤),将运行100个步骤的评估,然后继续培训
  • log\u step\u count\u steps每X步打印一次损耗输出
  • 参数throttle_secs定义了两个连续评估步骤之间的最小秒数。如果在此秒数之前存储了新的检查点,则跳过评估

  • 以上内容将在同一个数据集上进行训练和评估,如果您希望在不同的数据集上进行训练和评估,那么将其(数据集的)合适的输入函数传递给参数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)