我正在处理一个语义分割问题,在这个问题中,我关心的两个类别(除了背景)在图像像素上是相当不平衡的。由于训练掩码的编码方式,我实际上使用稀疏分类交叉熵作为损失函数。是否有任何版本的稀疏分类交叉熵可以考虑类别权重?我没有找到它,甚至原始的稀疏分类交叉熵源代码也没有。我以前从未探索过tf源代码,但是从API页面链接到源代码的链接似乎并没有链接到损失函数的实际实现。
我正在处理一个语义分割问题,在这个问题中,我关心的两个类别(除了背景)在图像像素上是相当不平衡的。由于训练掩码的编码方式,我实际上使用稀疏分类交叉熵作为损失函数。是否有任何版本的稀疏分类交叉熵可以考虑类别权重?我没有找到它,甚至原始的稀疏分类交叉熵源代码也没有。我以前从未探索过tf源代码,但是从API页面链接到源代码的链接似乎并没有链接到损失函数的实际实现。
def add_sample_weights(image, label):
# The weights for each class, with the constraint that:
# sum(class_weights) == 1.0
class_weights = tf.constant([2.0, 2.0, 1.0])
class_weights = class_weights/tf.reduce_sum(class_weights)
# Create an image of `sample_weights` by using the label at each pixel as an
# index into the `class weights` .
sample_weights = tf.gather(class_weights, indices=tf.cast(label, tf.int32))
return image, label, sample_weights
train_dataset.map(add_sample_weights).element_spec
然后他们只需使用tf.keras.losses.SparseCategoricalCrossentropy
作为损失函数,并像这样进行拟合:
weighted_model.fit(
train_dataset.map(add_sample_weights),
epochs=1,
steps_per_epoch=10)
看起来 Keras 稀疏分类交叉熵不支持类别权重。我找到了 this 适用于 Keras 的稀疏分类交叉熵损失函数实现,对我来说很有效。链接中的实现存在一些小问题,可能是由于某些版本不兼容,所以我已经修复了它。
import tensorflow as tf
from tensorflow import keras
class WeightedSCCE(keras.losses.Loss):
def __init__(self, class_weight, from_logits=False, name='weighted_scce'):
if class_weight is None or all(v == 1. for v in class_weight):
self.class_weight = None
else:
self.class_weight = tf.convert_to_tensor(class_weight,
dtype=tf.float32)
self.name = name
self.reduction = keras.losses.Reduction.NONE
self.unreduced_scce = keras.losses.SparseCategoricalCrossentropy(
from_logits=from_logits, name=name,
reduction=self.reduction)
def __call__(self, y_true, y_pred, sample_weight=None):
loss = self.unreduced_scce(y_true, y_pred, sample_weight)
if self.class_weight is not None:
weight_mask = tf.gather(self.class_weight, y_true)
loss = tf.math.multiply(loss, weight_mask)
return loss
应该通过将权重列表或数组作为参数来调用损失。
class_weight不支持3维以上的目标。
- Vittoweighted_sparse_categorical_crossentropy
损失函数(链接:https://github.com/tensorflow/models/blob/master/official/nlp/modeling/losses/weighted_sparse_categorical_crossentropy.py)。然而,它不起作用。```tf.keras```期望标签为整数值,而不是分割掩码。无论如何,我只是在希望有一天能得到这个问题的答案,因为我也急需这个用于语义分割的损失函数。 - Manuel Popp