tf.parse_example для примеров с последовательностью данных последовательности

Моя модель Tensorflow принимает последовательность данных последовательности для каждого примера, а именно, последовательности символьных токенов в последовательности слов (например, [[3], [4,3],[6,1,20]]). Я мог сделать это раньше, добавив трехмерный массив numpy [batch_size, max_words_len, max_chars_len] и вставив его в заполнитель.

in_question_chars = tf.placeholder(tf.int32, 
                                   [None, None, None], 
                                   name="in_question_chars")
# example of other data
in_question_words = tf.placeholder(tf.int32, 
                                   [None, None], 
                                   name="in_question_words")

Но теперь я хотел бы использовать Google Cloud Machine Learning Engine для онлайн-прогнозирования / развертывания. На основе примера из обслуживания Tensorflow: https://github.com/tensorflow/serving/blob/master/tensorflow_serving/example/mnist_saved_model.py

Я придумал что-то вроде этого, но на самом деле не знаю, что использовать для функции для анализа последовательности токенов последовательности:

serialized_tf_example = tf.placeholder(tf.string, name='tf_example')
feature_configs = {'in_question_chars':tf.FixedLenSequenceFeature(shape=[None], 
                                       allow_missing=True, 
                                       dtype=tf.int32, 
                                       default_value=0), 
                   'in_question_words':tf.FixedLenSequenceFeature(shape=[], 
                                       allow_missing=True, 
                                       dtype=tf.int32, 
                                       default_value=0)
                   }

tf_example = tf.parse_example(serialized_tf_example, feature_configs)

in_question_chars = tf.identity(tf_example['in_question_chars'], 
                                name='in_question_chars')
# example of other data
in_question_words = tf.identity(tf_example['in_question_words'], 
                                name='in_question_words')

Должен ли я использовать VarLenFeature, который превращает его в SparseTensor (хотя это не так уж редко), а затем использовать tf.sparse_tensor_to_dense, чтобы преобразовать его обратно в плотный?

На следующем шаге я получаю вложение для каждого символьного токена.

in_question_char_repres = tf.nn.embedding_lookup(char_embedding, 
                                                 in_question_chars) 

Так что другой вариант - оставить его SparseTensor, а затем использовать tf.nn.embedding_lookup_sparse.

Я не смог найти пример того, как это должно быть сделано. Пожалуйста, дайте мне знать, что такое лучшая практика. Спасибо!


Редактировать 25.08.17

Кажется, это не позволяет мне установить None для второго измерения.

Вот сокращенная версия моего кода

def read_dataset(filename, mode=tf.contrib.learn.ModeKeys.TRAIN):  
    def _input_fn():
        num_epochs = MAX_EPOCHS if mode == tf.contrib.learn.ModeKeys.TRAIN else 1

        input_file_names = tf.train.match_filenames_once(str(filename))

        filename_queue = tf.train.string_input_producer(
            input_file_names, num_epochs=num_epochs, shuffle=True)
        reader = tf.TFRecordReader()
        _, serialized = reader.read_up_to(filename_queue, num_records=batch_size)

        features_spec = {
            CORRECT_CHILD_NODE_IDX: tf.FixedLenFeature(shape=[],
                                               dtype=tf.int64, 
                                               default_value=0),
            QUESTION_LENGTHS: tf.FixedLenFeature(shape=[], dtype=tf.int64),
            IN_QUESTION_WORDS: tf.FixedLenSequenceFeature(shape=[], 
                                                      allow_missing=True, 
                                                      dtype=tf.int64
                                                      ),
            QUESTION_CHAR_LENGTHS: tf.FixedLenSequenceFeature(shape=[], 
                                                          allow_missing=True, 
                                                          dtype=tf.int64
                                                          ),
            IN_QUESTION_CHARS: tf.FixedLenSequenceFeature(shape=[None], 
                                                      allow_missing=True, 
                                                      dtype=tf.int64
                                                      )
            }
        examples = tf.parse_example(serialized, features=features_spec)

        label = examples[CORRECT_CHILD_NODE_IDX]
        return examples, label   # dict of features, label
    return _input_fn

Когда у меня есть "Нет" для формы, это дает мне эту ошибку:

    INFO:tensorflow:Using default config.
