Reputation: 5278
I want to create a L2 loss function that ignores values (=> pixels) where the label has the value 0. The tensor batch[1]
contains the labels while output
is a tensor for the net output, both have a shape of (None,300,300,1)
.
labels_mask = tf.identity(batch[1])
labels_mask[labels_mask > 0] = 1
loss = tf.reduce_sum(tf.square((output-batch[1])*labels_mask))/tf.reduce_sum(labels_mask)
My current code yields to TypeError: 'Tensor' object does not support item assignment
(on the second line). What's the tensorflow-way to do this? I also tried to normalize the loss with tf.reduce_sum(labels_mask)
, which I hope works like this.
Upvotes: 7
Views: 5182
Reputation: 671
update Ivan Talalaev's answer for TensorFlow v.2.x (use tensor_scatter_nd_update
instead of scatter_update
and use indexes
instead of mask
a = tf.Variable(initial_value=[0, 0, 4, 6, 1, 2, 4, 0])
mask = tf.greater_equal(a, 2) # [False False True True False True True False]
indexes = tf.where(mask) # [[2] [3] [5] [6]], shape=(4, 1)
b = tf.tensor_scatter_nd_update(a, indexes, 1500*np.ones(indexes.shape[0]))
Upvotes: 0
Reputation: 6534
Here is an example how to apply boolean indexing and conditionally assign values to Variable:
a = tf.Variable(initial_value=[0, 0, 4, 6, 1, 2, 4, 0])
mask = tf.greater_equal(a, 2) # [False False True True False True True False]
indexes = tf.where(mask) # [[2] [3] [5] [6]], shape=(4, 1)
b = tf.scatter_update(a, mask, tf.constant(1500))
output:
[ 0, 0, 1500, 1500, 1, 1500, 1500, 0]
Upvotes: 6
Reputation: 494
If you wanted to write it that way, you would have to use Tensorflow's scatter
method for assignment. Unfortunately, tensorflow doesn't really support boolean indexing either (the new boolean_select
makes it possible, but annoying). It would be tricky to write and difficult to read.
You have two options that are less annoying:
labels_mask > 0
as a boolean mask and use Tensorflow's recent boolean_mask function. Maybe this is the more tensorflow way, because it invokes arbitrarily specific functions.labels_mask > 0
to float: tf.cast(labels_mask > 0, tf.float32)
. Then, you can use it the way you wanted to in the final line of your code.Upvotes: 4