2016-05-19 17 views
46

Ich bin kürzlich auf tf.nn.sparse_softmax_cross_entropy_with_logits gestoßen und ich kann nicht herausfinden, was der Unterschied im Vergleich zu tf.nn.softmax_cross_entropy_with_logits ist.TensorFlow: Was ist der Unterschied zwischen sparse_softmax_cross_entropy_with_logits und softmax_cross_entropy_with_logits?

Ist der einzige Unterschied, dass Trainingsvektoren yone-hot encoded sein müssen, wenn sparse_softmax_cross_entropy_with_logits verwendet wird?

Lesen der API Ich konnte keinen anderen Unterschied im Vergleich zu softmax_cross_entropy_with_logits finden ... aber warum brauchen wir dann die Extra-Funktion?

Sollte nicht softmax_cross_entropy_with_logits die gleichen Ergebnisse wie sparse_softmax_cross_entropy_with_logits produzieren, wenn es mit One-hot codierten Trainingsdaten/Vektoren geliefert wird?

+0

Ich bin daran interessiert, einen Vergleich ihrer Leistung zu sehen, wenn beide verwendet werden können (z. B. mit exklusiven Bildbeschriftungen); Ich würde erwarten, dass die Sparse-Version zumindest im Hinblick auf die Speicherkapazität effizienter ist. –

+0

Siehe auch [diese Frage] (https://stackoverflow.com/q/47034888/712995), die * alle Cross-Entropie-Funktionen * im Tensorflow behandelt (es gibt viele davon). – Maxim

Antwort

81

Mit zwei verschiedenen Funktionen ist eine Bequemlichkeit, da sie das gleiche Ergebnis produzieren.

Der Unterschied ist einfach:

  • Für sparse_softmax_cross_entropy_with_logits, Etiketten die Form [batch_size] und die dtype int32 oder int64 haben muss. Jedes Etikett ist ein int im Bereich [0, num_classes-1].
  • Für softmax_cross_entropy_with_logits müssen Beschriftungen die Form [batch_size, num_classes] und dtype float32 oder float64 haben.

in softmax_cross_entropy_with_logits verwendet Labels sind die eine heiße Version von in sparse_softmax_cross_entropy_with_logits verwendeten Etiketten.

Ein weiterer kleiner Unterschied ist, dass mit sparse_softmax_cross_entropy_with_logits, geben Sie -1 als Etikett Verlust 0 auf diesem Etikett.

+5

Ist die -1 korrekt? Wie die Dokumentation liest: "Jeder Eintrag in Beschriftungen muss ein Index in [0, num_classes] sein. Andere Werte werden eine Ausnahme auslösen, wenn dieser Op auf CPU ausgeführt wird, und NaN für entsprechende Verlust- und Farbverlaufszeilen auf GPU zurückgeben." – user1761806

12

Ich möchte nur 2 Dinge zur akzeptierten Antwort hinzufügen, die Sie auch in TF-Dokumentation finden können.

Erstens:

tf.nn.softmax_cross_entropy_with_logits

HINWEIS: Während die Klassen gegenseitig ausschließen, ihre Wahrscheinlichkeiten muss nicht sein. Alles, was erforderlich ist, ist, dass jede Reihe von Etiketten eine gültige Wahrscheinlichkeitsverteilung ist. Wenn nicht, ist die Berechnung von der Gradient falsch.

Zweitens:

tf.nn.sparse_softmax_cross_entropy_with_logits

HINWEIS: Bei diesem Vorgang wird die Wahrscheinlichkeit eines bestimmten Label exklusiv betrachtet. Das heißt, weiche Klassen sind nicht zulässig, und der Etikettenvektor muss einen einzelnen spezifischen Index für die wahre Klasse für jede Reihe von Logits (jeden Minibucheintrag) bereitstellen.

+4

Was sollten wir verwenden, wenn sich die Klassen nicht gegenseitig ausschließen? Ich meine, wenn wir mehrere kategorische Labels kombinieren? – Hayro

+0

Ich lese das auch. Es bedeutet also, dass wir die Klassenwahrscheinlichkeit auf die Kreuzentropie anwenden, anstatt sie als einen Ein-Vektor zu betrachten. –

+0

@Hayro - Meinst du, du kannst keine Hot Encoding machen? Ich denke, man müsste sich ein anderes Modell ansehen. [This] (http://ufldl.stanford.edu/wiki/index.php/Softmax_Regression) erwähnte etwas wie "es wäre angemessener, 4 binäre logistische Regressions-Klassifikatoren zu bauen". Zuerst stellen Sie sicher, dass Sie die Klassen trennen können. – ashley

8

Beide Funktionen berechnet die gleichen Ergebnisse und sparse_softmax_cross_entropy_with_logits berechnet die Kreuzentropie direkt auf die Etiketten sparse anstatt sie mit one-hot encoding umwandelt.

Sie können dies überprüfen, indem Sie das folgende Programm ausgeführt wird:

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 

Hier erstelle ich einen zufälligen logits Vektor der Länge dims und erzeugen one-hot kodierten Etikett (wo Element in pos 1 ist und andere sind 0) .

Danach berechne ich softmax und sparse softmax und vergleiche ihre Ausgabe. Versuchen Sie es ein paar Mal erneut auszuführen, um sicherzustellen, dass es immer die gleiche Ausgabe erzeugt.