如何有条件地为张量分配值[用于损失函数的屏蔽]?

7
我想创建一个 L2 损失函数,它忽略标签值为 0 的值(=> 像素)。张量 batch[1] 包含标签,而 output 是网络输出的张量,两者都具有形状 (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)

我的当前代码会出现 TypeError: 'Tensor' object does not support item assignment 错误(在第二行)。使用tensorflow该怎么做呢?我还试图使用 tf.reduce_sum(labels_mask) 对损失进行归一化,希望它能像这样工作。

2个回答

6
这是一个示例,演示如何使用布尔索引并有条件地将值分配给变量:
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))

输出:

[   0,    0, 1500, 1500,    1, 1500, 1500,    0]

2
当尝试与急切张量一起使用时,我收到AttributeError:'EagerTensor'对象没有属性'_lazy_read',有没有办法在急切张量中使用它? - thebeancounter
这个 indexes = tf.where(mask) 行有什么作用吗? - Rodrigo Laguna

4
如果你想以这种方式编写它,你需要使用Tensorflow的scatter方法进行赋值。不幸的是,tensorflow也不真正支持布尔索引(新的boolean_select使其成为可能,但很烦人)。这将很棘手且难以阅读。
您有两个选项,它们都不那么麻烦:
  1. 使用labels_mask > 0作为布尔掩码,并使用Tensorflow的最近的boolean_mask函数。也许这是更Tensorflow的方式,因为它调用任意特定的函数。
  2. labels_mask > 0转换为浮点数:tf.cast(labels_mask > 0, tf.float32)。然后,您可以像在代码的最后一行中所希望的那样使用它。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接