张量必须与使用AdagradDA Optimizer的LinearClassifier中的张量来自同一张图

时间:2018-06-26 10:00:28

标签: python tensorflow machine-learning

我一直在尝试将tf.optimizer.AdagradDA与线性分类器一起使用。这是我的代码:

def input_fn():
    features_in = { "random_var": tf.convert_to_tensor(np.random.randn(100)) }
    labels_in = tf.convert_to_tensor(np.random.choice([0, 1], size=(100,), p=[1./2, 1./2]))
    dataset =  tf.data.Dataset.from_tensors((features_in, labels_in))
    dataset.repeat(2)
    dataset.batch(1)

    iterator = dataset.make_one_shot_iterator()
    features, labels = iterator.get_next()
    return features, labels

def main():
    global_step_tensor = tf.Variable(0, trainable=False, name='global_step')

    optimizer = tf.train.AdagradDAOptimizer(learning_rate=0.001, global_step=global_step_tensor)
    columns = [tf.feature_column.numeric_column('random_var')]
    model = tf.estimator.LinearClassifier(optimizer=optimizer, feature_columns=columns)
    model.train(input_fn=input_fn)

运行代码时,出现以下错误之一:

  • ValueError: Tensor("Identity_1:0", shape=(), dtype=int32) must be from the same graph as Tensor("linear/linear_model/random_var/weights/part_0:0", shape=(1, 1), dtype=float32_ref).
  • ValueError: Tensor("Identity_1:0", shape=(), dtype=int32) must be from the same graph as Tensor("linear/head/AdagradDA/update_linear/linear_model/random_var/weights/part_0/Cast_2/x:0", shape=(), dtype=float32)
  • ValueError: Tensor("Identity_1:0", shape=(), dtype=int32) must be from the same graph as Tensor("linear/linear/linear_model/random_var/weights/part_0/AdagradDA_1:0", shape=(1, 1), dtype=float32_ref).

当我使用 FtrlOptimizer AdagradOptimize 运行相同的代码时,代码可以正常运行。因此,我想这个问题必须与global_step_tensor实例有关。


这是到目前为止我尝试过的事情:

  • 将代码段移至with tf.Session() as sess:
  • LinearClassifier构造函数中创建优化器

1 个答案:

答案 0 :(得分:1)

注意事项:这可在TensorFlow 1.10.0(及以后的版本)中使用。显然,它在TensorFlow 1.9.0(可能更早)中不起作用。请参阅ZakJ在下面的评论。

您需要按以下方式更改构造优化器对象的方式:

optimizer = lambda: tf.train.AdagradDAOptimizer(learning_rate=0.001,global_step=tf.train.get_global_step())

1)注意lambda。与Tensorflow operation相比,这将创建一个可调用对象,而AdagradDAOptimizer会自己返回(没有lambda)。

2)您可以直接使用tf.train.get_global_step(),而不必定义全局步长张量。

我不太确定为什么在这种情况下需要通过添加lambda来创建可调用对象。但是我猜想,每当您想要使用需要global_step的优化程序(或者想要通过它,例如用于学习速率衰减)时,都需要将优化程序设置为可调用的(因此需要lambda)而不是Tensorflow operation

这也是文档here中学习率衰减示例的作用。

这是我在TensorFlow 1.10.0上成功运行的完整代码:

import tensorflow as tf
import numpy as np

def input_fn():
    features_in = { "random_var": tf.convert_to_tensor(np.random.randn(100)) }
    labels_in = tf.convert_to_tensor(np.random.choice([0, 1], size=(100,), p=[1./2, 1./2]))
    dataset =  tf.data.Dataset.from_tensors((features_in, labels_in))
    dataset.repeat(2)
    dataset.batch(1)

    iterator = dataset.make_one_shot_iterator()
    features, labels = iterator.get_next()
    return features, labels

def main():
    optimizer = lambda: tf.train.AdagradDAOptimizer(learning_rate=0.001,global_step=tf.train.get_global_step())
    columns = [tf.feature_column.numeric_column('random_var')]
    model = tf.estimator.LinearClassifier(optimizer=optimizer, feature_columns=columns)
    model.train(input_fn=input_fn)