web-dev-qa-db-de.com

Was ist logits, softmax und softmax_cross_entropy_with_logits?

Ich habe die Tensorflow-API-Dokumente durchgesehen hier . In der Tensorflow-Dokumentation wurde ein Schlüsselwort namens logits verwendet. Was ist es? Bei vielen Methoden in den API-Dokumenten ist es so geschrieben

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

Wenn geschrieben steht, dass diese logits nur Tensors sind, warum einen anderen Namen wie logits behalten?

Eine andere Sache ist, dass es zwei Methoden gibt, die ich nicht unterscheiden konnte. Sie sind

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

Was sind die Unterschiede zwischen ihnen? Die Dokumente sind mir nicht klar. Ich weiß, was tf.nn.softmax macht. Aber nicht die andere. Ein Beispiel wird sehr hilfreich sein.

318
Shubhashis

Logs bedeuten einfach, dass die Funktion mit der nicht skalierten Ausgabe früherer Layer arbeitet und dass der relative Maßstab zum Verständnis der Einheiten linear ist. Dies bedeutet insbesondere, dass die Summe der Eingaben möglicherweise nicht gleich 1 ist und dass die Werte keine Wahrscheinlichkeiten sind (möglicherweise haben Sie eine Eingabe von 5).

_tf.nn.softmax_ erzeugt nur das Ergebnis der Anwendung der Softmax-Funktion auf einen Eingangstensor. Der Softmax "quetscht" die Eingaben, so dass sum(input) = 1: eine Art der Normalisierung. Die Ausgabeform eines Softmax entspricht der Eingabe: Sie normalisiert lediglich die Werte. Die Ausgaben von softmax können als Wahrscheinlichkeiten interpretiert werden.

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

Im Gegensatz dazu berechnet _tf.nn.softmax_cross_entropy_with_logits_ die Querentropie des Ergebnisses nach Anwendung der Softmax-Funktion (aber dies alles zusammen auf mathematisch sorgfältigere Weise). Es ist ähnlich wie das Ergebnis von:

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

Die Kreuzentropie ist eine zusammenfassende Metrik: Sie summiert sich über die Elemente. Die Ausgabe von _tf.nn.softmax_cross_entropy_with_logits_ auf einem Formtensor _[2,5]_ hat die Form _[2,1]_ (die erste Dimension wird als Stapel behandelt).

Wenn Sie eine Optimierung durchführen möchten, um die Kreuzentropie UND zu minimieren, die Sie nach Ihrer letzten Ebene softmaxen, sollten Sie stattdessen _tf.nn.softmax_cross_entropy_with_logits_ verwenden es selbst zu tun, weil es numerisch instabile Eckfälle auf mathematisch richtige Weise abdeckt. Andernfalls hacken Sie es, indem Sie hier und da kleine Epsilons hinzufügen.

Bearbeitet am 07.02.2016: Wenn Sie Beschriftungen für eine einzelne Klasse haben, bei denen ein Objekt nur zu einer Klasse gehören kann, sollten Sie jetzt _tf.nn.sparse_softmax_cross_entropy_with_logits_, damit Sie Ihre Etiketten nicht in ein dichtes One-Hot-Array konvertieren müssen. Diese Funktion wurde nach Release 0.6.0 hinzugefügt.

394
dga

Kurzfassung:

Angenommen, Sie haben zwei Tensoren, wobei y_hat berechnete Punkte für jede Klasse enthält (z. B. aus y = W * x + b) und y_true one-hot-codierte echte Bezeichnungen enthält.

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

Wenn Sie die Scores in y_hat als nicht normalisierte Log-Wahrscheinlichkeiten interpretieren, handelt es sich um Logs .

Zusätzlich wird der gesamte Kreuzentropieverlust auf diese Weise berechnet:

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

entspricht im Wesentlichen dem mit der Funktion softmax_cross_entropy_with_logits() berechneten Gesamt-Entropieverlust:

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

Lange Version:

In der Ausgabeebene Ihres neuronalen Netzwerks werden Sie wahrscheinlich ein Array berechnen, das die Klassenwerte für jede Ihrer Trainingsinstanzen enthält, z. B. aus einer Berechnung y_hat = W*x + b. Als Beispiel habe ich unten ein y_hat als 2 x 3-Array erstellt, wobei die Zeilen den Trainingsinstanzen und die Spalten den Klassen entsprechen. Hier gibt es also 2 Trainingsinstanzen und 3 Klassen.

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]])

Beachten Sie, dass die Werte nicht normalisiert sind (d. H. Die Zeilen addieren sich nicht zu 1). Um sie zu normalisieren, können wir die Softmax-Funktion anwenden, die die Eingabe als nicht normalisierte Log-Wahrscheinlichkeiten (aka logits ) interpretiert und normalisierte lineare Wahrscheinlichkeiten ausgibt.

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]])

