【问题标题】:How to load sparse data with TensorFlow?如何使用 TensorFlow 加载稀疏数据?
【发布时间】:2016-04-28 14:34:25
【问题描述】:

有一个关于加载稀疏数据的小sn-p,但我不知道如何使用它。

SparseTensors 不能很好地处理队列。如果您使用 SparseTensors,则必须在批处理后使用 tf.parse_example 解码字符串记录(而不是在批处理前使用 tf.parse_single_example)。

Source

我想我并不真正了解数据是如何加载的。

我要加载的数据是SVM Light格式

我的想法是将训练集转换为 TFRecords 文件格式,然后使用 tensorflow 加载转换后的数据。问题是我不知道我应该如何格式化我的数据,以便 tensorflow 将其解析为 sparseTensors。

这是从one GitHub 上提供的示例中提取的 sn-p:

def convert_to(images, labels, name):
  num_examples = labels.shape[0]
  if images.shape[0] != num_examples:
    raise ValueError("Images size %d does not match label size %d." %
                     (images.shape[0], num_examples))
  rows = images.shape[1]
  cols = images.shape[2]
  depth = images.shape[3]

  filename = os.path.join(FLAGS.directory, name + '.tfrecords')
  print('Writing', filename)
  writer = tf.python_io.TFRecordWriter(filename)
  for index in range(num_examples):
    image_raw = images[index].tostring()
    example = tf.train.Example(features=tf.train.Features(feature={
        'height': _int64_feature(rows),
        'width': _int64_feature(cols),
        'depth': _int64_feature(depth),
        'label': _int64_feature(int(labels[index])),
        'image_raw': _bytes_feature(image_raw)}))
    writer.write(example.SerializeToString())
  writer.close()

它将图像数据编码为一个大块。我的数据的不同之处在于并非每个功能都被填充。我可能会以相同的方式保存我的数据,但我不确定这是使用这些功能的方式。

这无关紧要,因为另一方面我会解码,但是对于稀疏数据,有没有更好的方法呢?

关于读取,here 是读取密集张量数据的一个例子。

我知道我应该将tf.parse_single_exampletf.parse_example 交换并在批处理后进行。

但是,我如何告诉 tensorflow 我的数据是稀疏的?如何将我拥有的特征索引与张量中的特征值相关联?如何在加载数据之前进行批处理?

编辑 1:

这是我尝试过的,我收到 ValueError: Shape () must have rank 1 错误:

from tqdm import *

def convert_to_tensor_file(path, out_file_name):

    feature_set = set()

    filename = os.path.join(FLAGS.directory, out_file_name + '.tfrecords')
    writer = tf.python_io.TFRecordWriter(filename)

    with open(path, 'r') as f:
        for line in tqdm(f):
            data = line.strip().split(' ')
            features = {
                "label": _int64_feature(int(data[0]))
            }
            for feature in data[1:]:
                index, value = feature.split(':')

                feature_set.add(index)

                features[index] = _int64_feature(int(value))

            example = tf.train.Example(features=tf.train.Features(feature=features))
            writer.write(example.SerializeToString())
        writer.close()

    return feature_set

feature_set = convert_to_tensor_file(TRAIN, 'train')

def load_tensor_file(name):
    filename = os.path.join(FLAGS.directory, name + '.tfrecords')

    features = {
        'label': tf.FixedLenFeature([], tf.int64),
    }

    for feature in feature_set:
        features[feature] = tf.VarLenFeature(tf.int64)

    with tf.name_scope('input'):
        filename_queue = tf.train.string_input_producer([filename])

        reader = tf.TFRecordReader()
        _, serialized_example = reader.read(filename_queue)
        features = tf.parse_example(serialized_example, features=features)

load_tensor_file('train')

谢谢,