INFO:tensorflow:Using config: {'_task_type': None, '_task_id': 0, '_cluster_spec': <tensorflow.python.training.server_lib.ClusterSpec object at 0x7f57fc309c18>, '_master': '', '_num_ps_replicas': 0, '_num_worker_replicas': 0, '_environment': 'local', '_is_chief': True, '_evaluation_master': '', '_tf_config': gpu_options {
  per_process_gpu_memory_fraction: 1.0
}
, '_tf_random_seed': None, '_save_summary_steps': 100, '_save_checkpoints_secs': 600, '_log_step_count_steps': 100, '_session_config': None, '_save_checkpoints_steps': None, '_keep_checkpoint_max': 5, '_keep_checkpoint_every_n_hours': 10000, '_model_dir': 'outputdir'}
WARNING:tensorflow:From /home/jupyter-admin/anaconda3/lib/python3.6/site-packages/tensorflow/contrib/learn/python/learn/monitors.py:269: BaseMonitor.__init__ (from tensorflow.contrib.learn.python.learn.monitors) is deprecated and will be removed after 2016-12-05.
Instructions for updating:
Monitors are deprecated. Please use tf.train.SessionRunHook.
---------------------------------------------------------------------------
InvalidArgumentError                      Traceback (most recent call last)
/home/jupyter-admin/anaconda3/lib/python3.6/site-packages/tensorflow/python/framework/common_shapes.py in _call_cpp_shape_fn_impl(op, input_tensors_needed, input_tensors_as_shapes_needed, require_shape_fn)
    653           graph_def_version, node_def_str, input_shapes, input_tensors,
--> 654           input_tensors_as_shapes, status)
    655   except errors.InvalidArgumentError as err:

/home/jupyter-admin/anaconda3/lib/python3.6/contextlib.py in __exit__(self, type, value, traceback)
     88             try:
---> 89                 next(self.gen)
     90             except StopIteration:

/home/jupyter-admin/anaconda3/lib/python3.6/site-packages/tensorflow/python/framework/errors_impl.py in raise_exception_on_not_ok_status()
    465           compat.as_text(pywrap_tensorflow.TF_Message(status)),
--> 466           pywrap_tensorflow.TF_GetCode(status))
    467   finally:

InvalidArgumentError: dense_shapes[2] has unknown rank or unknown inner dimensions: [?,?] for 'ParseExample/ParseExample' (op: 'ParseExample') with input shapes: [?], [0], [], [], [], [], [], [], [], [], [], [0], [1], [], [], [0], [], [0], [0], [0].

During handling of the above exception, another exception occurred:

ValueError                                Traceback (most recent call last)
<ipython-input-45-392858a0e7b4> in <module>()
     48 
     49 shutil.rmtree('outputdir', ignore_errors=True) # start fresh each time
---> 50 learn_runner.run(experiment_fn, 'outputdir')

/home/jupyter-admin/anaconda3/lib/python3.6/site-packages/tensorflow/contrib/learn/python/learn/learn_runner.py in run(experiment_fn, output_dir, schedule, run_config, hparams)
    207   schedule = schedule or _get_default_schedule(run_config)
    208 
--> 209   return _execute_schedule(experiment, schedule)
    210 
    211 

/home/jupyter-admin/anaconda3/lib/python3.6/site-packages/tensorflow/contrib/learn/python/learn/learn_runner.py in _execute_schedule(experiment, schedule)
     44     logging.error('Allowed values for this experiment are: %s', valid_tasks)
     45     raise TypeError('Schedule references non-callable member %s' % schedule)
---> 46   return task()
     47 
     48 

/home/jupyter-admin/anaconda3/lib/python3.6/site-packages/tensorflow/contrib/learn/python/learn/experiment.py in train_and_evaluate(self)
    500             name=eval_dir_suffix, hooks=self._eval_hooks
    501         )]
