我正在 keras 中进行语义分割,并尝试修改 categorical_crossentropy 损失,以便损失是类加权的。
这是我的代码:
def class_weighted_categorical_crossentropy(output, target, from_logits=False):
"""Categorical crossentropy between an output tensor and a target tensor.
parameter = TrainingParameters()
# create ones array with shape of target tensor
# multiply class weight array with inverse class_accuracies for each label
class_weights = tf.convert_to_tensor(parameter.class_weights, dtype=floatx())
# weight targets with class weights and create pattern with which loss can be multiplied
class_weights_pattern = tf.multiply(target, class_weights)
class_weights_pattern = tf.reduce_sum(class_weights_pattern, reduction_indices=len(class_weights_pattern.get_shape())-1)#, keep_dims=True)
if not from_logits:
# scale preds so that the class probas of each sample sum to 1
output /= tf.reduce_sum(output,
reduction_indices=len(output.get_shape()) - 1,
keep_dims=True)
# manual computation of crossentropy
epsilon = _to_tensor(_EPSILON, output.dtype.base_dtype)
output = tf.clip_by_value(output, epsilon, 1. - epsilon)
loss = - tf.reduce_sum(target * tf.log(output), reduction_indices=len(output.get_shape()) - 1)
return tf.multiply(loss, class_weights_pattern)
else:
loss = tf.nn.softmax_cross_entropy_with_logits(labels=target, logits=output)
return tf.multiply(loss, class_weights_pattern)
最后我只改变了损失乘以 class_weights 模式。class_weights_pattern 包含每个像素对应的类权重,因此应该对正常的 categorical_crossentropy 损失进行加权。但是,如果我用修改后的损失训练我的模型,结果比我只使用 keras categorical_crossentropy 损失要糟糕得多。即使我将所有类权重设置为 1,这样我的 class_weighted_categorical_crossentropy 损失应该与 keras 的 categorical_crossentropy 损失完全相同,结果更糟。我已经用一些示例图像打印了这两种损失,并且损失完全相同。
有谁能够帮我?为什么它不起作用?提前致谢!