Comment calculer précision et rappel dans Keras

je suis en train de construire un classificateur multi-classe avec Keras 2.02 (avec TensorFlow backend) et je ne sais pas comment calculer la précision et le rappel dans Keras. S'il vous plaît aider moi.

17
demandé sur Jimmy Du 2017-03-28 20:53:43

6 réponses

à partir de Keras 2.0, précision et rappel ont été retirés de la branche principale. Vous devrez les mettre en œuvre vous-même. Suivez ce guide pour créer des mesures personnalisées:Ici.

la Précision et le rappel de l'équation peut être trouvé Ici

Ou de réutiliser le code de keras avant qu'il soit supprimé Ici.

il y a des mesures ont été supprimées parce qu'elles étaient de type discontinu de sorte que la valeur peut ou ne peut pas être correcte.

20
répondu Dref360 2017-03-29 21:34:10

Tensorflow a les mesures que vous recherchez ici.

Vous pouvez envelopper tf.métriques (par exemple,tf.metrics.precision) en keras.métrique.

à Partir de ma réponse Comment utiliser TensorFlow métriques dans Keras:

def as_keras_metric(method):
    import functools
    from keras import backend as K
    import tensorflow as tf
    @functools.wraps(method)
    def wrapper(self, args, **kwargs):
        """ Wrapper for turning tensorflow metrics into keras metrics """
        value, update_op = method(self, args, **kwargs)
        K.get_session().run(tf.local_variables_initializer())
        with tf.control_dependencies([update_op]):
            value = tf.identity(value)
        return value
    return wrapper

usage de base:

precision = as_keras_metric(tf.metrics.precision)
recall = as_keras_metric(tf.metrics.recall)
...

compilez le modèle keras:

model.compile(..., metrics=[precision, recall])

Rappel et de Précision de l'ASC:

vous pouvez également faire des choses comme l'emballage fonctionnel arguments (ce qui est nécessaire si vous voulez l'ASC de Rappel et de Précision):

@as_keras_metric
def auc_pr(y_true, y_pred, curve='PR'):
    return tf.metrics.auc(y_true, y_pred, curve=curve)

Et

model.compile(..., metrics=[auc_pr])
11
répondu Christian Skjødt 2018-05-28 12:49:35

paquet Python keras-metrics pourrait être utile pour cela (je suis l'auteur du paquet).

import keras
import keras_metrics

model = models.Sequential()
model.add(keras.layers.Dense(1, activation="sigmoid", input_dim=2))
model.add(keras.layers.Dense(1, activation="softmax"))

model.compile(optimizer="sgd",
              loss="binary_crossentropy",
              metrics=[keras_metrics.precision(), keras_metrics.recall()])
7
répondu Yasha Bubnov 2018-09-20 06:37:17

Ma réponse est basée sur l' commentaire de Keras GH question. Il calcule la précision de validation et le rappel à chaque époque pour une tâche de classification encodée onehot.

import keras as keras
import numpy as np
from keras.optimizers import SGD
from sklearn.metrics import precision_score, recall_score

model = keras.models.Sequential()
# ...
sgd = SGD(lr=0.001, momentum=0.9)
model.compile(optimizer=sgd, loss='categorical_crossentropy', metrics=['accuracy'])


class Metrics(keras.callbacks.Callback):
    def on_train_begin(self, logs={}):
        self._data = []

    def on_epoch_end(self, batch, logs={}):
        X_val, y_val = self.validation_data[0], self.validation_data[1]
        y_predict = np.asarray(model.predict(X_val))

        y_val = np.argmax(y_val, axis=1)
        y_predict = np.argmax(y_predict, axis=1)

        self._data.append({
            'val_recall': recall_score(y_val, y_predict),
            'val_precision': precision_score(y_val, y_predict),
        })
        return

    def get_data(self):
        return self._data


metrics = Metrics()
history = model.fit(X_train, y_train, epochs=100, validation_data=(X_val, y_val), callbacks=[metrics])
metrics.get_data()
0
répondu vogdb 2018-06-01 17:29:37

ce fil est un peu usé, mais juste au cas où il aiderait quelqu'un à atterrir ici. Si vous êtes prêt à mettre à niveau vers Keras v2.1.6, il y a eu beaucoup de travaux sur l'obtention de dynamique des paramètres pour un travail même si il semble y avoir plus de travail qu'est en train de faire (https://github.com/keras-team/keras/pull/9446).

Layer, illustré par exemple dans Binarytruepositifs.

Pour rappel, ce serait ressembler à ça:

class Recall(keras.layers.Layer):
    """Stateful Metric to count the total recall over all batches.

    Assumes predictions and targets of shape `(samples, 1)`.

    # Arguments
        name: String, name for the metric.
    """

    def __init__(self, name='recall', **kwargs):
        super(Recall, self).__init__(name=name, **kwargs)
        self.stateful = True

        self.recall = K.variable(value=0.0, dtype='float32')
        self.true_positives = K.variable(value=0, dtype='int32')
        self.false_negatives = K.variable(value=0, dtype='int32')
    def reset_states(self):
        K.set_value(self.recall, 0.0)
        K.set_value(self.true_positives, 0)
        K.set_value(self.false_negatives, 0)

    def __call__(self, y_true, y_pred):
        """Computes the number of true positives in a batch.

        # Arguments
            y_true: Tensor, batch_wise labels
            y_pred: Tensor, batch_wise predictions

        # Returns
            The total number of true positives seen this epoch at the
                completion of the batch.
        """
        y_true = K.cast(y_true, 'int32')
        y_pred = K.cast(K.round(y_pred), 'int32')

        # False negative calculations
        y_true = K.cast(y_true, 'int32')
        y_pred = K.cast(K.round(y_pred), 'int32')
        false_neg = K.cast(K.sum(K.cast(K.greater(y_pred, y_true), 'int32')), 'int32')
        current_false_neg = self.false_negatives * 1
        self.add_update(K.update_add(self.false_negatives,
                                     false_neg),
                        inputs=[y_true, y_pred])
        # True positive  calculations
        correct_preds = K.cast(K.equal(y_pred, y_true), 'int32')
        true_pos = K.cast(K.sum(correct_preds * y_true), 'int32')
        current_true_pos = self.true_positives * 1
        self.add_update(K.update_add(self.true_positives,
                                     true_pos),
                        inputs=[y_true, y_pred])
        # Combine
        recall = (K.cast(self.true_positives, 'float32') / (K.cast(self.true_positives, 'float32') + K.cast(self.false_negatives, 'float32') + K.cast(K.epsilon(), 'float32')))
        self.add_update(K.update(self.recall,
                                     recall),
                        inputs=[y_true, y_pred])

        return recall   
0
répondu vsocrates 2018-07-19 00:08:06

Utilisez Scikit Learn framework pour cela.

from sklearn.metrics import classification_report

history = model.fit(x_train, y_train, batch_size=32, epochs=10, verbose=1, validation_data=(x_test, y_test), shuffle=True)
pred = model.predict(x_test, batch_size=32, verbose=1)
predicted = np.argmax(pred, axis=1)
report = classification_report(np.argmax(y_test, axis=1), predicted)
print(report)

ce blog est très utile.

-2
répondu Jesús Utrera 2018-04-25 10:59:56