Was sind logits, softmax und softmax_cross_entropy_with_logits?

Ich habe hier die Tensorflow-API-Dokumentation gelesen. In der Tensorflow-Dokumentation verwendeten sie ein Schlüsselwort namens logits . Was ist es? In vielen Methoden in der API-Dokumentation ist es wie geschrieben

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

Wenn was geschrieben wird, sind diese logits nur Tensors , warum sollte man einen anderen Namen wie logits ?

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 Unterlagen sind mir nicht klar. Ich weiß, was tf.nn.softmax macht. Aber nicht der andere. Ein Beispiel wird sehr hilfreich sein.

    Logits bedeutet einfach, dass die function auf der unskalierten Ausgabe früherer Schichten arbeitet und dass die relative Skala zum Verständnis der Einheiten linear ist. Es bedeutet insbesondere, dass die Summe der Eingaben nicht gleich 1 ist, dass die Werte keine Wahrscheinlichkeiten sind (Sie könnten eine Eingabe von 5 haben).

    tf.nn.softmax erzeugt nur das Ergebnis der Anwendung der softmax-function auf einen Eingangstensor. Der Softmax “quetscht” die Eingaben so, dass Summe (Eingang) = 1; Es ist eine Art der Normalisierung. Die Form der Ausgabe eines Softmax ist die gleiche wie die Eingabe – es normalisiert nur 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 tf.nn.softmax_cross_entropy_with_logits berechnet tf.nn.softmax_cross_entropy_with_logits die Kreuzentropie des Ergebnisses nach dem Anwenden der softmax-function (aber es macht alles mathematisch vorsichtiger). Es ist ähnlich dem Ergebnis von:

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

    Die Kreuz-Entropie ist eine Summenmetrik – sie summiert sich über die Elemente. Die Ausgabe von tf.nn.softmax_cross_entropy_with_logits auf einem Form [2,5] tensor hat die Form [2,1] (die erste Dimension wird als Stapel behandelt).

    Wenn Sie eine Optimierung durchführen möchten, um die Kreuzentropie zu minimieren, und Sie nach der letzten Ebene softmax sind, sollten Sie tf.nn.softmax_cross_entropy_with_logits anstatt es selbst zu tun, da es rechnerisch numerisch instabile tf.nn.softmax_cross_entropy_with_logits abdeckt. Sonst wirst du es hacken, indem du hier und da kleine Epsilons hinzufügst.

    (Edited 2016-02-07: Wenn Sie Single-Class-Labels haben, bei denen ein Objekt nur zu einer class gehören kann, sollten Sie jetzt tf.nn.sparse_softmax_cross_entropy_with_logits damit Sie Ihre Labels nicht in eine dichte konvertieren müssen One-Hot Array. Diese function wurde nach Version 0.6.0 hinzugefügt.)

    Kurze Version:

    Angenommen, Sie haben zwei Tensoren, wobei y_hat berechnete Werte für jede class enthält (z. B. von y = W * x + b), und y_true enthält y_true codierte echte Etiketten.

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

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

    Zusätzlich wird der gesamte auf diese Weise berechnete Cross-Entropie-Verlust 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 Gesamt-Kreuz-Entropie-Verlust, der mit der function softmax_cross_entropy_with_logits() berechnet wurde:

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

    Lange Version:

    In der Ausgabeschicht Ihres neuronalen Netzwerks werden Sie wahrscheinlich ein Array berechnen, das die classnwerte für jede Ihrer Trainingsinstanzen enthält, beispielsweise aus einer Berechnung y_hat = W*x + b . Um als Beispiel zu dienen, habe ich unten ein y_hat als 2 x 3-Array erstellt, wobei die Zeilen den Trainingsinstanzen entsprechen und die Spalten den classn entsprechen. Also hier gibt es 2 Trainingsinstanzen und 3 classn.

     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 (dh die Zeilen addieren sich nicht zu 1). Um sie zu normalisieren, können wir die softmax-function 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 obige Ausgabe deutlicher darstellt. Es ist ersichtlich, dass zum Beispiel die Wahrscheinlichkeit, dass Instanz 1 “class 2” ist, 0,619 ist. Die classnwahrscheinlichkeiten für jede Trainingsinstanz sind normalisiert, so dass die Summe jeder Zeile 1,0 ist.

      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 classnwahrscheinlichkeiten für jede Trainingsinstanz, wobei wir argmax () jeder Zeile verwenden können, um eine endgültige Klassifizierung zu generieren. Von oben können wir generieren, dass Trainingsinstanz 1 zu “class 2” und Trainingsinstanz 2 zu “class 1” gehört.

    Sind diese Klassifizierungen korrekt? Wir müssen mit den echten Etiketten aus dem Trainingssatz messen. Sie benötigen ein One-Hot-codiertes y_true Array, wobei wiederum die Zeilen Trainingsinstanzen und Spalten classn sind. Im Folgenden habe ich ein Beispiel für ein y_true one-hot-Array erstellt, bei dem die wahre Bezeichnung für Trainingsinstanz 1 “class 2” und die wahre Bezeichnung für Trainingsinstanz 2 “class 3” ist.

     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 nahe der Wahrscheinlichkeitsverteilung in y_true ? Wir können den Cross-Entropie-Verlust verwenden , um den Fehler zu messen.

    Formel für Kreuz-Entropie-Verlust

    Wir können den Kreuz-Entropie-Verlust zeilenweise berechnen und die Ergebnisse sehen. Unten können wir sehen, 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, weil in unserem obigen Beispiel y_hat_softmax gezeigt hat, dass die höchste Wahrscheinlichkeit für Trainingsinstanz 1 für “class 2” war, was der Trainingsinstanz 1 in y_true ; Die Vorhersage für Trainingsinstanz 2 zeigte jedoch die höchste Wahrscheinlichkeit für “class 1”, die nicht der wahren class “class 3” entspricht.

     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 hinweg. Also 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 Entropieverlust berechnen, indem tf.nn.softmax_cross_entropy_with_logits() function tf.nn.softmax_cross_entropy_with_logits() verwenden, 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 Wesentlichen gleichwertige Ergebnisse mit einigen kleinen Unterschieden in den letzten Ziffern ergeben. Sie können jedoch auch den zweiten Ansatz verwenden: Es dauert eine Zeile weniger Code und akkumuliert weniger numerischen Fehler, da die softmax für Sie innerhalb von softmax_cross_entropy_with_logits() getan wird.

    tf.nn.softmax berechnet die Vorwärtsausbreitung durch eine Softmax-Schicht. Sie verwenden es während der Evaluierung des Modells, wenn Sie die vom Modell ausgegebenen Wahrscheinlichkeiten berechnen.

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

    Die Logits sind die nichtnormalisierten Log-Wahrscheinlichkeiten, die das Modell ausgeben (die Werte, die ausgegeben werden, bevor die Softmax-Normalisierung auf sie angewendet wird).

    Die obigen Antworten haben genug Beschreibung für die gestellte Frage.

    Darüber hinaus hat Tensorflow den Vorgang des Anwendens der Aktivierungsfunktion optimiert und dann die Kosten durch eigene Aktivierung gefolgt von Kostenfunktionen berechnet. Daher ist es eine gute tf.nn.softmax_cross_entropy() zu verwenden: tf.nn.softmax_cross_entropy() über tf.nn.softmax(); tf.nn.cross_entropy() tf.nn.softmax(); tf.nn.cross_entropy()

    Sie können einen deutlichen Unterschied zwischen ihnen in einem ressourcenintensiven Modell finden.

    Logit ist eine function, die Wahrscheinlichkeiten [0, 1] auf [-inf, + inf] abbildet. Tensorflow “mit Logit”: Dies bedeutet, dass Sie eine Softmax-function anwenden, um Logit-Nummern zu normalisieren. Der input_vector / logit ist nicht normalisiert und kann von [-inf, inf] skaliert werden.

    Diese Normalisierung wird für Klassifikationsprobleme mit mehreren classn verwendet. Und für Multilabel-Klassifizierungsprobleme wird eine Sigmoid-Normalisierung verwendet, dh tf.nn.sigmoid_cross_entropy_with_logits