使用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个类)。
答案 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