我想使用类似U-Net的FCN来进行一些语义分割。我使用基于Tensorflow后端的Python和Keras进行了操作。现在我有了很好的结果,我正在试图改进它们,并且我认为改善我的损失计算是实现这样一件事情的一种方式。
我知道在我的输出中,多个类别存在不平衡的情况,使用默认的 categorical_crossentropy
函数可能会带来问题。
我的模型输入和输出都是float32格式的,输入是channel_first,输出是channel_last(模型末尾完成置换)
在二元案例中,当我只想分割一个类时,我已经按以下方式更改了损失函数,以便可以根据输出内容逐个添加权重:
def weighted_loss(y_true, y_pred):
def weighted_binary_cross_entropy(y_true, y_pred):
w = tf.reduce_sum(y_true)/tf_cast(tf_size(y_true), tf_float32)
real_th = 0.5-th
tf_th = tf.fill(tf.shape(y_pred), real_th)
tf_zeros = tf.fill(tf.shape(y_pred), 0.)
return (1.0 - w) * y_true * - tf.log(tf.maximum(tf.zeros, tf.sigmoid(y_pred) + tf_th)) +
(1- y_true) * w * -tf.log(1 - tf.maximum(tf_zeros, tf.sigmoid(y_pred) + tf_th))
return weighted_binary_coss_entropy
请注意,th是激活阈值,默认值为1/nClasses,我已更改它以查看哪个值可以给我最佳结果。你对此有何看法?如果在多类情况下能够计算加权分类交叉熵,那么怎么样修改呢?
softmax_cross_entropy_with_logits
函数,它包含激活阈值,默认情况下为 1/nClasses(我猜)。 - Fou