如何创建加权交叉熵损失?

时间:2020-10-20 19:32:29

标签: python tensorflow keras loss-function cross-entropy

我必须处理高度不平衡的数据。据我了解,我需要使用加权交叉熵损失。

我尝试过:

import tensorflow as tf

weights = np.array([<values>])
def loss(y_true, y_pred):
    # weights.shape = (63,)
    # y_true.shape = (64, 63)
    # y_pred.shape = (64, 63)
    return tf.reduce_mean(tf.nn.weighted_cross_entropy_with_logits(y_true, y_pred, weights))

model.compile('adam', loss=loss, metrics=['acc'])

但是有一个错误:

ValueError: Creating variables on a non-first call to a function decorated with tf.function

我该如何造成这种损失?

3 个答案:

答案 0 :(得分:2)

我建议首先使用Keras的class_weight

class_weight

是带有{label:weight}

的字典

例如,如果标签1中的示例比标签0中的示例多20倍,那么您可以编写

# Assign 20 times more weight to label 0
model.fit(..., class_weight = {0:20, 1:0})

通过这种方式,您不必担心自己实施加权CCE。

附加说明:在您的model.compile()中,请不要忘记使用weighted_metrics=['accuracy'],以准确反映您的准确性。

model.fit(..., class_weight = {0:1, 1:20}, weighted_metrics = ['accuracy'])

答案 1 :(得分:0)

类权重是一个字典,用于补偿数据集中的不平衡。例如,如果您有1000个狗图像和100个猫图像的数据集,则分类器将偏向狗类。如果它每次都能预测狗,那么90%的时间是正确的。为了补偿不平衡,您可以使用class_weights词典在计算损失时为猫的样本加权比对狗的样本高10倍。一种方法是使用sklearn中的class_weight方法,如下所示

from sklearn.utils import class_weight
import numpy as np

class_weights = class_weight.compute_class_weight(
               'balanced',
                np.unique(train_generator.classes), 
                train_generator.classes) 

答案 2 :(得分:0)

如果使用不平衡类,则应使用类权重。例如,如果您有两个类别,其中类别0的数据是类别1的两倍:

class_weight = {0 :1, 1: 2}

编译时,请使用 weighted_metrics 而不是仅使用指标,否则该模型在计算准确性时将不会考虑类的权重,这会非常高。

model.compile(loss="binary_crossentropy",optimizer='adam', weighted_metrics=['accuracy'])

hist = model.fit_generator(train,validation_split=0.2,epochs=20,class_weight=class_weight)