--> 502       self.train(delay_secs=0)
    503 
    504     eval_result = self._call_evaluate(input_fn=self._eval_input_fn,

/home/jupyter-admin/anaconda3/lib/python3.6/site-packages/tensorflow/contrib/learn/python/learn/experiment.py in train(self, delay_secs)
    278     return self._call_train(input_fn=self._train_input_fn,
    279                             max_steps=self._train_steps,
--> 280                             hooks=self._train_monitors + extra_hooks)
    281 
    282   def evaluate(self, delay_secs=None, name=None):

/home/jupyter-admin/anaconda3/lib/python3.6/site-packages/tensorflow/contrib/learn/python/learn/experiment.py in _call_train(self, _sentinel, input_fn, steps, hooks, max_steps)
    675                                  steps=steps,
    676                                  max_steps=max_steps,
--> 677                                  monitors=hooks)
    678 
    679   def _call_evaluate(self, _sentinel=None,  # pylint: disable=invalid-name,

/home/jupyter-admin/anaconda3/lib/python3.6/site-packages/tensorflow/python/util/deprecation.py in new_func(*args, **kwargs)
    294               'in a future version' if date is None else ('after %s' % date),
    295               instructions)
--> 296       return func(*args, **kwargs)
    297     return tf_decorator.make_decorator(func, new_func, 'deprecated',
    298                                        _add_deprecated_arg_notice_to_docstring(

/home/jupyter-admin/anaconda3/lib/python3.6/site-packages/tensorflow/contrib/learn/python/learn/estimators/estimator.py in fit(self, x, y, input_fn, steps, batch_size, monitors, max_steps)
    456       hooks.append(basic_session_run_hooks.StopAtStepHook(steps, max_steps))
    457 
--> 458     loss = self._train_model(input_fn=input_fn, hooks=hooks)
    459     logging.info('Loss for final step: %s.', loss)
    460     return self

/home/jupyter-admin/anaconda3/lib/python3.6/site-packages/tensorflow/contrib/learn/python/learn/estimators/estimator.py in _train_model(self, input_fn, hooks)
    954       random_seed.set_random_seed(self._config.tf_random_seed)
    955       global_step = contrib_framework.create_global_step(g)
--> 956       features, labels = input_fn()
    957       self._check_inputs(features, labels)
    958       model_fn_ops = self._get_train_ops(features, labels)

<ipython-input-44-fdb63ed72b90> in _input_fn()
     35                                                           )
     36             }
---> 37         examples = tf.parse_example(serialized, features=features_spec)
     38 
     39         label = examples[CORRECT_CHILD_NODE_IDX]

/home/jupyter-admin/anaconda3/lib/python3.6/site-packages/tensorflow/python/ops/parsing_ops.py in parse_example(serialized, features, name, example_names)
    573   outputs = _parse_example_raw(
    574       serialized, example_names, sparse_keys, sparse_types, dense_keys,
--> 575       dense_types, dense_defaults, dense_shapes, name)
    576   return _construct_sparse_tensors_for_sparse_features(features, outputs)
    577 

/home/jupyter-admin/anaconda3/lib/python3.6/site-packages/tensorflow/python/ops/parsing_ops.py in _parse_example_raw(serialized, names, sparse_keys, sparse_types, dense_keys, dense_types, dense_defaults, dense_shapes, name)
    698         dense_keys=dense_keys,
    699         dense_shapes=dense_shapes,
--> 700         name=name)
    701     # pylint: enable=protected-access
    702 

/home/jupyter-admin/anaconda3/lib/python3.6/site-packages/tensorflow/python/ops/gen_parsing_ops.py in _parse_example(serialized, names, sparse_keys, dense_keys, dense_defaults, sparse_types, dense_shapes, name)
    174                                 dense_defaults=dense_defaults,
    175                                 sparse_types=sparse_types,
--> 176                                 dense_shapes=dense_shapes, name=name)
    177   return _ParseExampleOutput._make(result)
    178 

/home/jupyter-admin/anaconda3/lib/python3.6/site-packages/tensorflow/python/framework/op_def_library.py in apply_op(self, op_type_name, name, **keywords)
    765         op = g.create_op(op_type_name, inputs, output_types, name=scope,
    766                          input_types=input_types, attrs=attr_protos,
--> 767                          op_def=op_def)
    768         if output_structure:
    769           outputs = op.outputs

/home/jupyter-admin/anaconda3/lib/python3.6/site-packages/tensorflow/python/framework/ops.py in create_op(self, op_type, inputs, dtypes, input_types, name, attrs, op_def, compute_shapes, compute_device)
   2630                     original_op=self._default_original_op, op_def=op_def)
   2631     if compute_shapes:
