Tensorflow:全局步骤必须与损失相同

时间:2017-08-14 00:49:20

标签: python machine-learning tensorflow

我正在尝试使用Tensorflow对tf.contrib.layers包进行一些分类,我遇到了一个我无法弄清楚的问题。据我所知(例如thistutorial),图表的所有内容都由API处理。我可以很好地在我的环境中下载并运行相同的代码。

然而,当我运行我的代码时,我得到的错误是我的全局步骤不是与我的损失相同的图形,这看起来很奇怪:ValueError: Tensor("global_step:0", shape=(), dtype=int64_ref) must be from the same graph as Tensor("softmax_cross_entropy_loss/value:0", shape=(), dtype=float32).在构造{{1}期间发生错误}}

这是我的张量流代码(我确实有一些其他代码用于处理数据加载,但它不使用tensorflow中的任何内容)。对不起,现在代码有点混乱:我一直在试图弄清楚这个错误。

train_op

这是完整的堆栈跟踪:

import numpy as np
import tensorflow as tf
from tensorflow.contrib.learn.python.learn.estimators import model_fn as model_fn_lib

import data # my data loading module


def train(training_file, vocab_path, hidden_units=[10, 20, 10], estimator=tf.contrib.learn.DNNClassifier):
    """
    Given a training CSV file, train a Tensorflow neural network
    """

    training_set = data.load(training_file)

    vocab = tf.contrib.learn.preprocessing.VocabularyProcessor(data.DOC_LENGTH)
    vocab = vocab.restore(vocab_path)
    training_data = tf.one_hot(training_set.data, len(vocab.vocabulary_._mapping), dtype=tf.float32)
    training_targets = tf.constant(np.array(training_set.targets, dtype=np.int32))

    classifier = tf.contrib.learn.Estimator(model_fn=lambda features, targets, mode, params: model_fn(features, targets, mode, params, hidden_units))

    classifier.fit(input_fn=lambda: (training_data, training_targets), steps=2000)

    return classifier


def model_fn(features, targets, mode, params, hidden_units):
    if len(hidden_units) <= 0:
        raise ValueError("Hidden units must be a iterable of ints of length >= 1")

    # Define the network
    network = tf.contrib.layers.relu(features, hidden_units[0])
    for i in range(1, len(hidden_units)):
        network = tf.contrib.layers.relu(network, hidden_units[i])

    # Flatten the network
    network = tf.reshape(network, [-1, hidden_units[-1] * data.DOC_LENGTH])

    # Add dropout to enhance feature use
    network = tf.layers.dropout(inputs=network, rate=0.5, training=mode == tf.contrib.learn.ModeKeys.TRAIN)

    # Calculate the logits
    logits = tf.contrib.layers.fully_connected(network, 15)

    loss = None
    train_op = None

    if mode != tf.contrib.learn.ModeKeys.INFER:
        targets = tf.cast(tf.one_hot(targets, 15, 1, 0), dtype=tf.float32)
        loss = tf.losses.softmax_cross_entropy(logits=logits, onehot_labels=targets)

    if mode == tf.contrib.learn.ModeKeys.TRAIN:
        # This train_op causes the error
        train_op = tf.contrib.layers.optimize_loss(
          loss=loss,
          global_step=tf.train.get_global_step(),
          optimizer='Adam',
          learning_rate=0.01)

    predictions = {
          "classes": tf.argmax(input=logits, axis=1),
          "probabilities": tf.nn.softmax(logits, name="softmax_tensor")
    }

    return model_fn_lib.ModelFnOps(mode=mode, predictions=predictions, loss=loss, train_op=train_op)


def main(unusedargv):

    # ... parses arguments

    classifier = train(args.train_data, args.vocab)
    print(evaluate(classifier, args.train_data))
    print(evaluate(classifier, args.test_data))


if __name__ == "__main__":
    tf.app.run()

这是我的代码:

2 个答案:

答案 0 :(得分:2)

两个函数的上下文不同,因此,您需要使用调用函数中的tf.Graph()来设置默认图,如下所示。

def train(...):
    with tf.Graph().as_default():
        ...
        ...
        training_data = tf.one_hot(training_set.data, len(vocab.vocabulary_._mapping), dtype=tf.float32)
        training_targets = tf.constant(np.array(training_set.targets, dtype=np.int32))

        classifier = tf.contrib.learn.Estimator(model_fn=lambda features, targets, mode, params: model_fn(features, targets, mode, params, hidden_units))

        classifier.fit(input_fn=lambda: (training_data, training_targets), steps=2000)

        return classifier

答案 1 :(得分:1)

我发现了问题!这可能与Estimator接口有关,但基本上我需要将tensorflow变量定义移动到Estimator中。我最终创建了一个方法来实现这一点,但是当我在lambda中定义变量时它也起作用了:

def train(training_file, vocab_path, hidden_units=[10, 20, 10]):
    """
    Given a training CSV file, train a Tensorflow neural network
    """

    training_set = data.load(training_file)

    vocab = tf.contrib.learn.preprocessing.VocabularyProcessor(data.DOC_LENGTH)
    vocab = vocab.restore(vocab_path)
    # Note not defining the variables here
    training_data = training_set.data
    training_targets = np.array(training_set.targets, dtype=np.int32)

    classifier = tf.contrib.learn.Estimator(model_fn=lambda features, targets, mode, params: model_fn(features, targets, mode, params, hidden_units))

    # Note the variable definition here
    classifier.fit(
        input_fn=lambda: 
            (tf.one_hot(training_data, len(vocab.vocabulary_._mapping), dtype=tf.float32)
             tf.constant(training_targets)),
        steps=2000))

    return classifier