Qu'est-ce que logits, softmax et softmax cross entropy avec logits?

Je parcourais les documents de L'API tensorflow ici . Dans la documentation tensorflow, ils ont utilisé un mot clé appelé logits. Qu'est-ce que c'est? Dans beaucoup de méthodes dans les documents API, il est écrit comme

tf.nn.softmax(logits, name=None)

Si ce qui est écrit est ceux - logits sont uniquement Tensors, pourquoi garder un nom différent comme logits?

Une autre chose est qu'il y a deux méthodes que je ne pouvais pas différencier. Ils étaient

tf.nn.softmax(logits, name=None)
tf.nn.softmax_cross_entropy_with_logits(logits, labels, name=None)

Quelles sont les différences entre eux? Les documents ne sont pas clairs pour moi. Je savoir ce que tf.nn.softmax fait. Mais pas les autres. Un exemple sera vraiment utile.

250
demandé sur Kevin Johnsrude 2015-12-12 17:03:27

5 réponses

Logits signifie simplement que la fonction fonctionne sur la sortie non calibrée des couches précédentes et que l'échelle relative pour comprendre les unités est linéaire. Cela signifie, en particulier, que la somme des entrées peut ne pas être égale à 1, que les valeurs sontPas probabilités (vous pourriez avoir une entrée de 5).

tf.nn.softmax produit juste le résultat de l'application de la fonction softmax à un tenseur d'entrée. Le softmax "écrase" les entrées de sorte que sum (input) = 1; c'est un moyen de normaliser. La forme de sortie d'un softmax est la même que l'entrée - elle normalise simplement les valeurs. Les sorties de softmax peuvent être interprétées comme des probabilités.

a = tf.constant(np.array([[.1, .3, .5, .9]]))
print s.run(tf.nn.softmax(a))
[[ 0.16838508  0.205666    0.25120102  0.37474789]]

En revanche, tf.nn.softmax_cross_entropy_with_logits calcule l'entropie croisée du résultat après l'application de la fonction softmax (mais il le fait tous ensemble d'une manière plus prudente mathématiquement). C'est similaire au résultat de:

sm = tf.nn.softmax(x)
ce = cross_entropy(sm)

L'entropie croisée est une métrique sommaire-elle additionne les éléments. La sortie de tf.nn.softmax_cross_entropy_with_logits sur une forme [2,5] le tenseur est de forme [2,1] (la première dimension est traitée comme le lot).

Si vous voulez faire de l'optimisation pour minimiser l'entropie croisée, et que vous êtes softmaxing après votre dernière couche, vous devriez utiliser tf.nn.softmax_cross_entropy_with_logits au lieu de le faire vous-même, car il couvre les cas de coin numériquement instables de la bonne manière mathématiquement. Sinon, vous finirez par le pirater en ajoutant de petits epsilons ici et là.

(édité 2016-02-07: si vous avez des étiquettes à classe unique, lorsqu'un objet ne peut appartenir qu'à une classe, vous pouvez maintenant envisager d'utiliser tf.nn.sparse_softmax_cross_entropy_with_logits afin de ne pas avoir à convertir vos étiquettes en un tableau dense à un point chaud. Cette fonction a été ajoutée après la version 0.6.0.)

339
répondu dga 2016-02-07 18:30:35

Version Courte:

Supposons que vous ayez deux tenseurs, où y_hat contient des scores calculés pour chaque classe (par exemple, à partir de y = W * x + b)et y_true contient des étiquettes vraies codées à chaud.

y_hat  = ... # Predicted label, e.g. y = tf.matmul(X, W) + b
y_true = ... # True label, one-hot encoded

Si vous interprétez les scores dans y_hat comme des probabilités logiques non normalisées, alors ils sont logits .

De plus, la perte totale d'entropie croisée calculée de cette manière:

y_hat_softmax = tf.nn.softmax(y_hat)
total_loss = tf.reduce_mean(-tf.reduce_sum(y_true * tf.log(y_hat_softmax), [1]))

Est essentiellement équivalent à la perte totale d'entropie croisée calculé avec la fonction softmax_cross_entropy_with_logits():

total_loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(y_hat, y_true))

Version Longue:

Dans la couche de sortie de votre réseau neuronal, vous calculerez probablement un tableau contenant les scores de classe pour chacune de vos instances d'entraînement, par exemple à partir d'un calcul y_hat = W*x + b. Pour servir d'exemple, ci-dessous, j'ai créé un y_hat en tant que Tableau 2 x 3, où les lignes correspondent aux instances d'apprentissage et les colonnes correspondent aux classes. Donc ici il y a 2 instances de formation et 3 classe.

import tensorflow as tf
import numpy as np

sess = tf.Session()

# Create example y_hat.
y_hat = tf.convert_to_tensor(np.array([[0.5, 1.5, 0.1],[2.2, 1.3, 1.7]]))
sess.run(y_hat)
# array([[ 0.5,  1.5,  0.1],
#        [ 2.2,  1.3,  1.7]])

Notez que les valeurs ne sont pas normalisées (c'est-à-dire que les lignes ne s'additionnent pas à 1). Afin de les normaliser, nous pouvons appliquer la fonction softmax, qui interprète l'entrée comme des probabilités logiques non normalisées (aka logits) et génère des probabilités linéaires normalisées.

y_hat_softmax = tf.nn.softmax(y_hat)
sess.run(y_hat_softmax)
# array([[ 0.227863  ,  0.61939586,  0.15274114],
#        [ 0.49674623,  0.20196195,  0.30129182]])

Il est important de bien comprendre ce que dit la sortie softmax. Ci-dessous, j'ai montré un tableau qui représente plus clairement la sortie ci-dessus. Il peut être vu que, par exemple, l' la probabilité que l'instance d'entraînement 1 soit "Classe 2" est de 0,619. Les probabilités de classe pour chaque instance d'apprentissage sont normalisées, de sorte que la somme de chaque ligne est 1.0.

                      Pr(Class 1)  Pr(Class 2)  Pr(Class 3)
                    ,--------------------------------------
Training instance 1 | 0.227863   | 0.61939586 | 0.15274114
Training instance 2 | 0.49674623 | 0.20196195 | 0.30129182

Nous avons donc maintenant des probabilités de classe pour chaque instance d'apprentissage, où nous pouvons prendre l'argmax () de chaque ligne pour générer une classification finale. D'en haut, nous pouvons générer que l'instance de formation 1 appartient à "classe 2" et que l'instance de formation 2 appartient à "classe 1".

Ces classifications sont-elles correctes? Nous avons besoin de pour mesurer par rapport aux vraies étiquettes de l'ensemble de formation. Vous aurez besoin d'un tableau y_true encodé à chaud, où encore une fois les lignes sont des instances d'apprentissage et les colonnes sont des classes. Ci-dessous, j'ai créé un exemple y_true Un tableau à chaud où l'étiquette vraie pour l'instance de formation 1 est "Classe 2" et l'étiquette vraie pour l'instance de formation 2 est "Classe 3".

y_true = tf.convert_to_tensor(np.array([[0.0, 1.0, 0.0],[0.0, 0.0, 1.0]]))
sess.run(y_true)
# array([[ 0.,  1.,  0.],
#        [ 0.,  0.,  1.]])

Est la distribution de probabilité dans y_hat_softmax proche de la distribution de probabilité dans y_true? Nous pouvons utiliser entropie croisée pour mesure de l'erreur.

Formule pour la perte d'entropie croisée

Nous pouvons calculer la perte d'entropie croisée sur une base linéaire et voir les résultats. Ci-dessous, nous pouvons voir que l'instance d'entraînement 1 a une perte de 0.479, tandis que l'instance d'entraînement 2 a une perte plus élevée de 1.200. Ce résultat est logique car dans notre exemple ci-dessus, y_hat_softmax a montré que la probabilité la plus élevée de l'instance d'entraînement 1 était pour la "classe 2", qui correspond à l'instance d'entraînement 1 dans y_true; cependant, la prédiction pour l'instance d'entraînement 2 a montré un Probabilité la plus élevée pour "Classe 1", qui ne correspond pas à la vraie classe "Classe 3".

loss_per_instance_1 = -tf.reduce_sum(y_true * tf.log(y_hat_softmax), reduction_indices=[1])
sess.run(loss_per_instance_1)
# array([ 0.4790107 ,  1.19967598])

Ce que nous voulons vraiment, c'est la perte totale sur toutes les instances d'entraînement. Nous pouvons donc calculer:

total_loss_1 = tf.reduce_mean(-tf.reduce_sum(y_true * tf.log(y_hat_softmax), reduction_indices=[1]))
sess.run(total_loss_1)
# 0.83934333897877944

Utilisation de softmax_cross_entropy_with_logits()

Nous pouvons plutôt calculer la perte totale d'entropie croisée en utilisant la fonction tf.nn.softmax_cross_entropy_with_logits(), comme indiqué ci-dessous.

loss_per_instance_2 = tf.nn.softmax_cross_entropy_with_logits(y_hat, y_true)
sess.run(loss_per_instance_2)
# array([ 0.4790107 ,  1.19967598])

total_loss_2 = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(y_hat, y_true))
sess.run(total_loss_2)
# 0.83934333897877922

