【问题标题】:InvalidArgumentError: logits and labels must have the same first dimension seq2seq TensorflowInvalidArgumentError:logits 和标签必须具有相同的第一维 seq2seq Tensorflow
【发布时间】:2017-12-18 18:13:57
【问题描述】:

我在 seq2seq.sequence_loss 中收到此错误,即使 logits 和标签的第一个暗淡具有相同的维度,即 batchSize

我在 TF 1.0 版本中创建了一个 seq2seq 模型。我的损失函数如下:

    logits  = self.decoder_logits_train
    targets = self.decoder_train_targets
    self.loss     = seq2seq.sequence_loss(logits=logits, targets=targets, weights=self.loss_weights)
    self.train_op = tf.train.AdamOptimizer().minimize(self.loss)

我在训练时运行网络时遇到以下错误:

InvalidArgumentError (see above for traceback): logits and labels must have the same first dimension, got logits shape [1280,150000] and labels shape [1536]
     [[Node: sequence_loss/SparseSoftmaxCrossEntropyWithLogits/SparseSoftmaxCrossEntropyWithLogits = SparseSoftmaxCrossEntropyWithLogits[T=DT_FLOAT, Tlabels=DT_INT32, _device="/job:localhost/replica:0/task:0/cpu:0"](sequence_loss/Reshape, sequence_loss/Reshape_1)]]

我确认logitstargets张量的形状如下:

a,b = sess.run([model.decoder_logits_train, model.decoder_train_targets], feed_dict)
print(np.shape(a)) # (128, 10, 150000) which is (BatchSize, MaxSeqSize, Vocabsize)
print(np.shape(b)) # (128, 12) which is (BatchSize, Max length of seq including padding)

那么,既然targetslogits 的第一个维度相同,那么为什么会出现此错误?

有趣的是,在错误中你可以观察到 logits 的维度被提到为(1280, 150000),即(128 * 10, 150000)[product of first two dimension, vocab_size],目标相同,即(1536),即(128*12),又是第一个产品二维?

注意:Tensorflow 1.0 CPU 版本

【问题讨论】:

    标签: python-3.x tensorflow deep-learning


    【解决方案1】:

    错误消息似乎有点误导,因为您实际上需要第一维和第二维相同。这是写here

    logits:形状为 [batch_size, sequence_length, num_decoder_symbols] 和 dtype 浮点数。 logits 对应于 在每个时间步跨所有类进行预测。

    targets:形状为 [batch_size, sequence_length] 和 dtype 的张量 诠释。目标代表每个时间步的真实类。

    这也是有道理的,因为logits 是概率向量,而targets 代表实际输出,因此它们需要具有相同的长度。

    【讨论】:

    • 我的 logits 和目标的形状相同,但从损失函数中得到错误。我的 logits 的形状为 (128,10,150000) ,但错误消息将形状提到为 (1280,150000),即它使第一维和第二维变平,因此出现错误。
    • 你不是说目标的形状是 (128, 12) 吗?
    • 是的,目标的形状是 (128,12),因为它们也有填充。代码链接:github.com/adakum/seq2seq/blob/philly_compatible/…
    • 根据文档,logits 和 target 不能有不同的第二维。它们都需要等于 sequence_length。在您的情况下,其中一个是 10,另一个是 12。
    • 是的,我认为这就是我遇到此错误的问题。我的解码器输入尺寸为(128,12),但 decoder_rnn 仅展开 10 次。 :/ 你有什么想法吗?
    【解决方案2】:

    也许你填充错误的方式。如果你将 _EOS 填充到目标序列的末尾,那么 max_length(目标句子的实际长度)应该加 1 为 [batch, max_len+1]。由于您填充了 _GO 和 _EOS,因此您的目标句子长度应加 2,即等于 12。

    我阅读了一些其他人的 NMT 实现,他们只填充 _EOS 用于目标语句,而 _GO 用于解码器的输入。告诉我我是否错了。

    【讨论】:

      【解决方案3】:

      我遇到了和你一样的错误,我理解了这个问题:

      问题:

      您使用以下参数运行解码器:

      • targets 是解码器输入。由于填充,它们的长度为max_length。形状:[batch_size, max_length]
      • sequence_length 是当前批次的所有目标的非填充长度。形状:[batch_size]

      您的 logits,即输出 tf.contrib.seq2seq.dynamic_decode 具有形状:

      [batch_size, longer_sequence_in_this_batch, n_classes]

      其中longer_sequence_in_this_batch 等于tf.reduce_max(sequence_length)

      因此,您在计算损失时遇到了问题,因为您尝试同时使用两者:

      • 您的第一维形状longer_sequence_in_this_batch的logits
      • 您的目标具有一维形状max_length

      注意longer_sequence_in_this_batch max_length

      如何解决:

      您可以简单地对您的 logits 应用一些填充。

      logits  = self.decoder_logits_train
      targets = self.decoder_train_targets
      
      paddings = [[0, 0], [0, max_length-tf.shape(logits)[1]], [0, 0]]
      padded_logits = tf.pad(logits, paddings, 'CONSTANT', constant_values=0)
      
      
      self.loss = seq2seq.sequence_loss(logits=padded_logits, targets=targets, 
                                        weights=self.loss_weights)
      

      使用此方法,您可以确保您的 logits 将被填充为目标,并且具有维度 [batch_size, max_length, n_classes]

      有关pad功能的更多信息,请访问 Tensorflow's documentation

      【讨论】:

        猜你喜欢
        • 2019-09-15
        • 2021-07-03
        • 2018-08-16
        • 2019-06-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-11-10
        • 2017-10-23
        相关资源
        最近更新 更多