在keras中计算微F-1分数

Posted

技术标签:

【中文标题】在keras中计算微F-1分数【英文标题】:Calculating micro F-1 score in keras 【发布时间】:2021-06-07 18:34:24 【问题描述】:

我有一个包含 15 个不平衡类的数据集,并尝试使用 keras 进行多标签分类。

我正在尝试使用微 F-1 分数作为衡量标准。

我的模特:

# Create a VGG instance
model_vgg = tf.keras.applications.VGG19(weights = 'imagenet', pooling = 'max', include_top = False, 
input_shape = (512, 512, 3))

# Freeze the layers which you don't want to train. 
for layer in model_vgg.layers[:-5]:
layer.trainable = False

# Adding custom Layers 
x = model_vgg.output
x = Flatten()(x)
x = Dense(1024, activation = "relu")(x)
x = Dropout(0.5)(x)
x = Dense(1024, activation = "relu")(x)
predictions = Dense(15, activation = "sigmoid")(x)

# creating the final model 
model_vgg_final = Model(model_vgg.input, predictions)

# Print the summary
model_vgg_final.summary()

对于 F1 分数,我使用来自 this question 的自定义指标

from keras import backend as K

def f1(y_true, y_pred):
    def recall(y_true, y_pred):
        """Recall metric.

    Only computes a batch-wise average of recall.

    Computes the recall, a metric for multi-label classification of
    how many relevant items are selected.
    """
    true_positives = K.sum(K.round(K.clip(y_true * y_pred, 0, 1)))
    possible_positives = K.sum(K.round(K.clip(y_true, 0, 1)))
    recall = true_positives / (possible_positives + K.epsilon())
    return recall

    def precision(y_true, y_pred):
        """Precision metric.

    Only computes a batch-wise average of precision.

    Computes the precision, a metric for multi-label classification of
    how many selected items are relevant.
    """
    true_positives = K.sum(K.round(K.clip(y_true * y_pred, 0, 1)))
    predicted_positives = K.sum(K.round(K.clip(y_pred, 0, 1)))
    precision = true_positives / (predicted_positives + K.epsilon())
    return precision

    precision = precision(y_true, y_pred)
    recall = recall(y_true, y_pred)
    return 2*((precision*recall)/(precision+recall+K.epsilon()))

我在编译模型时使用二元交叉熵和自定义 F-1

# Compile a model
model_vgg_final.compile(optimizer = 'adam', loss = 'binary_crossentropy', metrics = [f1]) 

我监控 F-1 是否提前停止

# Early stopping
early_stopping = EarlyStopping(monitor = 'f1', patience = 5)

# Training the model
history_vgg = model_vgg_final.fit(train_generator, steps_per_epoch = 10, epochs = 30, verbose = 1, 
callbacks = [early_stopping], validation_data = valid_generator)

如何更新此自定义函数并获取 micro F-1 作为指标?也感谢有关我的方法的提示。

scikit-learn documentation中有信息,但不知道如何将其合并到keras中

【问题讨论】:

我找到了这个androidkt.com/calculate-f1-macro-in-keras 【参考方案1】:

好问题。

您在此处提供的链接指向如何在旧版本的 Keras 中计算指标(请耐心等待,简短说明)。问题是,在较旧的 Keras (1.X) 中,指标是分批计算的,这当然会导致不正确的全局结果。在 Keras 2.X 中,删除了内置指标。

但是,您的问题有一些解决方案。

    您可以实现自己的自定义回调。你可以在这里查看我的答案,保证在 TensorFlow 2.x 中工作:How to get other metrics in Tensorflow 2.0 (not only accuracy)? 你可以使用tensorflow-addons --> pip install tensorflow-addons。 TensorFlow addons 是一个非常好的包,它包含了基础 TensorFlow 包中没有的多种功能和特性。这里,F1Score 是一个内置指标,因此您可以直接使用它。

例子:

model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=0.00001),
                      loss=tf.keras.losses.BinaryCrossentropy(),
                      metrics=[tf.keras.metrics.BinaryAccuracy(),
                               tfa.metrics.F1Score(num_classes=number_of_classes, average='micro',threshold=0.5),

请注意'micro'参数的用法,它实际上代表了你想要的,微f1-score

【讨论】:

有没有办法对输出为单个值的二进制分类执行此操作? tfa.metrics.F1Score 似乎不支持这一点。如果是这种情况,那就太奇怪了,因为二元分类可能是最常见的 ML 问题。 TFA 仅支持单热编码的 y 值,因此如果您有二进制分类,您可以将 y 标签从 0 和 1 转换为 [0,1] 和 [1,0 ]

以上是关于在keras中计算微F-1分数的主要内容,如果未能解决你的问题,请参考以下文章

Keras 输入形状错误

在 keras(tensorflow 后端)中计算梯度时出错

如何在 Keras 中计算精度和召回率

国民体质测定标准手册及标准解析成JSON文件计算分数,java解析excel文件

如何在 keras 中计算接收操作特征 (ROC) 和 AUC?

keras中不同批量大小的损失计算