Notez que total_loss_1 et total_loss_2 produisent des résultats essentiellement équivalents avec quelques petites différences dans le très derniers chiffres. Cependant, vous pouvez aussi bien utiliser la deuxième approche: il faut une ligne de code de moins et accumule moins d'erreurs numériques car le softmax est fait pour vous à l'intérieur de softmax_cross_entropy_with_logits().

209
répondu stackoverflowuser2010 2016-09-16 06:19:43

tf.nn.softmax calcule la propagation vers l'avant à travers une couche softmax. Vous l'utilisez pendant évaluation du modèle lorsque vous calculez les probabilités que les sorties du modèle.

tf.nn.softmax_cross_entropy_with_logits calcule le coût d'un softmax couche. Il n'est utilisé que pendant la formation .

Les logits sont les probabilités de log unnormalized sortie du modèle (les valeurs de sortie avant la normalisation softmax leur est appliquée).

36
répondu Ian Goodfellow 2017-11-11 23:06:12

Les réponses ci-dessus ont suffisamment de description pour la question posée.

En plus de cela, Tensorflow a optimisé l'opération d'application de la fonction d'activation puis de calcul du coût en utilisant sa propre activation suivie de fonctions de coût. C'est donc une bonne pratique d'utiliser: tf.nn.softmax_cross_entropy() over tf.nn.softmax(); tf.nn.cross_entropy()

Vous pouvez trouver une différence importante entre eux dans un modèle gourmand en ressources.

1
répondu Abish 2017-07-19 07:25:41

Logit est une fonction qui mappe les probabilités [0, 1] à [- inf, + inf]. Tensorflow "avec logit": cela signifie que vous appliquez une fonction softmax aux nombres logit pour les normaliser. Le input_vector / logit n'est pas normalisé et peut évoluer à partir de [- inf, inf].

Cette normalisation est utilisée pour les problèmes de classification multiclasse. Et pour les problèmes de classification multilabel, la normalisation sigmoïde est utilisée, c'est-à-dire tf.nn.sigmoid_cross_entropy_with_logits

0
répondu jayesh 2018-07-08 06:44:12