来自带有gcloud ml-engine作业的Tensorflow估算器RNNClassifier的ValueError

时间:2019-04-01 15:46:54

标签: tensorflow lstm gcloud recurrent-neural-network tensorflow-estimator

我正在处理task.py文件,用于提交gcloud MLEngine作业。以前,我曾使用tensorflow.estimator.DNNClassifier成功提交包含我的数据的作业(该数据仅由8列连续数字数据组成,以表示加密货币的价格和数量;无分类)。

我现在切换到了张量流贡献估计器RNNClassifier。这是我当前相关部分的代码:

def get_feature_columns():
  return [
      tf.feature_column.numeric_column(feature, shape=(1,))
      for feature in column_names[:len(column_names)-1]
  ]

def build_estimator(config, learning_rate, num_units):
  return tf.contrib.estimator.RNNClassifier(
    sequence_feature_columns=get_feature_columns(),
    num_units=num_units,
    cell_type='lstm',
    rnn_cell_fn=None,
    optimizer=tf.train.AdamOptimizer(learning_rate=learning_rate),
    config=config)

estimator = build_estimator(
    config=run_config,
    learning_rate=args.learning_rate,
    num_units=[32, 16])

tf.estimator.train_and_evaluate(estimator, train_spec, eval_spec)

但是,我收到以下ValueError:

ValueError: All feature_columns must be of type _SequenceDenseColumn. You can wrap a sequence_categorical_column with an embedding_column or indicator_column. Given (type <class 'tensorflow.python.feature_column.feature_column_v2.NumericColumn'>): NumericColumn(key='LTCUSD_close', shape=(1,), default_value=None, dtype=tf.float32, normalizer_fn=None)

我不明白这一点,因为数据不是绝对的。

2 个答案:

答案 0 :(得分:0)

由于使用数字特征列而出现这种错误,而这种估算器只能接受序列特征列,就像您在init function上看到的那样。

因此,不必使用数字列,而必须使用sequence_numeric_column

答案 1 :(得分:0)

@ Ben7指出sequence_feature_columns接受诸如sequence_numeric_column之类的列。但是,根据文档,RNNClassifier sequence_feature_columns期望SparseTensors和sequence_numeric_column是密集张量。这似乎是矛盾的。

这是我用来解决此问题的一种解决方法(我从this answer中获取了to_sparse_tensor函数):

def to_sparse_tensor(dense):

    # sequence_numeric_column default is float32
    zero = tf.constant(0.0, dtype=tf.dtypes.float32) 

    where = tf.not_equal(dense, zero)
    indices = tf.where(where)
    values = tf.gather_nd(dense, indices)

    return tf.SparseTensor(indices, values, tf.shape(dense, out_type=tf.dtypes.int64))

def get_feature_columns():
  return [
      tf.feature_column.sequence_numeric_column(feature, shape=(1,), normalizer_fn=to_sparse_tensor)
      for feature in column_names[:len(column_names)-1]
  ]