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

How to create weighted cross entropy loss?

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

我试过这个:

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

如何造成这种损失?

我建议首先使用 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:20, 1:0}, weighted_metrics = ['accuracy'])

class weights是一个字典,用来补偿数据集中的不平衡。例如,如果您有一个包含 1000 张狗图像和 100 张猫图像的数据集,您的 class 过滤器会偏向狗 class。如果它每次都预测狗,那么它在 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) 

如果您处理不平衡 classes,您应该使用 class 权重。例如,如果您有两个 classes,其中 class 0 的数据是 class 1 的两倍:

class_weight = {0 :1, 1: 2}

编译时,使用 weighted_metrics 而不仅仅是指标,否则模型在计算时不会考虑 class 权重准确率高得不切实际

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)