Преобразование графика Tensorflow для использования оценщика, получение «TypeError: тип данных не понят» в функции потерь с использованием «sampled_softmax_loss» или «nce_loss»

Я пытаюсь преобразовать официальную базовую реализацию word2vec Tensorflow для использования tf.Estimator. Проблема в том, что функция потерь (sampled_softmax_loss или nce_loss) выдает ошибку при использовании оценщиков тензорного потока. В исходной реализации он отлично работает.

Вот официальная базовая реализация word2vec от Tensorflow:

https://github.com/tensorflow/tensorflow/blob/master/tensorflow/examples/tutorials/word2vec/word2vec_basic.py

Вот блокнот Google Colab, в котором я реализовал этот код, который работает.

https://colab.research.google.com/drive/1nTX77dRBHmXx6PEF5PEF5

Вот блокнот Google Colab, в котором я изменил код, чтобы он использовал Tensorflow Estimator, который не работает.

И вот здесь я называю оценщик и обучение

word2vecEstimator = tf.estimator.Estimator(
        model_fn=my_model,
        params={
            'batch_size': 16,
            'embedding_size': 10,
            'num_inputs': 3,
            'num_sampled': 128,
            'batch_size': 16
        })

word2vecEstimator.train(
    input_fn=generate_batch,
    steps=10)

И это сообщение об ошибке, которое я получаю, когда вызываю обучение оценщика:

INFO:tensorflow:Calling model_fn.
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-22-955f44867ee5> in <module>()
      1 word2vecEstimator.train(
      2     input_fn=generate_batch,
----> 3     steps=10)

/usr/local/lib/python3.6/dist-packages/tensorflow/python/estimator/estimator.py in train(self, input_fn, hooks, steps, max_steps, saving_listeners)
    352 
    353       saving_listeners = _check_listeners_type(saving_listeners)
--> 354       loss = self._train_model(input_fn, hooks, saving_listeners)
    355       logging.info('Loss for final step: %s.', loss)
    356       return self

/usr/local/lib/python3.6/dist-packages/tensorflow/python/estimator/estimator.py in _train_model(self, input_fn, hooks, saving_listeners)
   1205       return self._train_model_distributed(input_fn, hooks, saving_listeners)
   1206     else:
-> 1207       return self._train_model_default(input_fn, hooks, saving_listeners)
   1208 
   1209   def _train_model_default(self, input_fn, hooks, saving_listeners):

/usr/local/lib/python3.6/dist-packages/tensorflow/python/estimator/estimator.py in _train_model_default(self, input_fn, hooks, saving_listeners)
   1235       worker_hooks.extend(input_hooks)
   1236       estimator_spec = self._call_model_fn(
-> 1237           features, labels, model_fn_lib.ModeKeys.TRAIN, self.config)
   1238       global_step_tensor = training_util.get_global_step(g)
   1239       return self._train_with_estimator_spec(estimator_spec, worker_hooks,

/usr/local/lib/python3.6/dist-packages/tensorflow/python/estimator/estimator.py in _call_model_fn(self, features, labels, mode, config)
   1193 
   1194     logging.info('Calling model_fn.')
-> 1195     model_fn_results = self._model_fn(features=features, **kwargs)
   1196     logging.info('Done calling model_fn.')
   1197 

<ipython-input-20-9d389437162a> in my_model(features, labels, mode, params)
     33                 inputs=embed,
     34                 num_sampled=num_sampled,
---> 35                 num_classes=vocabulary_size))
     36 
     37     # Add the loss value as a scalar to summary.

/usr/local/lib/python3.6/dist-packages/tensorflow/python/ops/nn_impl.py in nce_loss(weights, biases, labels, inputs, num_sampled, num_classes, num_true, sampled_values, remove_accidental_hits, partition_strategy, name)
   1246       remove_accidental_hits=remove_accidental_hits,
   1247       partition_strategy=partition_strategy,
-> 1248       name=name)
   1249   sampled_losses = sigmoid_cross_entropy_with_logits(
   1250       labels=labels, logits=logits, name="sampled_losses")

/usr/local/lib/python3.6/dist-packages/tensorflow/python/ops/nn_impl.py in _compute_sampled_logits(weights, biases, labels, inputs, num_sampled, num_classes, num_true, sampled_values, subtract_log_q, remove_accidental_hits, partition_strategy, name, seed)
   1029   with ops.name_scope(name, "compute_sampled_logits",
   1030                       weights + [biases, inputs, labels]):
-> 1031     if labels.dtype != dtypes.int64:
   1032       labels = math_ops.cast(labels, dtypes.int64)
   1033     labels_flat = array_ops.reshape(labels, [-1])

TypeError: data type not understood

