Saltar al contenido

¿Cómo calcular F1 Macro en Keras?

Solución:

desde las métricas f1 de Keras 2.0, se han eliminado la precisión y la recuperación. La solución es utilizar una función métrica personalizada:

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()))


model.compile(loss="binary_crossentropy",
          optimizer= "adam",
          metrics=[f1])

La línea de retorno de esta función

return 2*((precision*recall)/(precision+recall+K.epsilon()))

se modificó agregando la constante épsilon, para evitar la división entre 0. Por lo tanto, NaN no se calculará.

Usar una función métrica de Keras no es la forma correcta de calcular F1 o AUC o algo así.

La razón de esto es que la función métrica se llama en cada paso del lote durante la validación. De esa forma, el sistema Keras calcula un promedio de los resultados del lote. Y esa no es la puntuación correcta de F1.

Esa es la razón por la que la puntuación F1 se eliminó de las funciones métricas en keras. Mira aquí:

  • https://github.com/keras-team/keras/commit/a56b1a55182acf061b1eb2e2c86b48193a0e88f7
  • https://github.com/keras-team/keras/issues/5794

La forma correcta de hacer esto es usar una función de devolución de llamada personalizada de una manera como esta:

  • https://github.com/PhilipMay/mltb#module-keras
  • https://medium.com/@thongonary/how-to-compute-f1-score-for-each-epoch-in-keras-a1acd17715a2

También sugiero esta solución

  • instalar el paquete keras_metrics por ybubnov
  • llama model.fit(nb_epoch=1, ...) dentro de un bucle for aprovechando las métricas de precisión / recuperación generadas después de cada época

Algo como esto:

    for mini_batch in range(epochs):
        model_hist = model.fit(X_train, Y_train, batch_size=batch_size, epochs=1,
                            verbose=2, validation_data=(X_val, Y_val))

        precision = model_hist.history['val_precision'][0]
        recall = model_hist.history['val_recall'][0]
        f_score = (2.0 * precision * recall) / (precision + recall)
        print 'F1-SCORE {}'.format(f_score)
¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)


Tags : /

Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *