我实际上正在与Keras进行图像分割项目。
我正在使用Unet的实现。 我有2个按像素值标识的类,0 =背景1 =我要寻找的对象。
我有一个具有S型激活功能的输出。 我正在使用具有损失函数的二进制交叉熵。
这是问题所在:我的数据集非常不平衡。我大约有100个黑色像素的1个白色像素。而且据我了解,二进制交叉熵与不平衡的数据集不太兼容。
因此,我尝试使用以下公式实现加权交叉熵:
这是我的代码:
def weighted_cross_entropy(y_true, y_pred):
w = [0.99, 0.01]
y_true_f = K.flatten(y_true)
y_pred_f = K.flatten(y_pred)
val = - (w[0] * y_true_f * K.log(y_pred_f) + w[1] * (1-y_true_f) * K.log(1-y_predf))
return K.mean(val, axis=-1)
我正在使用F1-Score / Dice在每个时期结束时测量结果。
但是经过5个纪元,损失等于NaN,F1得分仍然很低(0.02)。 似乎我的网络没有学习,但是我不明白为什么。也许我的公式是错误的? 我也尝试过权重值,但结果是相同的。
经过一些研究,我注意到可以直接在fit函数中给出定义的权重。
赞:
from sklearn.utils import class_weight
w = class_weight.compute_class_weight('balanced', np.unique(y.train.ravel()) , y_train.ravel())
model.fit(epochs = 1000, ..., class_weight = w)
通过使用二进制交叉熵基本函数来执行此操作,与不使用预定义权重相比,网络可以正确学习并给出更好的结果。
所以我不明白这两种方法之间的区别。真的有必要实现加权交叉熵函数吗?