Tensorflow:如何在语义分割过程中忽略特定标签?

2024-03-28

我正在使用张量流进行语义分割。在计算像素损失时,如何告诉张量流忽略特定标签?

我读了在这篇文章中 https://stackoverflow.com/questions/39091432/tensorflow-softmax-ignore-negative-labels-just-like-caffe/39113607对于图像分类,可以将标签设置为-1并且它会被忽略。如果这是真的,给定标签张量,我如何修改我的标签,以便将某些值更改为-1?

在 Matlab 中它会是这样的:

ignore_label = 255
myLabelTensor(myLabelTensor == ignore_label) = -1

但我不知道在TF中如何做到这一点?

一些背景信息:
这是标签的加载方式:

label_contents = tf.read_file(input_queue[1])
label = tf.image.decode_png(label_contents, channels=1)

这是目前计算损失的方式:

raw_output = net.layers['fc1_voc12']
prediction = tf.reshape(raw_output, [-1, n_classes])
label_proc = prepare_label(label_batch, tf.pack(raw_output.get_shape()[1:3]),n_classes)
gt = tf.reshape(label_proc, [-1, n_classes])

# Pixel-wise softmax loss.
loss = tf.nn.softmax_cross_entropy_with_logits(prediction, gt)
reduced_loss = tf.reduce_mean(loss)

with

def prepare_label(input_batch, new_size, n_classes):
    """Resize masks and perform one-hot encoding.

    Args:
      input_batch: input tensor of shape [batch_size H W 1].
      new_size: a tensor with new height and width.

    Returns:
      Outputs a tensor of shape [batch_size h w 21]
      with last dimension comprised of 0's and 1's only.
    """
    with tf.name_scope('label_encode'):
        input_batch = tf.image.resize_nearest_neighbor(input_batch, new_size) # as labels are integer numbers, need to use NN interp.
        input_batch = tf.squeeze(input_batch, squeeze_dims=[3]) # reducing the channel dimension.
        input_batch = tf.one_hot(input_batch, depth=n_classes)
    return input_batch

我正在使用张量流-deeplab-resnet 模型 https://github.com/DrSleep/tensorflow-deeplab-resnet它将 Caffe 中实现的 Resnet 模型转移到张量流中,使用caffe-tensorflow https://github.com/ethereon/caffe-tensorflow.


根据文档,tf.nn.softmax_cross_entropy_with_logits https://www.tensorflow.org/api_docs/python/nn/classification#softmax_cross_entropy_with_logits必须使用有效的概率分布来调用labels,否则计算将不正确,并使用tf.nn.sparse_softmax_cross_entropy_with_logits https://www.tensorflow.org/api_docs/python/nn/classification#sparse_softmax_cross_entropy_with_logits(这在您的情况下可能更方便)带有负标签将导致错误或返回 NaN 值。我不会依赖它来忽略一些标签。

我要做的是将被忽略类的 logits 替换为那些像素中的无穷大,其中正确的类是被忽略的类,因此它们不会对损失产生任何影响:

ignore_label = ...
# Make zeros everywhere except for the ignored label
input_batch_ignored = tf.concat(input_batch.ndims - 1,
    [tf.zeros_like(input_batch[:, :, :, :ignore_label]),
     tf.expand_dims(input_batch[:, :, :, ignore_label], -1),
     tf.zeros_like(input_batch[:, :, :, ignore_label + 1:])])
# Make corresponding logits "infinity" (a big enough number)
predictions_fix = tf.select(input_batch_ignored > 0,
    1e30 * tf.ones_like(predictions), predictions)
# Compute loss with fixed logits
loss = tf.nn.softmax_cross_entropy_with_logits(prediction, gt)

唯一的问题是,您正在考虑被忽略类的像素总是被正确预测,这意味着包含大量此类像素的图像的损失将人为地变小。根据具体情况,这可能很重要,也可能不重要,但如果你想真正准确,你必须根据未忽略的像素数量对每个图像的损失进行加权,而不是仅仅取平均值。

# Count relevant pixels on each image
input_batch_relevant = 1 - input_batch_ignored
input_batch_weight = tf.reduce_sum(input_batch_relevant, [1, 2, 3])
# Compute relative weights
input_batch_weight = input_batch_weight / tf.reduce_sum(input_batch_weight)
# Compute reduced loss according to weights
reduced_loss = tf.reduce_sum(loss * input_batch_weight)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Tensorflow:如何在语义分割过程中忽略特定标签? 的相关文章

随机推荐