如何在Keras中进行交叉熵损失的权重不平衡类?

时间:2017-09-30 15:48:36

标签: keras

使用Keras对高度不平衡的数据集进行图像分割,我想按照here所述的方法对每个类中像素值的比例重新加权。如果a具有weights = [0.8, 0.2]的二进制类,如何修改K.sparse_categorical_crossentropy(y_true, y_pred)以根据像素所属的类重新加权损失?

输入的形状为(4, 256, 256, 1)(批次,高度,宽度,通道),输出为0和1的矢量(4, 65536, 1)(正负类) 。模型和数据类似于here,不同之处在于图像是灰度的,而掩模是二进制的(2个类)。

3 个答案:

答案 0 :(得分:5)

这是我用于语义分段项目的自定义丢失函数。它是根据keras/backend/tensorflow_backend.py中的categorical_crossentropy函数修改的。

def class_weighted_pixelwise_crossentropy(target, output):
    output = tf.clip_by_value(output, 10e-8, 1.-10e-8)
    weights = [0.8, 0.2]
    return -tf.reduce_sum(target * weights * tf.log(output))

请注意,我的最终版本没有使用类权重 - 我发现它鼓励模型使用代表不足的类作为图像补丁的填充,而不是做出更真实​​的猜测,从而损害性能。

答案 1 :(得分:1)

Jessica的答案很干净而且效果很好。我通常推荐它。但是为了多样化: 我发现,对感兴趣的区域进行采样,包括在类之间具有更好的比率,是快速学习偏斜的像素级类的有效方法。

就我而言,我有两个像您一样的课程,这使事情变得更容易。我在图像中寻找外观较少代表的区域。我用一个随机偏移量围绕它裁剪一个恒定大小的边界框(我对每个图像重复多次该过程)。这会产生大量的小图像,每个图像的比率都相当相等。 我可能应该在此处添加,必须将网络设置为输入形状(无,无,num_chanals),然后才能在原始图像上工作。

由于您跳过了绝大多数像素(属于多数类),因此训练非常快,但并没有利用多数类的所有数据。

答案 2 :(得分:0)

在 tensorflow 2.x 中,model.fit 方法有一个 class_weight 参数来本地执行此操作,为每个类传递一个权重字典。 Documentation