-> 2632       set_shapes_for_outputs(ret)
   2633     self._add_op(ret)
   2634     self._record_op_seen_by_control_dependencies(ret)

/home/jupyter-admin/anaconda3/lib/python3.6/site-packages/tensorflow/python/framework/ops.py in set_shapes_for_outputs(op)
   1909       shape_func = _call_cpp_shape_fn_and_require_op
   1910 
-> 1911   shapes = shape_func(op)
   1912   if shapes is None:
   1913     raise RuntimeError(

/home/jupyter-admin/anaconda3/lib/python3.6/site-packages/tensorflow/python/framework/ops.py in call_with_requiring(op)
   1859 
   1860   def call_with_requiring(op):
-> 1861     return call_cpp_shape_fn(op, require_shape_fn=True)
   1862 
   1863   _call_cpp_shape_fn_and_require_op = call_with_requiring

/home/jupyter-admin/anaconda3/lib/python3.6/site-packages/tensorflow/python/framework/common_shapes.py in call_cpp_shape_fn(op, require_shape_fn)
    593     res = _call_cpp_shape_fn_impl(op, input_tensors_needed,
    594                                   input_tensors_as_shapes_needed,
--> 595                                   require_shape_fn)
    596     if not isinstance(res, dict):
    597       # Handles the case where _call_cpp_shape_fn_impl calls unknown_shape(op).

/home/jupyter-admin/anaconda3/lib/python3.6/site-packages/tensorflow/python/framework/common_shapes.py in _call_cpp_shape_fn_impl(op, input_tensors_needed, input_tensors_as_shapes_needed, require_shape_fn)
    657       missing_shape_fn = True
    658     else:
--> 659       raise ValueError(err.message)
    660 
    661   if missing_shape_fn:

ValueError: dense_shapes[2] has unknown rank or unknown inner dimensions: [?,?] for 'ParseExample/ParseExample' (op: 'ParseExample') with input shapes: [?], [0], [], [], [], [], [], [], [], [], [], [0], [1], [], [], [0], [], [0], [0], [0].

В настоящее время я справляюсь с этим, превращая двумерную последовательность последовательности в одномерную последовательность, устанавливая для второго измерения значение max_char_length, а затем объединяю его в одномерный массив. Поэтому я сохраняю только первый символ max_char_length, если он длиннее max_char_length, или добавляю его к нулям, если он короче. Кажется, это работает, но, возможно, есть способ, где он может принять последовательность переменной длины для второго измерения и выполнить заполнение в tf.parse_example или tf.train.batch.

1 ответ

РЕДАКТИРОВАТЬ: исправлена ​​путаница / неправильный ответ =)

Так что вы хотите, это tf.SequenceExample который использует tf.parse_single_sequence_example скорее, чем tf.parse_example, Это позволяет вам иметь каждую функцию в feature_list в примере быть частью последовательности, в этом случае каждый Feature может быть VarLenFeature представляющий количество символов в слове. К сожалению, это не работает так же хорошо, если вы хотите передать несколько предложений. Таким образом, мы должны взломать функции высшего порядка и tf.sparse_concat:

Я создал тестовую программу, которая делает это здесь: https://gist.github.com/elibixby/1c7a2497f96a457130241c59c676ebd4

Ввод (до сериализации в пакет SequenceExamples) похоже:

[[[5, 10], [5, 10, 20]],
 [[0, 1, 2], [2, 1, 0], [0, 1, 2, 3]]]

Результирующий SparseTensor похоже:

SparseTensorValue(indices=array([[[0, 0, 0],
    [0, 0, 1],
    [0, 1, 0],
    [0, 1, 1],
    [0, 1, 2],
    [1, 0, 0],
    [1, 0, 1],
    [1, 0, 2],
    [1, 1, 0],
    [1, 1, 1],
    [1, 1, 2],
    [1, 2, 0],
    [1, 2, 1],
    [1, 2, 2],
    [1, 2, 3]]]), values=array([[ 5, 10,  5, 10, 20,  0,  1,  2,  2,  1,  0,  0,  1,  2,  3]]), dense_shape=array([[2, 3, 4]]))

Который, кажется, SparseTensor где index=[sentence, word, letter]

Другие вопросы по тегам