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
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
3条答案
按热度按时间z8dt9xmd1#
据我所知,你可以在www.example.com中使用类权重model.fit计算任何损失函数。我已经用它来计算categorical_cross_entropy,它是有效的。它只是用类权重来衡量损失,所以我认为没有理由不使用sparse_categorical_cross_entropy。
1szpjjfi2#
我认为this是在Keras中为
sparse_categorical_crossentropy
加权的解决方案。他们使用以下方法向数据集添加“第二个掩码”(包含掩码图像的每个类的权重)。然后,他们只使用
tf.keras.losses.SparseCategoricalCrossentropy
作为损失函数,拟合如下:osh3o9ms3#
看起来Keras稀疏分类交叉熵不适用于类权重。我已经找到了Keras稀疏分类交叉熵损失的this实现,它对我有效。链接中的实现有一个小bug,可能是由于一些版本不兼容,所以我已经修复了它。
损失应通过将权重列表或数组作为参数来调用。