web-dev-qa-db-fra.com

Précision de classe et rappel pour la classification multi-classes dans Tensorflow?

Existe-t-il un moyen d’obtenir une précision par classe ou un rappel lors de la classification multiclass à l’aide du flux tensoriel?.

Par exemple, si j’ai y_true et y_pred de chaque lot, existe-t-il un moyen fonctionnel d’obtenir une précision ou un rappel par classe si j’ai plus de 2 classes?.

7
prateek agrawal

Voici une solution qui fonctionne pour moi pour un problème avec n = 6 classes. Si vous avez beaucoup plus de classes, cette solution est probablement lente et vous devriez utiliser une sorte de mappage au lieu d'une boucle.

Supposons que vous ayez une étiquette de classe codée à chaud dans les lignes de tenseur labels et de logits (ou postérieurs) dans tenseur labels. Ensuite, si n est le nombre de classes, essayez ceci:

y_true = tf.argmax(labels, 1)
y_pred = tf.argmax(logits, 1)

recall = [0] * n
update_op_rec = [[]] * n

for k in range(n):
    recall[k], update_op_rec[k] = tf.metrics.recall(
        labels=tf.equal(y_true, k),
        predictions=tf.equal(y_pred, k)
    )

Notez qu'à l'intérieur de tf.metrics.recall, les variables labels et predictions sont définies sur des vecteurs booléens, comme dans le cas des 2 variables, ce qui permet d'utiliser la fonction.

5
Avi

Je crois que vous ne pouvez pas faire la précision multiclass, rappel, f1 avec les fonctions tf.metrics.precision/recall. Vous pouvez utiliser sklearn comme ceci pour un scénario à 3 classes:

from sklearn.metrics import precision_recall_fscore_support as score

prediction = [1,2,3,2] 
y_original = [1,2,3,3]

precision, recall, f1 = score(y_original, prediction)

print('precision: {}'.format(precision))
print('recall: {}'.format(recall))
print('fscore: {}'.format(fscore))

Cela va imprimer un tableau de précision, rappeler des valeurs mais le formater comme vous le souhaitez.

2
Momin Al Aziz

Ce problème me laisse perplexe depuis assez longtemps. Je sais que ce problème peut être résolu par Sklearn, mais je veux vraiment le résoudre avec l'API de Tensorflow. Et en lisant son code, j'ai enfin compris comment cette API fonctionne.

tf.metrics.precision_at_k(labels, predictions, k, class_id)
  • Tout d'abord, supposons qu'il s'agit d'un problème de 4 classes.
  • Deuxièmement, nous avons deux échantillons qui leurs étiquettes sont 3 et 1 et leurs prédictions sont [0.5,0.3,0.1,0,1], [0,5,0,3,0,1,0,1]. Selon nos prévisions, nous pouvons obtenir le résultat que les deux échantillons ont été prédits comme 1,1.
  • Troisièmement, si vous voulez obtenir la précision de class 1, utilisez la formule TP/(TP + FP), et nous supposons que le résultat est 1/(1+ 1) = 0,5. Parce que les deux échantillons ont été prédits comme 1, mais que l'un d'entre eux est en fait 3, le TP est donc 1, le FP vaut 1, et le résultat est 0.5.
  • Enfin, utilisons cette API pour vérifier notre hypothèse.

    import tensorflow as tf
    
    labels = tf.constant([[2],[0]],tf.int64)
    predictions = tf.constant([[0.5,0.3,0.1,0.1],[0.5,0.3,0.1,0.1]])
    
    metric = tf.metrics.precision_at_k(labels, predictions, 1, class_id=0)
    
    sess = tf.Session()
    sess.run(tf.local_variables_initializer())
    
    precision, update = sess.run(metric)
    print(precision) # 0.5
    

REMARQUER

  • k n'est pas le nombre de classes. Il représente le nombre de ce que nous voulons trier, ce qui signifie que la dernière dimension des prédictions doit correspondre à la valeur de k.

  • class_id représente la classe pour laquelle nous voulons des métriques binaires.

  • Si k = 1, cela signifie que nous ne trierons pas les prédictions, car ce que nous voulons faire est en réalité une classificaion binaire, mais en nous référant à différentes classes. Donc, si nous trions les prédictions, le class_id sera confondu et le résultat sera faux.

  • Et une autre chose importante est que si nous voulons obtenir le bon résultat, l'entrée du libellé doit être inférieure à 1 car le class_id représente en fait l'indice du libellé et l'indice commence. avec 0.

1
Hong Lan

2 faits:

  1. Comme indiqué dans d'autres réponses, les métriques intégrées de Tensorflow précision et rappellent ne prennent pas en charge les classes multiples (le document dit will be cast to bool)

  2. Il existe différentes manières d'obtenir les scores un contre tous en utilisant precision_at_k en spécifiant le class_id ou en convertissant simplement votre labels et predictions en tf.bool de la bonne manière.

Parce que cela est insatisfaisant et incomplet, j’ai écrittf_metrics, un paquet simple pour métriques multi-classes que vous pouvez trouver sur github . Il prend en charge plusieurs méthodes de calcul de moyenne telles que scikit-learn.

Exemple

import tensorflow as tf
import tf_metrics

y_true = [0, 1, 0, 0, 0, 2, 3, 0, 0, 1]
y_pred = [0, 1, 0, 0, 1, 2, 0, 3, 3, 1]
pos_indices = [1]        # Metrics for class 1 -- or
pos_indices = [1, 2, 3]  # Average metrics, 0 is the 'negative' class
num_classes = 4
average = 'micro'

# Tuple of (value, update_op)
precision = tf_metrics.precision(
    y_true, y_pred, num_classes, pos_indices, average=average)
recall = tf_metrics.recall(
    y_true, y_pred, num_classes, pos_indices, average=average)
f2 = tf_metrics.fbeta(
    y_true, y_pred, num_classes, pos_indices, average=average, beta=2)
f1 = tf_metrics.f1(
    y_true, y_pred, num_classes, pos_indices, average=average)
1
LeCodeDuGui

Je crois que TF ne fournit pas encore une telle fonctionnalité. Selon les docs ( https://www.tensorflow.org/api_docs/python/tf/metrics/precision ), il est dit que les libellés et les prédictions seront convertis en bool, ce qui ne concerne que binaire. classification. Peut-être est-il possible de coder les exemples en une seule opération et que cela fonctionnerait? Mais pas sûr de ça.

1
AVCarreiro

Il existe un moyen de faire cela dans TensorFlow.

tf.metrics.precision_at_k(labels, predictions, k, class_id)

définir k = 1 et définir class_id correspondant. Par exemple, class_id = 0 pour calculer la précision de la première classe.

0
Nandeesh