2016-05-19 28 views
46

Recentemente mi sono imbattuto in tf.nn.sparse_softmax_cross_entropy_with_logits e non riesco a capire quale sia la differenza rispetto a tf.nn.softmax_cross_entropy_with_logits.TensorFlow: qual è la differenza tra sparse_softmax_cross_entropy_with_logits e softmax_cross_entropy_with_logits?

L'unica differenza che i vettori di allenamento devono essere one-hot encoded quando si utilizza sparse_softmax_cross_entropy_with_logits?

Leggere l'API Non sono riuscito a trovare altre differenze rispetto a softmax_cross_entropy_with_logits ... ma perché è necessaria la funzione extra?

Non dovrebbe softmax_cross_entropy_with_logits produrre gli stessi risultati di sparse_softmax_cross_entropy_with_logits, se viene fornito con dati/vettori di allenamento codificati a una temperatura elevata?

+0

Sono interessato a vedere un confronto delle loro prestazioni se entrambe possono essere utilizzate (ad esempio con etichette di immagini esclusive); Mi aspetto che la versione sparsa sia più efficiente, almeno per quanto riguarda la memoria. –

+0

Vedere anche [questa domanda] (https://stackoverflow.com/q/47034888/712995), che tratta * di tutte le funzioni di cross-entropy * in tensorflow (risulta che ce ne sono molte). – Maxim

risposta

81

Avere due diverse funzioni è una convenienza , poiché producono lo stesso risultato.

La differenza è semplice:

  • Per sparse_softmax_cross_entropy_with_logits, le etichette devono avere la forma [batch_size] ei int32 DTYPE o Int64. Ogni etichetta è un intervallo compreso tra [0, num_classes-1].
  • Per softmax_cross_entropy_with_logits, le etichette devono avere la forma [batch_size, num_classes] e dtype float32 o float64.

etichette utilizzate nel softmax_cross_entropy_with_logits sono la una versione caldo di etichette utilizzate in sparse_softmax_cross_entropy_with_logits.

Un'altra piccola differenza è che con sparse_softmax_cross_entropy_with_logits, è possibile assegnare a 1 come etichetta la perdita 0 su questa etichetta.

+5

Il -1 è corretto? Come si legge nella documentazione: "Ogni voce nelle etichette deve essere un indice in [0, num_classes.] Altri valori generano un'eccezione quando questo op viene eseguito su CPU e restituiscono NaN per le corrispondenti righe di perdita e di gradiente su GPU." – user1761806

12

Vorrei solo aggiungere 2 cose alla risposta accettata che è possibile trovare anche nella documentazione TF.

Primo:

tf.nn.softmax_cross_entropy_with_logits

NOTA: Durante le classi sono mutuamente esclusive, le loro probabilità non devono essere. Tutto ciò che è richiesto è che ogni riga di etichette sia una distribuzione di probabilità valida . Se non lo sono, il calcolo del gradiente non sarà corretto.

Secondo:

tf.nn.sparse_softmax_cross_entropy_with_logits

NOTA: Per questa operazione, la probabilità di una determinata etichetta è considerata esclusiva. Ovvero, le classi software non sono consentite e il vettore di etichette deve fornire un singolo indice specifico per la classe reale per ogni riga di logits (ogni voce di minibatch).

+4

Cosa dovremmo usare se le classi non si escludono a vicenda. Voglio dire se stiamo combinando più etichette categoriali? – Hayro

+0

Ho letto anche questo. Quindi significa che applichiamo la probabilità di classe sull'entropia incrociata piuttosto che considerarla come un vettore istantaneo. –

+0

@ Hayro - Vuoi dire che non sei in grado di fare una codifica a caldo? Penso che dovresti guardare un modello diverso. [Questo] (http://ufldl.stanford.edu/wiki/index.php/Softmax_Regression) ha menzionato qualcosa come "sarebbe più appropriato costruire 4 classificatori di regressione logistica binaria" Per prima cosa assicurati di poter separare le classi. – ashley

8

Entrambe le funzioni calcola gli stessi risultati e sparse_softmax_cross_entropy_with_logits calcola l'entropia croce direttamente sulle etichette sparse invece di convertirli con one-hot encoding.

È possibile verificare ciò eseguendo il seguente programma:

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 

Qui crea un casuale logits vettore di lunghezza dims e generare etichette di una vasca codificati (dove elemento in pos è 1 e altri sono 0) .

Successivamente, calcolo softmax e sparse softmax e ne confronta l'output. Prova a ripetere l'operazione alcune volte per assicurarti che produca sempre la stessa uscita