Keras:class_weight 实际上是尝试平衡什么?

9

我的数据极度不平衡。大约99.99%的样本是负面的,正面的样本则被分成了另外三个类别。我认为我正在训练的模型基本上总是预测大多数的负面类别。因此,我尝试加权处理这些类别。

模型

model = Sequential()

#Layer 1
model.add(Conv1D( {{choice([32, 64, 90, 128])}}, {{choice([3, 4, 5, 6, 8])}}, activation='relu', kernel_initializer=kernel_initializer, input_shape=X_train.shape[1:]))
model.add(BatchNormalization())

#Layer 2
model.add(Conv1D({{choice([32, 64, 90, 128])}}, {{choice([3, 4, 5, 6])}}, activation='relu',kernel_initializer=kernel_initializer))
model.add(Dropout({{uniform(0, 0.9)}}))

#Flatten
model.add(Flatten())

#Output
model.add(Dense(4, activation='softmax'))

(“{{...}}”是用于Hyperas的。) 如何进行加权处理: 1. 在model.fit()中使用class_weight
model.fit(X_train, Y_train, batch_size=64, epochs=10, verbose=2, validation_data=(X_test, Y_test), class_weight={0: 9999, 1:9999, 2: 9999, 3:1})

\2. 使用sklearn compute_class_weight()model.fit()中使用class_weight

model.fit(..., class_weight=class_weight.compute_class_weight("balanced", np.unique(Y_train), Y_train)

\3. 使用自定义损失函数

from keras import backend as K
def custom_loss(weights):
    #gist.github.com/wassname/ce364fddfc8a025bfab4348cf5de852d

    def loss(Y_true, Y_pred):
        Y_pred /= K.sum(Y_pred, axis=-1, keepdims=True)
        Y_pred = K.clip(Y_pred, K.epsilon(), 1 - K.epsilon())

        loss = Y_true * K.log(Y_pred) * weights
        loss = -K.sum(loss, -1)
        return loss

    return loss

extreme_weights = np.array([9999, 9999, 9999, 1])
model.compile(loss=custom_loss(extreme_weights),
            metrics=['accuracy'],
            optimizer={{choice(['rmsprop', 'adam', 'sgd','Adagrad','Adadelta'])}}
            )

#(then fit *without* class_weight)

结果

结果较差。所有类别的准确率约为0.99,所有类别的不平衡准确率约为 0.5。但更有意义的指标,如auPRC,告诉我们完全不同的故事。在大多数类别中,auPRC接近于1,而在其余类别中则接近于0

Keras是如何平衡类别的?它只是确保各个类别的准确率相同-还是这两种度量应该相等或可比?还是我指定权重错误了?

1个回答

2
Keras在训练过程中使用类别权重,但准确度并不反映这一点。准确度是跨越所有样本计算的,与类别之间的权重无关。这是因为您在compile()中使用了指标“accuracy”。您可以定义一个自定义的更准确的加权准确度并使用它,或者使用sklearn度量(例如f1_score(),可以是“binary”,“weighted”等)。
def macro_f1(y_true, y_pred):
     return f1_score(y_true, y_pred, average='macro')


model.compile(loss=custom_loss(extreme_weights),
        metrics=['accuracy', macro_f1],
        optimizer={{choice(['rmsprop', 'adam', 'sgd','Adagrad','Adadelta'])}}
        )

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接