使用 tensorflow 进行语义分割 - 损失函数中的 ValueError (sparse-softmax)

Posted

技术标签:

【中文标题】使用 tensorflow 进行语义分割 - 损失函数中的 ValueError (sparse-softmax)【英文标题】:semantic segmentation with tensorflow - ValueError in loss function (sparse-softmax) 【发布时间】:2016-11-27 13:33:33 【问题描述】:

所以,我正在基于Marvin Teichmann's tensorflow-fcn 构建一个完全卷积网络 (FCN)

我的输入图像数据,暂时是750x750x3 RGB图像。 通过网络运行后,我使用形状为 [batch_size, 750,750,2] 的 logits 进行损失计算。

这是一个二元分类 - 我在这里有 2 个类别,[0, 1] 在我的标签中(形状为 [batch_sizex750x750]。这些进入损失函数,如下所示:

def loss(logits, labels, num_classes):
with tf.name_scope('loss mine'):
    logits = tf.to_float(tf.reshape(logits, [-1, num_classes]))

    #CHANGE labels type to int, for sparse_softmax...
    labels = tf.to_int64(tf.reshape(labels, [-1]))

    print ('shape of logits: %s' % str(logits.get_shape()))
    print ('shape of labels: %s' % str(labels.get_shape()))

    cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(logits, labels, name='Cross_Entropy')
    tf.add_to_collection('losses', cross_entropy)

    loss = tf.add_n(tf.get_collection('losses'), name='total_loss')
return loss

这些是重塑后的 logits 和标签的形状:

shape of logits: (562500, 2)
shape of labels: (562500,)

在这里,它向我抛出一个 ValueError 声明:

Shapes () and (562500,) are not compatible

完整的追溯如下:

  File "train.py", line 89, in <module>
loss_train = loss.loss(logits, data.train.labels, 2)
File "/tensorflow-fcn/loss.py", line 86, in loss
loss = tf.add_n(tf.get_collection('losses'), name='total_loss')
File "/tensorflow/lib/python2.7/site-packages/tensorflow/python/ops/gen_math_ops.py", line 88, in add_n
result = _op_def_lib.apply_op("AddN", inputs=inputs, name=name)
File "/tensorflow/lib/python2.7/site-packages/tensorflow/python/ops/op_def_library.py", line 704, in apply_op
op_def=op_def)
File "/tensorflow/lib/python2.7/site-packages/tensorflow/python/framework/ops.py", line 2262, in create_op
set_shapes_for_outputs(ret)
File "/tensorflow/lib/python2.7/site-packages/tensorflow/python/framework/ops.py", line 1702, in      set_shapes_for_outputs
shapes = shape_func(op)
File "/tensorflow/lib/python2.7/site-packages/tensorflow/python/ops/math_ops.py", line 1557, in _AddNShape
merged_shape = merged_shape.merge_with(input_.get_shape())
File "/tensorflow/lib/python2.7/site-packages/tensorflow/python/framework/tensor_shape.py", line 570, in merge_with
(self, other))
ValueError: Shapes () and (562500,) are not compatible

建议?我对tf.add_to_collection('losses', cross_entropy) 的执行是否错误?

更新:

我试图在没有像素求和的情况下运行它(或者我认为是这样),直接在上面的代码中返回cross_entropy,作为损失。

它似乎奏效了。 (它现在从训练优化器函数中抛出一个ValueError,声明:No gradients provided for any variable。 假设这与我的权重初始化和正则化有关。

更新 2:

以上(关于 ValueError 由于没有梯度)是微不足道的。正如here 所述,当定义的任何 tf.Variable 对象与被最小化的损失张量之间没有路径时,通常会遇到此消息。

尽管使用tf.add_n 的最初问题仍然存在。我假设它与 TensorFlow 中 Graph 集合的工作机制有关。初始化我的变量后,错误现在显示为:

Shapes () and (?,) are not compatible

【问题讨论】:

嗨,murushiv,您是否介意分享更多关于如何定义形状 [batch_size, 750,750,2] 的 logits 的信息? @user288609 logits(不确定我的术语)你提到的批量大小,我从模型中提取(构建方法)。有什么具体想知道的吗? 【参考方案1】:

关闭。原来损失函数中的代码缺少平均求和。对于遇到此问题的其他人,请按如下方式修改损失函数,它应该可以正常工作。

    cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(logits, labels, name='Cross_Entropy')
    cross_entropy_mean = tf.reduce_mean(cross_entropy, name='xentropy_mean')
    tf.add_to_collection('losses', cross_entropy_mean)

    loss = tf.add_n(tf.get_collection('losses'), name='total_loss')
return loss 

【讨论】:

@OlivierMoindrot 会做,一旦我被允许。 实现损失函数时,结果为nan。造成它的原因是什么?谢谢

以上是关于使用 tensorflow 进行语义分割 - 损失函数中的 ValueError (sparse-softmax)的主要内容,如果未能解决你的问题,请参考以下文章

语义分割 Keras 的交叉熵损失

为啥训练多类语义分割的unet模型中的分类交叉熵损失函数非常高?

语义分割之车道线检测Lanenet(tensorflow版)

训练和验证模式 tensorflow 的 SAME 数据丢失不一致

语义分割损失函数

语义分割损失函数