【问题标题】:Converting Tensorflow Graph to use Estimator, get 'TypeError: data type not understood' at loss function using `sampled_softmax_loss` or `nce_loss`将 TensorFlow Graph 转换为使用 Estimator,使用 `sampled_softmax_loss` 或 `nce_loss` 在损失函数中获取“TypeError:数据类型不理解”
【发布时间】:2018-11-21 05:17:25
【问题描述】:

我正在尝试将 Tensorflow 的官方基本 word2vec 实现转换为使用 tf.Estimator。 问题是损失函数(sampled_softmax_lossnce_loss)在使用 TensorFlow Estimators 时会出错。它在原始实现中运行良好。

这是 Tensorflow 的官方基本 word2vec 实现:

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

这是我实现此代码的 Google Colab 笔记本,它正在运行。

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

这是 Google Colab 笔记本,我在其中更改了代码,使其使用无法正常工作的 Tensorflow Estimator。

https://colab.research.google.com/drive/1IVDqGwMx6BK5-Bgrw190jqHU6tt3ZR3e

为方便起见,这里是我在上面定义 model_fn 的 Estimator 版本的确切代码

batch_size = 128
embedding_size = 128  # Dimension of the embedding vector.
skip_window = 1  # How many words to consider left and right.
num_skips = 2  # How many times to reuse an input to generate a label.
num_sampled = 64  # Number of negative examples to sample.

def my_model( features, labels, mode, params):

    with tf.name_scope('inputs'):
        train_inputs = features
        train_labels = labels

    with tf.name_scope('embeddings'):
        embeddings = tf.Variable(
          tf.random_uniform([vocabulary_size, embedding_size], -1.0, 1.0))
        embed = tf.nn.embedding_lookup(embeddings, train_inputs)

    with tf.name_scope('weights'):
        nce_weights = tf.Variable(
          tf.truncated_normal(
              [vocabulary_size, embedding_size],
              stddev=1.0 / math.sqrt(embedding_size)))
    with tf.name_scope('biases'):
        nce_biases = tf.Variable(tf.zeros([vocabulary_size]))

    with tf.name_scope('loss'):
        loss = tf.reduce_mean(
            tf.nn.nce_loss(
                weights=nce_weights,
                biases=nce_biases,
                labels=train_labels,
                inputs=embed,
                num_sampled=num_sampled,
                num_classes=vocabulary_size))

    tf.summary.scalar('loss', loss)

    if mode == "train":
        with tf.name_scope('optimizer'):
            optimizer = tf.train.GradientDescentOptimizer(1.0).minimize(loss)

        return tf.estimator.EstimatorSpec(mode, loss=loss, train_op=optimizer)

这里是我称之为估计器和训练的地方

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)

这是我在调用 Estimator 培训时收到的错误消息:

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

【问题讨论】:

  • 您使用的是哪些 Python、TensorFlow 和 NumPy 版本?如果它们不是最新的(TensorFlow 1.12、NumPy 1.15),您是否尝试过升级?
  • 对于 Tensorflow ,版本 '1.12.0' ;对于 Numpy ,版本 '1.14.6'

标签: python tensorflow tensorflow-estimator


【解决方案1】:

你在这里像变量一样使用generate_batch

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

使用generate_batch() 调用函数。 但我认为你必须将一些值传递给函数。

【讨论】:

  • 我设置它,以便没有值传递给函数。我使用了generate_batch(),但现在我收到了TypeError: unsupported callable 错误。官方文档说要把它当作一个函数来对待,所以应该像generate_batch一样调用它。 tensorflow.org/guide/estimators 。这在这篇文章stackoverflow.com/questions/47120637/… 中有详细说明
  • 你能告诉我们generate_batch()调用的输出吗?
  • 是的,刚刚更新了原帖,generate_batch() call 的输出在底部。
  • 特征数组和标签数组的大小不同。长度16和长度15。它们不应该有相同的尺寸吗?
  • 他们都是 16 岁,我认为这有点令人困惑,因为标签开始与特征结束在同一行。 ` [1892528, 1352240, 1552349]], dtype=int32), array([[1635226],`, 1635226 是第二个数组的一部分。
【解决方案2】:

可能张量和操作必须在input_fn 中,而不是在'model_fn'中

我发现这个问题 #4026 解决了我的问题......也许只是我很愚蠢,但如果你提到张量和操作都必须在文档的某个地方的 input_fn 内,那就太好了。

您必须从 input_fn 内部的某个位置调用 read_batch_examples,以便它创建的张量在 Estimator 在 fit() 中创建的图中。

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

哦,我觉得自己像个白痴!我一直在图形范围之外创建操作。它现在有效,不敢相信我没想过要尝试。非常感谢!这不是问题,已解决

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

但是,关于导致问题的原因仍然没有足够的信息。这只是一个线索。

【讨论】:

    【解决方案3】:

    找到答案

    错误清楚地表明您的标签类型无效。

    您试图传递 numpy 数组而不是 Tensor。有时张量流 在后台执行从 ndarray 到 Tensor 的隐式转换 (这就是您的代码在 Estimator 之外工作的原因),但在这种情况下 不要。

    .

    不,官方表示。从占位符提供数据。占位符是 总是一个张量,所以它不依赖于隐含的东西。

    但是如果你直接用一个numpy数组作为输入调用损失函数 (注意:在图构建阶段调用,所以参数内容 嵌入到图表中),它可以工作(但是,我没有检查它)。

    这段代码:

    nce_loss(labels=[1,2,3]) 在图表期间只会被调用一次 建造。标签将作为静态嵌入到图形中 常量并且可能是任何与张量兼容的类型(列表, ndarray 等)

    这段代码:```Python def model(label_input): nce_loss(labels=label_input)

    estimator(model_fun=model).train() ``` 不能嵌入标签变量 静态的,因为它的内容在图表期间没有定义 建造。所以如果你喂除了张量之外的任何东西,它会抛出 一个错误。

    来自

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

    所以我使用了labels=tf.dtypes.cast( train_labels, tf.int64),它成功了

    【讨论】:

      猜你喜欢
      • 2018-03-14
      • 1970-01-01
      • 2020-08-12
      • 1970-01-01
      • 2019-03-06
      • 2017-03-26
      • 2019-02-08
      • 1970-01-01
      • 2020-06-16
      相关资源
      最近更新 更多