【问题标题】:Tensorflow: Input pipeline with sparse data for the SVM estimatorTensorflow:用于 SVM 估计器的具有稀疏数据的输入管道
【发布时间】:2017-09-15 07:38:28
【问题描述】:

简介:

我正在尝试用稀疏数据训练 tensorflow svm 估计器tensorflow.contrib.learn.python.learn.estimators.svm。在tensorflow/contrib/learn/python/learn/estimators/svm_test.py#L167 的github repo 中使用稀疏数据的示例(我不允许发布更多链接,所以这里是相对路径)。

支持向量机估计器期望作为参数example_id_columnfeature_columns,其中特征列应该派生自类FeatureColumn,例如tf.contrib.layers.feature_column.sparse_column_with_hash_bucket。请参阅tensorflow/contrib/learn/python/learn/estimators/svm.py#L85 上的 Github 存储库和python/contrib.layers#Feature_columns 上 tensorflow.org 上的文档。

问题:

  1. 如何设置输入管道以格式化稀疏数据,以便我可以使用 tf.contrib.layers 特征列之一作为 svm 估计器的输入。
  2. 具有许多特征的密集输入函数会是什么样子?

背景

我使用的数据是来自LIBSVM websitea1a 数据集。该数据集有 123 个特征(如果数据密集,则对应于 123 个特征列)。我编写了一个用户操作来读取tf.decode_csv() 之类的数据,但使用的是 LIBSVM 格式。该操作将标签作为密集张量返回,将特征作为稀疏张量返回。我的输入管道:

NUM_FEATURES = 123
batch_size = 200

# my op to parse the libsvm data
decode_libsvm_module = tf.load_op_library('./libsvm.so')

def input_pipeline(filename_queue, batch_size):
    with tf.name_scope('input'):
        reader = tf.TextLineReader(name="TextLineReader_")
        _, libsvm_row = reader.read(filename_queue, name="libsvm_row_")
        min_after_dequeue = 1000
        capacity = min_after_dequeue + 3 * batch_size
        batch = tf.train.shuffle_batch([libsvm_row], batch_size=batch_size,
                                       capacity=capacity,
                                       min_after_dequeue=min_after_dequeue,
                                       name="text_line_batch_")
        labels, sp_indices, sp_values, sp_shape = \
            decode_libsvm_module.decode_libsvm(records=batch,
                                               num_features=123,
                                               OUT_TYPE=tf.int64, 
                                               name="Libsvm_decoded_")
        # Return the features as sparse tensor and the labels as dense
        return tf.SparseTensor(sp_indices, sp_values, sp_shape), labels

Here 是带有batch_size = 5 的示例批处理。

def input_fn(dataset_name):
    maybe_download()

    filename_queue_train = tf.train.string_input_producer([dataset_name], 
                                                        name="queue_t_")
    features, labels = input_pipeline(filename_queue_train, batch_size)

    return {
        'example_id': tf.as_string(tf.range(1,123,1,dtype=tf.int64)),
        'features': features
    }, labels

这是我迄今为止尝试过的:

with tf.Session().as_default() as sess:
    sess.run(tf.global_variables_initializer())

    coord = tf.train.Coordinator()
    threads = tf.train.start_queue_runners(sess=sess, coord=coord)

    feature_column = tf.contrib.layers.sparse_column_with_hash_bucket(
        'features', hash_bucket_size=1000, dtype=tf.int64)

    svm_classifier = svm.SVM(feature_columns=[feature_column],
                             example_id_column='example_id',
                             l1_regularization=0.0,
                             l2_regularization=1.0)
    svm_classifier.fit(input_fn=lambda: input_fn(TRAIN),
                       steps=30)

    accuracy = svm_classifier.evaluate(
        input_fn= lambda: input_fn(features, labels), 
        steps=1)['accuracy']                       
    print(accuracy)
    coord.request_stop()

    coord.join(threads)
    sess.close()

【问题讨论】:

  • 看来您的方向是正确的。你有整数特征,对吗? sparse_column_with_integerized_feature 对你有用吗?
  • 是的,事实上如果有一个值它就是一个'1',所以基本上是布尔特征。使用 sparse_column_with_integerized_feature 我得到一个形状错误 batch_size=200: InvalidArgumentError: Expected shape [200,4] for example_state_data, got [122,4] (full traceback)

标签: tensorflow classification svm sparse-matrix


【解决方案1】:

这里有一个示例,包含虚构的数据,适用于 TensorFlow 1.1.0-rc2。我认为我的评论具有误导性;您最好将大约 100 个二进制特征转换为实值特征 (tf.sparse_tensor_to_dense) 并使用 real_valued_column,因为 sparse_column_with_integerized_feature 对 SVM 估计器隐藏了大部分有用信息。

import tensorflow as tf

batch_size = 10
num_features = 123
num_examples = 100

def input_fn():
  example_ids = tf.random_uniform(
      [batch_size], maxval=num_examples, dtype=tf.int64)
  # Construct a SparseTensor with features
  dense_features = (example_ids[:, None]
                    + tf.range(num_features, dtype=tf.int64)[None, :]) % 2
  non_zeros = tf.where(tf.not_equal(dense_features, 0))
  sparse_features = tf.SparseTensor(
      indices=non_zeros,
      values=tf.gather_nd(dense_features, non_zeros),
      dense_shape=[batch_size, num_features])
  features = {
      'some_sparse_features': tf.sparse_tensor_to_dense(sparse_features),
      'example_id': tf.as_string(example_ids)}
  labels = tf.equal(dense_features[:, 0], 1)
  return features, labels
svm = tf.contrib.learn.SVM(
    example_id_column='example_id',
    feature_columns=[
      tf.contrib.layers.real_valued_column(
          'some_sparse_features')],
    l2_regularization=0.1, l1_regularization=0.5)
svm.fit(input_fn=input_fn, steps=1000)
positive_example = lambda: {
    'some_sparse_features': tf.sparse_tensor_to_dense(
        tf.SparseTensor([[0, 0]], [1], [1, num_features])),
    'example_id': ['a']}
print(svm.evaluate(input_fn=input_fn, steps=20))
print(next(svm.predict(input_fn=positive_example)))
negative_example = lambda: {
    'some_sparse_features': tf.sparse_tensor_to_dense(
        tf.SparseTensor([[0, 0]], [0], [1, num_features])),
    'example_id': ['b']}
print(next(svm.predict(input_fn=negative_example)))

打印:

{'accuracy': 1.0, 'global_step': 1000, 'loss': 1.0645389e-06}
{'logits': array([ 0.01612902], dtype=float32), 'classes': 1}
{'logits': array([ 0.], dtype=float32), 'classes': 0}

【讨论】:

  • 得到错误:WARNING:tensorflow:tf.variable_op_scope(values, name, default_name) is deprecated, use tf.variable_scope(name, default_name, values) 但没有variable_op_scope 哈哈。有什么想法吗?
  • 呃。不知道为什么它仍然存在(它是in the SDCA code FWIW)。实际上,想要提出拉取请求吗?我认为您可以 s/variable_op_scope/variable_scope/ 在那一行。
【解决方案2】:

自 TensorFlow 1.5.0 以来,有一个内置函数可以读取 LIBSVM 数据, 在这里参考我的回答 https://stackoverflow.com/a/56354308/3885491

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-16
    • 1970-01-01
    相关资源
    最近更新 更多