Изменить: по запросу вот как выглядит типичный вывод для input_fn

print(generate_batch(batch_size=8, num_skips=2, skip_window=1))

(array([3081, 3081,   12,   12,    6,    6,  195,  195], dtype=int32), array([[5234],
       [  12],
       [   6],
       [3081],
       [  12],
       [ 195],
       [   6],
       [   2]], dtype=int32))

person SantoshGupta7    schedule 21.11.2018    source источник
comment
Какие версии Python, TensorFlow и NumPy вы используете? Если они не обновлены (TensorFlow 1.12, NumPy 1.15), вы пробовали обновиться?   -  person jdehesa    schedule 27.11.2018
comment
Для Tensorflow версия 1.12.0; Для Numpy версия 1.14.6   -  person SantoshGupta7    schedule 29.11.2018


Ответы (3)


Вы используете generate_batch как переменную здесь:

word2vecEstimator.train(
    input_fn=generate_batch,
    steps=10)

Вызовите функцию с generate_batch(). Но я думаю, вы должны передать функции некоторые значения.

person tifi90    schedule 29.11.2018
comment
Я настроил его так, чтобы функции не передавались никакие значения. Я использовал generate_batch(), но теперь получаю TypeError: unsupported callable ошибку. В официальной документации говорится, что нужно относиться к нему как к функции, поэтому он должен называться как generate_batch. tensorflow.org/guide/estimators. Это подробно описано в этом сообщении stackoverflow.com/questions/47120637/ - person SantoshGupta7; 29.11.2018
comment
Вы можете показать нам результат вызова generate_batch()? - person tifi90; 30.11.2018
comment
да, только что обновил исходный пост, вывод generate_batch() call внизу. - person SantoshGupta7; 30.11.2018
comment
Размер массива функций и массива меток различается. Длина 16 и длина 15. Разве они не должны быть одинакового размера? - person tifi90; 30.11.2018
comment
Им обоим по 16 лет, я думаю, это немного сбивает с толку, поскольку метки начинаются на той же строке, что и заканчиваются функции. `[1892528, 1352240, 1552349]], dtype = int32), array ([[1635226],`, 1635226 является частью 2-го массива. - person SantoshGupta7; 01.12.2018

Возможно, тензоры и операции должны быть в input_fn, а не в 'model_fn'

Я обнаружил эту проблему №4026, которая решила мою проблему ... Может быть, я просто дурак, но было бы здорово, если бы вы упомянули, что все тензоры и операции должны находиться внутри input_fn где-нибудь в документации.

Вы должны вызвать read_batch_examples откуда-то из input_fn, чтобы создаваемые им тензоры находились на графике, который Оценщик создает в fit ().

https://github.com/tensorflow/tensorflow/issues/8042

О, я чувствую себя идиотом! Я создавал операцию за пределами графика. Теперь это работает, не могу поверить, что не подумал попробовать это. Большое спасибо! Это не проблема, и она решена

https://github.com/tensorflow/tensorflow/issues/4026

Однако по-прежнему недостаточно информации о том, что вызывает проблему. Это просто зацепка.

person SantoshGupta7    schedule 03.12.2018

Нашел ответ

Ошибка явно говорит о том, что у вас недопустимый тип этикеток.

Вы пытаетесь передать массив numpy вместо Tensor. Иногда Tensorflow выполняет неявное преобразование из ndarray в Tensor под капотом (почему ваш код работает вне Оценщика), но в данном случае это не так.

.

Нет, официальная имп. подает данные из заполнителя. Заполнитель всегда является тензорным, поэтому он не зависит от неявных вещей.

Но если вы напрямую вызываете функцию потерь с массивом numpy в качестве входных данных (Примечание: вызов на этапе построения графика, поэтому содержимое аргумента встроено в график), она МОЖЕТ работать (однако я не проверял это).

Этот код:

nce_loss (labels = [1,2,3]) будет вызываться только ОДИН РАЗ во время построения графа. Ярлыки будут статически встроены в граф как константа и потенциально могут иметь любой совместимый с Tensor тип (список, ndarray и т. Д.).

Этот код: `` Модель Python def (label_input): nce_loss (labels = label_input)

Estimator (model_fun = model) .train () `` не может вставлять переменную меток статически, потому что ее содержимое не определяется во время построения графика. Поэтому, если вы скармливаете что-нибудь, кроме Tensor, он выдаст ошибку.

Из

https://www.reddit.com/r/MachineLearning/comments/a39pef/r_tensorflow_estimators_managing_simplicity_vs/

Я использовал labels=tf.dtypes.cast( train_labels, tf.int64), и это сработало

person SantoshGupta7    schedule 06.12.2018