web-dev-qa-db-fra.com

Qu'est-ce que logits, softmax et softmax_cross_entropy_with_logits?

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

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

Si ce qui est écrit est que ces logits ne sont que Tensors, pourquoi garder un nom différent comme logits?

Une autre chose est qu'il y a deux méthodes que je ne pourrais 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 docs ne sont pas clairs pour moi. Je sais ce que tf.nn.softmax fait. Mais pas l'autre. Un exemple sera vraiment utile.

318
Shubhashis

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

tf.nn.softmax produit uniquement le résultat de l'application de fonction softmax à un tenseur d'entrée. Le softmax "écrase" les entrées pour que sum(input) = 1: soit un moyen de normalisation. La forme de la sortie d'un softmax est identique à celle de 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 le fait tous ensemble d'une manière plus mathématiquement plus prudente). C'est semblable au résultat de:

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

L'entropie croisée est une métrique récapitulative: elle consiste à faire la somme de tous les éléments. La sortie de tf.nn.softmax_cross_entropy_with_logits sur une forme [2,5] tenseur est de forme [2,1] (la première dimension est traitée comme un lot).

Si vous souhaitez effectuer une optimisation afin de minimiser l'entropie croisée ET après la dernière couche, vous devez utiliser tf.nn.softmax_cross_entropy_with_logits à la place. de le faire vous-même, car il couvre mathématiquement les cas de coin instables numériquement. Sinon, vous finirez par le pirater en ajoutant de petits epsilons ici et là.

Modifié le 17/02/2016: Si vous avez des étiquettes à une seule classe, dans lesquelles un objet ne peut appartenir qu'à une seule classe, vous pouvez maintenant envisager d'utiliser tf.nn.sparse_softmax_cross_entropy_with_logits afin que vous n'ayez pas à convertir vos étiquettes en un tableau dense à une seule tâche. Cette fonction a été ajoutée après la version 0.6.0.

394
dga

Version abrégée:

Supposons que vous avez deux tenseurs, où y_hat contient les scores calculés pour chaque classe (par exemple, 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 de journal non normalisées, il s'agit alors de logits .

De plus, la perte totale par 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 équivalente à la perte totale d'entropie croisée calculée 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 de neurones, vous calculerez probablement un tableau contenant les scores de classe pour chacune de vos instances de formation, par exemple à partir d'un calcul y_hat = W*x + b. Pour servir d'exemple, j'ai créé ci-dessous un y_hat sous la forme d'un tableau 2 x 3, où les lignes correspondent aux instances de formation et les colonnes correspondent aux classes. Donc, ici, il y a 2 instances de formation et 3 classes.

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 totalisent pas 1). Afin de les normaliser, nous pouvons appliquer la fonction softmax, qui interprète l'entrée comme des probabilités de journal non normalisées (ou 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. On peut voir que, par exemple, la probabilité que l'instance de formation 1 soit "Classe 2" est de 0,619. Les probabilités de classe pour chaque instance d'apprentissage étant normalisées, la somme de chaque ligne est égale à 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 de formation, où nous pouvons utiliser la méthode argmax () de chaque ligne pour générer une classification finale. De là-haut, nous pouvons générer que l'instance de formation 1 appartient à la "classe 2" et l'instance de formation 2 à la "classe 1".

Ces classifications sont-elles correctes? Nous devons mesurer par rapport aux véritables étiquettes de l'ensemble de formation. Vous aurez besoin d'un tableau y_true codé à chaud, où encore une fois, les lignes sont des instances d'apprentissage et les colonnes sont des classes. J'ai créé ci-dessous un exemple de tableau y_true one-hot où le véritable libellé de l'instance d'apprentissage 1 est "Classe 2" et le véritable libellé de l'instance d'apprentissage 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.]])

La distribution de probabilité dans y_hat_softmax est-elle proche de la distribution de probabilité dans y_true? Nous pouvons utiliser perte d'entropie croisée pour mesurer l'erreur.

Formula for cross-entropy loss

Nous pouvons calculer la perte d'entropie croisée par rangée et voir les résultats. Nous pouvons voir ci-dessous que l'instance de formation 1 a une perte de 0,479, tandis que l'instance de formation 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 de formation 1 était pour "Classe 2", ce qui correspond à l'instance de formation 1 dans y_true; toutefois, la prédiction pour l'instance de formation 2 indiquait une probabilité plus élevée de "classe 1", ce 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 de formation. 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 à l'aide de 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 différences minimes dans les derniers chiffres. Cependant, vous pouvez aussi bien utiliser la seconde approche: elle prend une ligne de code en moins et génère moins d’erreurs numériques car la softmax est faite pour vous dans softmax_cross_entropy_with_logits().

260

tf.nn.softmax calcule la propagation en avant via une couche softmax. Vous l'utilisez pendant evaluation du modèle lorsque vous calculez les probabilités que le modèle génère.

tf.nn.softmax_cross_entropy_with_logits calcule le coût d'un calque softmax. Il est utilisé uniquement pendant training.

Les logits sont les probabilités de journal non normalisées générées par le modèle (les valeurs générées avant l'application de la normalisation softmax).

46
Ian Goodfellow

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

En plus de cela, Tensorflow a optimisé l'opération consistant à appliquer la fonction d'activation, puis à calculer le coût à l'aide de sa propre activation suivie de fonctions de coût. Par conséquent, il est recommandé d'utiliser: tf.nn.softmax_cross_entropy() sur tf.nn.softmax(); tf.nn.cross_entropy()

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

3
Abish

Tout ce qui se passe à softmax est logit, c'est ce que J. Hinton répète tout le temps dans les vidéos de coursera.

1
prosti