【问题讨论】:

    标签: python tensorflow


    【解决方案1】:

    首先,解释一下该文档的含义:

    1. 对于密集数据,您通常会这样做:

      序列化示例(来自读者)-> parse_single_example -> batch queue -> 使用它。

    2. 对于稀疏数据你目前需要做的:

      序列化示例(来自读者)-> batch queue -> parse_example -> 使用它。

    这方面的一个例子是:

    reader  = tf.TFRecordReader()
    _, serialized_example = reader.read(filename_queue)
    batch_serialized_examples = tf.shuffle_batch([serialized_example], batch_size)
    feature_to_type = {
      'label': tf.FixedLenFeature([1], dtype=tf.int64),
      'sparse_feature': tf.VarLenFeature(dtype=tf.int64)
    }
    features = tf.parse_example(batch_serialized_examples, feature_to_type)
    

    注意,shuffle_batch 接受一系列字符串并返回一批字符串。 label 在您的示例中应该是 len 的 rank == 1。

    【讨论】:

    • 谢谢,对于答案,这引发了更多问题:批处理步骤用于什么?这里sparse_feature的定义是什么,是特征向量,包含多个特征的向量还是特征向量的一个元素?
    【解决方案2】:

    在您的 TFRecords 示例中存储索引和值,并使用 SparseFeature 进行解析。例如,存储和加载稀疏表示:

    [[0, 0, 0, 0, 0, 7],
     [0, 5, 0, 0, 0, 0],
     [0, 0, 0, 0, 9, 0],
     [0, 0, 0, 0, 0, 0]]
    

    这将创建一个 TFRecords 示例:

    my_example = tf.train.Example(features=tf.train.Features(feature={
        'index_0': tf.train.Feature(int64_list=tf.train.Int64List(value=[0, 1, 2])),
        'index_1': tf.train.Feature(int64_list=tf.train.Int64List(value=[5, 1, 4])),
        'values': tf.train.Feature(int64_list=tf.train.Int64List(value=[7, 5, 9]))
    }))
    my_example_str = my_example.SerializeToString()
    

    这会用SparseFeature解析它:

    my_example_features = {'sparse': tf.SparseFeature(index_key=['index_0', 'index_1'],
                                                      value_key='values',
                                                      dtype=tf.int64,
                                                      size=[4, 6])}
    serialized = tf.placeholder(tf.string)
    parsed = tf.parse_single_example(serialized, features=my_example_features)
    session.run(parsed, feed_dict={serialized: my_example_str})
    
    ## {'sparse': SparseTensorValue(indices=array([[0, 5], [1, 1], [2, 4]]),
    ##                              values=array([7, 5, 9]),
    ##                              dense_shape=array([4, 6]))}
    

    更多说明:Sparse Tensors and TFRecords

    【讨论】:

    • 在阅读了这个anwser和博客之后,我仍然无法弄清楚如何加载一维稀疏表示?
    【解决方案3】:

    对于 libsvm 格式,如果您想要稀疏张量结果(而不是使用填充策略的密集张量结果),您可以像下面这样编写和解析

        #---write
        _float_feature = lambda v: tf.train.Feature(float_list=tf.train.FloatList(value=v))
        _int_feature = lambda v: tf.train.Feature(int64_list=tf.train.Int64List(value=v))
    
        indexes = []
        values = []
    
        for item in l[start:]:
          index,value = item.split(':')
          indexes.append(int(index))
          values.append(float(value))
    
        example = tf.train.Example(features=tf.train.Features(feature={
          'label': _int_feature([label]),
          'num_features': _int_feature([num_features]),
          'index': _int_feature(indexes),
          'value': _float_feature(values)
          }))
    
        writer.write(example.SerializeToString())
    
        #---read
        def decode(batch_serialized_examples):
            features = tf.parse_example(
                batch_serialized_examples,
                features={
                    'label' : tf.FixedLenFeature([], tf.int64),
                    'index' : tf.VarLenFeature(tf.int64),
                    'value' : tf.VarLenFeature(tf.float32),
                })
    
            label = features['label']
            index = features['index']
            value = features['value']
    
            return label, index, value
    

    因此,通过这种方式,您将获得标签作为密集张量,索引和值作为两个稀疏张量,您可以看到一个自包含的示例,将 libsvm 格式写入 TFRecord 并从

    读取它以进行 mlp 分类

    https://github.com/chenghuige/tensorflow-example/tree/master/examples/tf-record/sparse https://github.com/chenghuige/tensorflow-example/tree/master/examples/text-classification

    【讨论】:

      【解决方案4】:

      您可以使用weighted_categorical_column 来解析indexvalue,例如。

      categorical_column = tf.feature_column.categorical_column_with_identity(
                  key='index', num_buckets=your_feature_dim)
      sparse_columns = tf.feature_column.weighted_categorical_column(
          categorical_column=categorical_column, weight_feature_key='value')
      

      然后将sparse_columns 输入到线性模型估计器,在输入到 DNN 之前,请使用嵌入,例如。

      dense_columns = tf.feature_column.embedding_column(sparse_columns, your_embedding_dim)
      

      然后将dense_columns 提供给您的 DNN 估算器

      【讨论】:

        【解决方案5】:

        如果您将稀疏值作为输入传递,则需要使用 tf.sparse_placeholder 创建稀疏占位符。

        然后您应该使用 tf.sparse_to_dense 将稀疏张量转换为密集张量。

        为此,您需要在 feed_dict 中输入数据时显式传递稀疏矩阵的值、形状和索引,然后在图表中使用 tf.sparse_to_dense

        在图中:

        dense = tf.sparse_to_dense(
            sparse_indices=sparse_placeholder.indices,
            output_shape=sparse_placeholder.shape,
            sparse_values=sparse_placeholder.values,
        validate_indices=False)
        

        在 feed_dict 中:

        sparse_placeholder:tf.SparseTensorValue(indices=indices,values=sparse_values,dense_shape=sparse_shape)
        

        【讨论】:

        • 在训练时将稀疏数据转换为密集数据不会否定稀疏数据结构的点吗?
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-04-27
        • 2020-03-14
        • 2019-04-11
        • 1970-01-01
        • 1970-01-01
        • 2015-05-12
        • 1970-01-01
        相关资源
        最近更新 更多