我必须处理高度不平衡的数据。据我了解,我需要使用加权交叉熵损失。
我尝试过:
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
我该如何造成这种损失?
答案 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)