Как загрузить разреженные данные с помощью TensorFlow?

Есть небольшой фрагмент о загрузке разреженных данных, но я понятия не имею, как его использовать.

SparseTensors плохо работают с очередями. Если вы используете SparseTensors, вам необходимо декодировать строковые записи, используя tf.parse_example после пакетной обработки (вместо использования tf.parse_single_example перед пакетной загрузкой).

Источник

Я думаю, я действительно не понимаю, как загружаются данные.

Данные, которые я хочу загрузить, находятся в формате SVM Light

Я думаю об этом, чтобы преобразовать обучающий набор в формат файла TFRecords, а затем загрузить эти преобразованные данные с помощью тензорного потока. Дело в том, что я не знаю, как я должен отформатировать свои данные, чтобы тензорный поток анализировал его как разреженные тензоры.

Вот фрагмент, извлеченный из одного из примеров, доступных в GitHub:

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()

Он кодирует данные изображения как один большой кадр. Разница с моими данными заключается в том, что не каждая функция заполнена. Я мог бы сохранять свои данные таким же образом, но я не уверен, что это способ использования этих функций.

Это не имеет значения, поскольку я буду расшифровывать вещи с другой стороны, но есть ли лучший способ сделать это для разреженных данных?

Что касается чтения, здесь - это один пример, который считывает плотные данные тензора.

У меня получилось, что я должен был поменять tf.parse_single_example на tf.parse_example и сделать это после пакетной обработки.

Однако, как я могу сообщить тензорному потоку, что мои данные разрежены? Как связать индексы функций, которые у меня есть с значениями функции в тензоре? Как я могу выполнить пакетную обработку, прежде чем загружать данные?

ИЗМЕНИТЬ 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')

Спасибо,

Ответы

Ответ 1

Во-первых, чтобы объяснить, что означает эта документация:

  • Для плотных данных, которые вы обычно делаете:

    Сериализованный пример (от читателя) → parse_single_examplebatch queue → используйте его.

  • Для редких данных, которые вам в настоящее время необходимо сделать:

    Сериализованный пример (от читателя) → batch queueparse_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 ранга == 1 из вашего примера.

Ответ 2

В формате 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

Ответ 3

Сохраните индексы и значения в примерах 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]))}

Дополнительная экспозиция: Редкие тензоры и TFRecords