Es ist wichtig zu verstehen, was der Softmax-Ausgang sagt. Unten habe ich eine Tabelle gezeigt, die die Ausgabe oben deutlicher darstellt. Es ist ersichtlich, dass zum Beispiel die Wahrscheinlichkeit, dass die Trainingsinstanz 1 "Klasse 2" ist, 0,619 beträgt. Die Klassenwahrscheinlichkeiten für jede Trainingsinstanz sind normalisiert, sodass die Summe jeder Zeile 1,0 beträgt.

                      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

Jetzt haben wir Klassenwahrscheinlichkeiten für jede Trainingsinstanz, in der wir das argmax () jeder Zeile verwenden können, um eine endgültige Klassifizierung zu erstellen. Von oben können wir erzeugen, dass die Trainingsinstanz 1 zu "Klasse 2" und die Trainingsinstanz 2 zu "Klasse 1" gehört.

Sind diese Klassifikationen korrekt? Wir müssen uns an den richtigen Etiketten aus dem Trainingsset messen. Sie benötigen ein One-Hot-codiertes y_true -Array, in dem die Zeilen wiederum Trainingsinstanzen und die Spalten Klassen sind. Unten habe ich ein Beispiel y_true One-Hot-Array erstellt, in dem die wahre Bezeichnung für Trainingsinstanz 1 "Klasse 2" und die wahre Bezeichnung für Trainingsinstanz 2 "Klasse 3" lautet.

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.]])

Liegt die Wahrscheinlichkeitsverteilung in y_hat_softmax in der Nähe der Wahrscheinlichkeitsverteilung in y_true? Wir können Kreuzentropieverlust verwenden, um den Fehler zu messen.

Formula for cross-entropy loss

Wir können den Cross-Entropy-Verlust zeilenweise berechnen und die Ergebnisse anzeigen. Unten sehen wir, dass Trainingsinstanz 1 einen Verlust von 0,479 hat, während Trainingsinstanz 2 einen höheren Verlust von 1.200 hat. Dieses Ergebnis ist sinnvoll, da in unserem obigen Beispiel y_hat_softmax zeigte, dass die höchste Wahrscheinlichkeit für Trainingsinstanz 1 für "Klasse 2" lag, was mit Trainingsinstanz 1 in y_true übereinstimmt. Die Vorhersage für die Trainingsinstanz 2 zeigte jedoch die höchste Wahrscheinlichkeit für "Klasse 1", die nicht mit der wahren Klasse "Klasse 3" übereinstimmt.

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])

Was wir wirklich wollen, ist der Gesamtverlust über alle Trainingsinstanzen. So können wir berechnen:

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

Verwenden von softmax_cross_entropy_with_logits ()

Wir können stattdessen den gesamten Kreuzentropieverlust mit der Funktion tf.nn.softmax_cross_entropy_with_logits() berechnen, wie unten gezeigt.

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

Beachten Sie, dass total_loss_1 und total_loss_2 im Wesentlichen äquivalente Ergebnisse mit einigen kleinen Unterschieden in den letzten Ziffern liefern. Sie können jedoch auch den zweiten Ansatz verwenden: Er benötigt eine Codezeile weniger und akkumuliert weniger numerische Fehler, da der Softmax innerhalb von softmax_cross_entropy_with_logits() für Sie durchgeführt wird.

260

tf.nn.softmax berechnet die Vorwärtsausbreitung durch eine Softmax-Schicht. Sie verwenden es während Auswertung des Modells, wenn Sie die Wahrscheinlichkeiten berechnen, die das Modell ausgibt.

tf.nn.softmax_cross_entropy_with_logits berechnet die Kosten für eine Softmax-Schicht. Es wird nur während Training verwendet.

Die Logs sind die nicht normalisierten Log-Wahrscheinlichkeiten , die das Modell ausgeben (die Werte, die ausgegeben wurden, bevor die Softmax-Normalisierung auf sie angewendet wurde).

46
Ian Goodfellow

Die obigen Antworten enthalten eine ausreichende Beschreibung für die gestellte Frage.

Zusätzlich hat Tensorflow die Anwendung der Aktivierungsfunktion optimiert und anschließend die Kosten mithilfe der eigenen Aktivierung und anschließend der Kostenfunktionen berechnet. Daher ist es eine gute Praxis, Folgendes zu verwenden: tf.nn.softmax_cross_entropy() über tf.nn.softmax(); tf.nn.cross_entropy()

In einem ressourcenintensiven Modell können Sie einen deutlichen Unterschied zwischen ihnen feststellen.

3
Abish

Was immer an softmax geht, ist logit, das wiederholt J. Hinton die ganze Zeit in Coursera-Videos.

1
prosti