Построение SparseTensors из элементов набора данных и таблицы поиска для оценщика - PullRequest
0 голосов
/ 02 октября 2018

Я пытаюсь создать один tf.SparseTensor для подачи в модель.Я хочу создать разреженный тензор для каждого входа, затем объединить их по строкам и затем пакетировать их.Входные данные представляют собой строки, которые преобразуются в индексы через таблицу поиска из модуля contrib.lookup.Модель и входной конвейер строятся с помощью парадигмы оценки и API набора данных.Мои примеры прототипов находятся в файлах TFRecord следующим образом:

{'user_id': ['user123'],
 'item_id':['item123'],
 'label': [.12]}

my input_fn выглядит следующим образом:

def dataset_input_fn(tfrecord_pattern, batch_size,
                     n_epochs, user_lookup, item_lookup):

    def _make_sparse_features(features):
        keys_to_features = {
            'user_id': tf.FixedLenFeature([1], tf.string),
            'item_id': tf.FixedLenFeature([1], tf.string),
            'label': tf.FixedLenFeature([1], tf.float32)
         }
        features = tf.parse_single_example(features, keys_to_features)
        user_tensor = sparse_tensor_from_lookup(user_lookup, features['user_id'])

        item_tensor = sparse_tensor_from_lookup(item_lookup, features['item_id'])

        sp_inputs = [user_tensor, item_tensor]
        sparse_features = tf.sparse_concat(axis=0, values=sp_inputs)

        return sparse_features, features['label']

    dataset = tf.data.Dataset.from_tensor_slices(glob.glob(tfrecord_pattern))
    dataset = dataset.shuffle(buffer_size=1028)
    dataset = dataset.flat_map(tf.data.TFRecordDataset)
    dataset = dataset.map(_make_sparse_features)

    dataset = dataset.repeat(num_epochs)
    dataset = dataset.batch(batch_size)

    return dataset

где sparse_tensor_from_lookup определено так (я пробовал оба tf.SparseTensor и tf.SparseTensorValue):

def sparse_tensor_from_lookup(lookup, key_tensor):
    indices = lookup.lookup(key_tensor)
    sparse_tensor = tf.SparseTensorValue(indices=indices,
                                         values=tf.ones_like(indices),
                                         dense_shape=lookup.size())
    return sparse_tensor

Экземпляры таблиц создаются в моей main функции обучения / оценки:

def main_training_and_eval_loop(model_function,
                            training_epochs=10000, batch_size=256,
                            max_training_steps=8000000, learning_rate=1e-2, l2_weight=1e-3,
                            reader_n_threads=2, parser_n_threads=2,
                            save_checkpoint_every_n_steps=2000, factor_order=2,
                            max_steps_without_decrease=20000, shuffle_buffer_size=100000,
                            **context):

    model_directory = '/tmp/'

    users_id_file_path = os.path.join(model_directory, 'vocab/users.txt')
    item_id_file_path = os.path.join(model_directory, 'vocab/items.txt')

    tfrecord_dir = 'airflow_tmp/tfrecords_backfill_2018-09-29T00:43:32.624007/'

    item_lookup = index_table_from_file(item_id_file_path,
                                              num_oov_buckets=1)
    user_lookup = index_table_from_file(users_id_file_path,
                                     num_oov_buckets=1)

    training_input_fn = functools.partial(dataset_input_fn,
                                          os.path.join(tfrecord_dir, '*.tfrecord'), 
                                          batch_size=batch_size,
                                          n_epochs=training_epochs,
                                          user_lookup=user_lookup,
                                          item_lookup=item_lookup)


... etc

Похоже, ошибка, которую я получаю, связана сзначениям, передаваемым tf.SparseTensor при попытке построить указанный тензор:

<ipython-input-5-ec313e9d7732> in _make_sparse_features(features)
 17         }
 18         features = tf.parse_single_example(features, keys_to_features)
---> 19         course_tensor = sparse_tensor_from_lookup(course_lookup, features['target_course_id'])
     20 
     21         course_tags = tf.sparse_tensor_to_dense(features['course_tags'], default_value='')

~/Code/learning-recommendations/airflow/dags/utils/tensorflow/sparse.py in sparse_tensor_from_lookup(lookup, key_tensor)
      6     sparse_tensor = tf.SparseTensor(indices=indices,
      7                                     values=tf.ones_like(indices),
----> 8                                     dense_shape=lookup.size())
      9     return sparse_tensor

/usr/local/lib/python3.6/site-packages/tensorflow/python/framework/sparse_tensor.py in __init__(self, indices, values, dense_shape)
    132     self._dense_shape = dense_shape
    133 
--> 134     indices_shape = indices.get_shape().with_rank(2)
    135     values_shape = values.get_shape().with_rank(1)
    136     dense_shape_shape = dense_shape.get_shape().with_rank(1)

/usr/local/lib/python3.6/site-packages/tensorflow/python/framework/tensor_shape.py in with_rank(self, rank)
    745       return self.merge_with(unknown_shape(ndims=rank))
    746     except ValueError:
--> 747       raise ValueError("Shape %s must have rank %d" % (self, rank))
    748 
    749   def with_rank_at_least(self, rank):

ValueError: Shape (1,) must have rank 2

, но это отличается от ошибки, которую я получаю с tf.SparseTensorValue:

<ipython-input-5-ec313e9d7732> in _make_sparse_features(features)
     30 
     31         sp_inputs = [course_tensor, course_tags_tensor, user_tensor, user_interests_tensor]
---> 32         sparse_features = tf.concat(axis=0, values=sp_inputs)
     33 
     34         return sparse_features, features['label']

/usr/local/lib/python3.6/site-packages/tensorflow/python/ops/array_ops.py in concat(values, axis, name)
   1112               tensor_shape.scalar())
   1113       return identity(values[0], name=scope)
-> 1114   return gen_array_ops.concat_v2(values=values, axis=axis, name=name)
   1115 
   1116 

/usr/local/lib/python3.6/site-packages/tensorflow/python/ops/gen_array_ops.py in concat_v2(values, axis, name)
   1028     _attr_N = len(values)
   1029     _, _, _op = _op_def_lib._apply_op_helper(
-> 1030         "ConcatV2", values=values, axis=axis, name=name)
   1031     _result = _op.outputs[:]
   1032     _inputs_flat = _op.inputs

/usr/local/lib/python3.6/site-packages/tensorflow/python/framework/op_def_library.py in _apply_op_helper(self, op_type_name, name, **keywords)
    481                                 (prefix, dtype.name))
    482               else:
--> 483                 raise TypeError("%s that don't all match." % prefix)
    484             else:
    485               raise TypeError("%s that are invalid." % prefix)

TypeError: Tensors in list passed to 'values' of 'ConcatV2' Op have types [<NOT CONVERTIBLE TO TENSOR>, <NOT CONVERTIBLE TO TENSOR>] that don't all match.

Я выключенRes здесь?Я изо всех сил пытался найти материалы о том, как работать с такого рода рабочим процессом с API набора данных, и еще труднее найти материал о различиях между tf.SparseTensor и tf.SparseTensorValue или вообще много информации о разреженных тензорах.

...