Comment calculer F1 Macro dans Keras?
j'ai essayé d'utiliser les codes donnés à partir de Keras avant qu'ils ne soient supprimés. Voici le code :
def precision(y_true, y_pred):
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
def recall(y_true, y_pred):
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 fbeta_score(y_true, y_pred, beta=1):
if beta < 0:
raise ValueError('The lowest choosable beta is zero (only precision).')
# If there are no true positives, fix the F score at 0 like sklearn.
if K.sum(K.round(K.clip(y_true, 0, 1))) == 0:
return 0
p = precision(y_true, y_pred)
r = recall(y_true, y_pred)
bb = beta ** 2
fbeta_score = (1 + bb) * (p * r) /(bb * p + r + K.epsilon())
return fbeta_score
def fmeasure(y_true, y_pred):
return fbeta_score(y_true, y_pred, beta=1)
De ce que j'ai vu (je suis un amateur dans le présent), il semble que l'on utilise la formule correcte. Mais, quand j'ai essayé de l'utiliser comme indicateurs dans le processus de formation, j'ai obtenu exactement égal de sortie pour val_accuracy, val_precision, val_recall, et val_fmeasure. Je crois que cela pourrait se produire même si la formule correcte, mais je crois que c'est peu probable. Une explication à ce problème? Merci
- Sont les valeurs de sortie à l'identique de zéro?
- Pourriez-vous fournir un code complet - avec le
fit
etcompile
appels? Pourriez-vous également fournir plus de détails au sujet de vos données? - C'est un problème connu dans Keras (Voir: github.com/fchollet/keras/issues/5400). Précision, Rcall, et F1-Score sont estimés dans un batchwise fashon.
- La meilleure approche, à mon avis, est celle qui a été adoptée dans: github.com/fchollet/keras/issues/5400#issuecomment-282188692
- Il y a 2 catégories de l'étiquette, 0 et 1. J'utilise categorical_crossentropy et la dernière couche Dense est à l'aide de softmax fonction d'activation. J'ai essayé de modifier le code pour utiliser binary_crossentropy et la dernière couche Dense à l'aide relu, et la précision, etc fonctionnent parfaitement. Je me dis qu'il est à cause de la fonction ne peut pas être appliquée à tenseur en forme de données. Toute suggestion?
- Je suppose que vous n'utilisez 1-hot codage avec categorical_crossentropy mais pas lors de l'utilisation de binary_crossentropy ?
- Oui, j'utilise un encodage. Et j'ai essayé d'exécuter le code avec lot unique tenseur et cela a fonctionné. Je suppose que le code est d'avoir du mal avec la 3d tenseur(avec le lot). Juste une possibilité. Qu'en pensez-vous?
Vous devez vous connecter pour publier un commentaire.
depuis Keras 2.0 métriques de f1, de précision et de rappel ont été supprimés. La solution est d'utiliser une métrique personnalisée fonction:
La ligne de retour de cette fonction
a été modifié par l'ajout de la constante d'epsilon, afin d'éviter la division par 0. Donc NaN ne sera pas calculé.
return 2*((precision*recall)/(precision+recall))
àreturn 2*((precision*recall)/(precision+recall+K.epsilon()))
de fixer NaN duÀ l'aide d'un Keras métrique fonction n'est pas la bonne façon de calculer F1 ou de l'ASC ou quelque chose comme ça.
La raison pour cela est que la métrique fonction est appelée à chaque changement d'étape lors de la validation. De cette façon, le Keras système calcule une moyenne sur le lot de résultats. Et ce n'est pas le droit de F1 score.
C'est la raison pourquoi F1 score est supprimée à partir de la métrique fonctions dans keras. Voir ici:
La bonne façon de le faire est d'utiliser une fonction de rappel personnalisée la fonction comme ceci:
https://medium.com/@thongonary/how-to-compute-f1-score-for-each-epoch-in-keras-a1acd17715a2
Je suggère également de ce travail autour
model.fit(nb_epoch=1, ...)
à l'intérieur d'une boucle de prendre avantage de la précision/rappel des métriques édité après chaque époqueQuelque chose comme ceci:
HTML:
Comme quoi @Pedia a dit dans son commentaire ci-dessus,
on_epoch_end
,comme indiqué dans le github.com/fchollet/keras/issues/5400 est la meilleure approche.