semantic segmentation with tensorflow - ValueError in loss function (sparse-softmax)
Asked Answered
C

1

7

So, I'm working on a building a fully convolutional network (FCN), based off of Marvin Teichmann's tensorflow-fcn

My input image data, for the time being is a 750x750x3 RGB image. After running through the network, I use logits of shape [batch_size, 750,750,2] for my loss calculation.

It is a binary classification - I have 2 classes here, [0, 1] in my labels (of shape [batch_sizex750x750]. And these go into the loss function, below:

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

These are shapes for the logits and labels after reshaping:

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

And here, it throws me a ValueError stating:

Shapes () and (562500,) are not compatible

Full traceback below:

  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

Suggestions? Is my implementation of the tf.add_to_collection('losses', cross_entropy) wrong?

UPDATE:

I tried to run this without the summing across pixels (or so I think), by returning cross_entropy in the above code directly, as the loss.

It seems to have worked. (It now throws a ValueError from the training optimizer function, stating: No gradients provided for any variable. Assuming this has more to do with my weight initialization and regularization than anything else.

UPDATE 2:

The above (regarding ValueError due to absence of gradients) was trivial. As mentioned here, this message is usually encountered when there is no path between any of the tf.Variable objects defined and the loss tensor that that is being minimized.

The initial problem with usage of tf.add_n persists though. I'm assuming it has to do with the mechanics of how Graph collections work in TensorFlow. Having initialized my variables, the error now reads:

Shapes () and (?,) are not compatible
Caffrey answered 23/7, 2016 at 22:19 Comment(2)
Hi, murushiv, would you mind sharing more on how do you define logits of shape [batch_size, 750,750,2] ?Regine
@Regine logits (unsure of my terminology here) of the batch size you mention, I extract from the model (the build method). Anything specific you want to know?Caffrey
C
3

Closing. Turns out the code in the loss function was missing a mean summation. For anyone else facing this problem, modify the loss function as below, and it should work fine.

    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 
Caffrey answered 24/7, 2016 at 2:4 Comment(2)
@OlivierMoindrot will do, once I'm allowed to.Caffrey
When implementing the loss function, the result is nan. What's the reason resulting it? ThanksCadmium

© 2022 - 2024 — McMap. All rights reserved.