在 tf keras 中屏蔽语义分割的损失函数

Mask the Loss function for segmantic segmentation in tf keras

我有大小为 (256,256) 的图像,被分割成 10 class 个(09)。 我想在此数据集上训练一个语义分割网络,但只想将其视为 9 class 问题(即忽略 class 2)。

我的问题是是否有类似掩码的东西我可以解析未评估损失的地方。

我目前的做法是: 我是在one hot encoding之前修改图片的对应区域,即:


# change any pixel with value 2 to 255
target = tf.where(target==2,tf.constant(255,shape=(256, 256), dtype=tf.uint8),target) 

# change 3 -> 2, 4 -> 3, ..., 9 -> 8    
for i in range(3,10):
    target = tf.where(target==i,tf.constant(i-1,shape=(256, 256), dtype=tf.uint8),target)

# do one hot
out = tf.one_hot(target,9)

并训练一个具有 9 class 输出的网络。曾经具有值 2 的所有像素 被一次性编码为 [0,0,0,0,0,0,0,0,0],不应计入损失函数 (categorical_crossentropy)。无论如何,我不确定这是否会在我们除以像素数(常数 256^2)时产生问题,并且如果图像的大部分被零向量标记,这会减少其他标签的影响。

我正在使用 tf.kerasTensorflow 2.0

我认为你可以使用权重向量来实现你在这里需要的东西。

# Creating a random vector of targets of size (128)
target = tf.constant(np.random.randint(0,10, size=128).astype(np.int32))
# Create weights of size (128) and reshape to (128,1)
weights = tf.cast(tf.not_equal(target, 2), tf.float32)[:,tf.newaxis]

# do one hot and multiply by weights
out = tf.one_hot(target,9) * weights

话虽如此,这是为了获得一个零向量。但是忽略这些像素的标准方法是将实际的交叉熵损失乘以权重而不是单热向量。

out = tf.one_hot(target,9)
# pred is the predictions made
loss = tf.keras.losses.CategoricalCrossentropy()(out, pred) * weights

这将使损失忽略值为 2 的像素。