Quelle est la différence entre sparse_softmax_cross_entropy_with_logits et softmax_cross_entropy_with_logits?

111

Je suis récemment tombé sur tf.nn.sparse_softmax_cross_entropy_with_logits et je ne peux pas comprendre quelle est la différence par rapport à tf.nn.softmax_cross_entropy_with_logits .

La seule différence est-elle que les vecteurs d'apprentissage ydoivent être encodés à chaud lors de l'utilisation sparse_softmax_cross_entropy_with_logits?

En lisant l'API, je n'ai pas pu trouver d'autre différence par rapport à softmax_cross_entropy_with_logits. Mais pourquoi avons-nous besoin de la fonction supplémentaire alors?

Ne devrait pas softmax_cross_entropy_with_logitsproduire les mêmes résultats que sparse_softmax_cross_entropy_with_logitss'il est fourni avec des données / vecteurs d'apprentissage encodés à chaud?

daniel451
la source
1
Je suis intéressé à voir une comparaison de leurs performances si les deux peuvent être utilisés (par exemple avec des étiquettes d'image exclusives); Je m'attendrais à ce que la version clairsemée soit plus efficace, du moins en termes de mémoire.
Yibo Yang
1
Voir aussi cette question , qui traite de toutes les fonctions d'entropie croisée dans tensorflow (il s'avère qu'il y en a beaucoup).
Maxim

Réponses:

175

Avoir deux fonctions différentes est une commodité , car elles produisent le même résultat.

La différence est simple:

  • Pour sparse_softmax_cross_entropy_with_logits, les étiquettes doivent avoir la forme [batch_size] et le dtype int32 ou int64. Chaque étiquette est un entier dans la plage [0, num_classes-1].
  • Pour softmax_cross_entropy_with_logits, les étiquettes doivent avoir la forme [batch_size, num_classes] et dtype float32 ou float64.

Les étiquettes utilisées dans softmax_cross_entropy_with_logitssont la seule version chaude des étiquettes utilisées dans sparse_softmax_cross_entropy_with_logits.

Une autre petite différence est qu'avec sparse_softmax_cross_entropy_with_logits, vous pouvez donner -1 comme étiquette pour avoir une perte 0sur cette étiquette.

Olivier Moindrot
la source
15
Le -1 est-il correct? Comme le lit la documentation: "Chaque entrée dans les étiquettes doit être un index dans [0, num_classes). Les autres valeurs lèveront une exception lorsque cette opération est exécutée sur le processeur et renverront NaN pour les lignes de perte et de gradient correspondantes sur le GPU."
user1761806
1
[0, num_classes) = [0, num_classes-1]
Karthik C
24

Je voudrais juste ajouter 2 choses à la réponse acceptée que vous pouvez également trouver dans la documentation TF.

Première:

tf.nn.softmax_cross_entropy_with_logits

REMARQUE: Bien que les classes soient mutuellement exclusives, leurs probabilités ne doivent pas nécessairement l'être. Tout ce qui est requis est que chaque ligne d'étiquettes soit une distribution de probabilité valide. Si ce n'est pas le cas, le calcul du gradient sera incorrect.

Seconde:

tf.nn.sparse_softmax_cross_entropy_with_logits

REMARQUE: Pour cette opération, la probabilité d'une étiquette donnée est considérée comme exclusive. Autrement dit, les classes souples ne sont pas autorisées et le vecteur d'étiquettes doit fournir un seul index spécifique pour la classe vraie pour chaque ligne de logits (chaque entrée de mini-match).

Faites glisser0
la source
4
Que devons-nous utiliser si les classes ne sont pas mutuellement exclusives. Je veux dire si nous combinons plusieurs étiquettes catégoriques?
Hayro
J'ai aussi lu ceci. Cela signifie donc que nous appliquons la probabilité de classe sur l'entropie croisée plutôt que de la prendre comme un vecteur onehot.
Shamane Siriwardhana
@Hayro - Voulez-vous dire que vous ne parvenez pas à effectuer un encodage à chaud? Je pense qu'il faudrait envisager un modèle différent. Cela mentionnait quelque chose comme "il serait plus approprié de construire 4 classificateurs de régression logistique binaire" Pour d'abord vous assurer que vous pouvez séparer les classes.
ashley
21

Les deux fonctions calculent les mêmes résultats et sparse_softmax_cross_entropy_with_logits calcule l'entropie croisée directement sur les étiquettes éparses au lieu de les convertir avec un encodage à chaud .

Vous pouvez le vérifier en exécutant le programme suivant:

import tensorflow as tf
from random import randint

dims = 8
pos  = randint(0, dims - 1)

logits = tf.random_uniform([dims], maxval=3, dtype=tf.float32)
labels = tf.one_hot(pos, dims)

res1 = tf.nn.softmax_cross_entropy_with_logits(       logits=logits, labels=labels)
res2 = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=logits, labels=tf.constant(pos))

with tf.Session() as sess:
    a, b = sess.run([res1, res2])
    print a, b
    print a == b

Ici, je crée un logitsvecteur aléatoire de longueur dimset génère des étiquettes encodées à chaud (où l'élément dans posest 1 et les autres sont 0).

Après cela, je calcule softmax et softmax clairsemé et compare leur sortie. Essayez de le réexécuter plusieurs fois pour vous assurer qu'il produit toujours le même résultat

Salvador Dali
la source