Tensorflow:用于 SVM 估计器的具有稀疏数据的输入管道
Tensorflow: Input pipeline with sparse data for the SVM estimator
简介:
我正在尝试使用稀疏数据训练 tensorflow svm 估计器 tensorflow.contrib.learn.python.learn.estimators.svm
。在 tensorflow/contrib/learn/python/learn/estimators/svm_test.py#L167
的 github 回购中使用稀疏数据的示例(我不允许 post 更多链接,所以这里是相对路径)。
svm 估计器期望参数 example_id_column
和 feature_columns
,其中特征列应该来自 class 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 的文档。
问题:
- 我如何设置我的输入管道来格式化稀疏数据,以便我可以使用 tf.contrib.layers feature_columns 之一作为 svm 估计器的输入。
- 具有许多特征的密集输入函数会是什么样子?
背景
我使用的数据是来自 LIBSVM website 的 a1a
数据集。该数据集有 123 个特征(如果数据密集,则对应 123 feature_columns)。我写了一个用户操作来读取 tf.decode_csv()
之类的数据,但对于 LIBSVM 格式。 op returns 标签为密集张量,特征为稀疏张量。我的输入管道:
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()
这是一个示例,其中包含虚构数据,适用于 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}
从 TensorFlow 1.5.0 开始有一个内置函数来读取 LIBSVM 数据,
在这里参考我的回答
简介:
我正在尝试使用稀疏数据训练 tensorflow svm 估计器 tensorflow.contrib.learn.python.learn.estimators.svm
。在 tensorflow/contrib/learn/python/learn/estimators/svm_test.py#L167
的 github 回购中使用稀疏数据的示例(我不允许 post 更多链接,所以这里是相对路径)。
svm 估计器期望参数 example_id_column
和 feature_columns
,其中特征列应该来自 class 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 的文档。
问题:
- 我如何设置我的输入管道来格式化稀疏数据,以便我可以使用 tf.contrib.layers feature_columns 之一作为 svm 估计器的输入。
- 具有许多特征的密集输入函数会是什么样子?
背景
我使用的数据是来自 LIBSVM website 的 a1a
数据集。该数据集有 123 个特征(如果数据密集,则对应 123 feature_columns)。我写了一个用户操作来读取 tf.decode_csv()
之类的数据,但对于 LIBSVM 格式。 op returns 标签为密集张量,特征为稀疏张量。我的输入管道:
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()
这是一个示例,其中包含虚构数据,适用于 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}
从 TensorFlow 1.5.0 开始有一个内置函数来读取 LIBSVM 数据, 在这里参考我的回答