¿Cómo cargar datos escasos con TensorFlow?

Hay un pequeño fragmento sobre la carga de datos escasos, pero no tengo idea de cómo usarlo.

Los tensores dispersos no juegan bien con las colas. Si usa SparseTensors, tiene que decodificar los registros de la cadena usando tf.parse_example después del procesamiento por lotes (en lugar de usar tf.parse_single_example antes del procesamiento por lotes).

Fuente

Supongo que realmente no entiendo cómo se cargan los datos.

Los datos que quiero cargar están en formato SVM Light

La forma en que pienso de esto es convertir el conjunto de entrenamiento al formato de archivo TFRecords y luego cargar estos datos convertidos con tensorflow. La cosa es que no sé cómo se supone que debo formatear mis datos para que tensorflow los analice como Tensores dispersos.

Aquí hay un fragmento extraído de uno de los ejemplos disponibles en 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() 

Codifica los datos de la imagen como un gran blob. La diferencia con mis datos es que no todas las características están pobladas. Podría estar conservando mis datos de la misma manera, pero no estoy seguro de que esta sea la forma de usar las funciones.

Eso no debería importar ya que, por otro lado, estaré decodificando cosas, pero ¿hay una mejor manera de hacerlo para datos escasos?

En cuanto a la lectura, aquí hay un ejemplo que lee datos densos del tensor.

tf.parse_single_example que tenía que intercambiar tf.parse_single_example con tf.parse_example y hacerlo después del procesamiento por lotes.

Sin embargo, ¿cómo le digo a tensorflow que mis datos son escasos? ¿Cómo asocio los índices de características que tengo con los valores de característica en el tensor? ¿Cómo puedo hacer lotes incluso antes de haber cargado los datos?

EDITAR 1:

Esto es lo que intenté, obtengo un ValueError: Shape () must have rank 1 error de 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') 

Gracias,

Primero, explicar qué significa esa documentación:

  1. Para datos densos usualmente estás haciendo:

    Ejemplo serializado (del lector) -> parse_single_example -> batch queue -> usarlo.

  2. Para datos dispersos que necesita hacer actualmente:

    Ejemplo serializado (del lector) -> batch queue -> parse_example -> usarlo.

Un ejemplo de esto sería:

 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) 

Tenga en cuenta que shuffle_batch toma una serie de cadenas y devuelve lotes de cadenas. label debe ser fija len de rango == 1 de su ejemplo.

Almacene índices y valores en sus ejemplos de TFRecords, y SparseFeature con SparseFeature . Por ejemplo, para almacenar y cargar una representación dispersa para:

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

Esto crea un ejemplo de 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() 

Y esto lo analiza con 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]))} 

Más exposición: Sparse Tensors y TFRecords.

Para el formato libsvm, puede escribir y analizar como se muestra a continuación, si desea un resultado de tensor disperso (a diferencia del resultado de tensor denso que utiliza la estrategia de relleno)

  #---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 

Así, de esta manera obtendrá la etiqueta como tensor denso, el índice y el valor como dos tensores dispersos, puede ver un ejemplo autónomo de escritura de formato libsvm en TFRecord y leerlo para la clasificación mlp de

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

Puede usar weighted_categorical_column para analizar el index y el value , por ejemplo.

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

luego alimente sparse_columns al estimador de modelo lineal, antes de alimentar a DNN, use incrustación, por ejemplo.

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

luego alimente las dense_columns a su estimador de DNN

Si está pasando valores dispersos como entradas, debe crear marcadores de posición dispersos utilizando tf.sparse_placeholder .

Luego debe convertir sus tensores dispersos en tensor denso usando tf.sparse_to_dense .

Para esto, debe pasar explícitamente los valores, la forma y los índices de la matriz dispersa mientras alimenta los datos en feed_dict y luego use tf.sparse_to_dense en el gráfico.

En la gráfica:

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

En el feed_dict:

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