Qual è la differenza tra sparse_softmax_cross_entropy_with_logits e softmax_cross_entropy_with_logits?


111

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 .

L'unica differenza è che i vettori di addestramento ydevono essere codificati a caldo quando si usano sparse_softmax_cross_entropy_with_logits?

Leggendo l'API, non sono riuscito a trovare altre differenze rispetto a softmax_cross_entropy_with_logits. Ma allora perché abbiamo bisogno della funzione extra?

Non dovrebbe softmax_cross_entropy_with_logitsprodurre gli stessi risultati di sparse_softmax_cross_entropy_with_logits, se viene fornito con dati / vettori di addestramento con codifica singola?


1
Sono interessato a vedere un confronto delle loro prestazioni se entrambi possono essere utilizzati (ad esempio con etichette di immagini esclusive); Mi aspetto che la versione sparsa sia più efficiente, almeno dal punto di vista della memoria.
Yibo Yang

1
Vedi anche questa domanda , che discute tutte le funzioni di entropia incrociata in tensorflow (risulta che ce ne sono molte).
Maxim

Risposte:


175

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

La differenza è semplice:

  • Per sparse_softmax_cross_entropy_with_logits, le etichette devono avere la forma [batch_size] e il dtype int32 o int64. Ogni etichetta è un int nell'intervallo [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.

Le etichette utilizzate in softmax_cross_entropy_with_logitssono l' unica versione calda delle etichette utilizzate in sparse_softmax_cross_entropy_with_logits.

Un'altra piccola differenza è che con sparse_softmax_cross_entropy_with_logits, puoi dare -1 come etichetta per avere una perdita 0su questa etichetta.


15
Il -1 è corretto? Come si legge nella documentazione: "Ogni voce nelle etichette deve essere un indice in [0, num_classes). Altri valori solleveranno un'eccezione quando questa operazione viene eseguita sulla CPU e restituirà NaN per la perdita corrispondente e le righe sfumate sulla GPU."
user1761806

1
[0, num_classes) = [0, num_classes-1]
Karthik C

24

Vorrei solo aggiungere 2 cose alla risposta accettata che puoi trovare anche nella documentazione di TF.

Primo:

tf.nn.softmax_cross_entropy_with_logits

NOTA: sebbene le classi si escludano a vicenda, le loro probabilità non devono esserlo. Tutto ciò che è richiesto è che ogni riga di etichette sia una distribuzione di probabilità valida. In caso contrario, il calcolo del gradiente non sarà corretto.

Secondo:

tf.nn.sparse_softmax_cross_entropy_with_logits

NOTA: per questa operazione, la probabilità di una data etichetta è considerata esclusiva. Cioè, le classi soft non sono consentite e il vettore delle etichette deve fornire un singolo indice specifico per la vera classe per ogni riga di logit (ciascuna voce di minibatch).


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

Ho letto anche questo. Quindi significa che applichiamo la probabilità di classe all'entropia incrociata piuttosto che prenderla come un vettore onehot.
Shamane Siriwardhana

@ Hayro - Vuoi dire che non sei in grado di fare una codifica a caldo? Penso che dovresti guardare un modello diverso. Questo menzionava qualcosa del tipo "sarebbe più appropriato costruire 4 classificatori di regressione logistica binaria" Per assicurarti prima di poter separare le classi.
Ashley

21

Entrambe le funzioni calcolano gli stessi risultati e sparse_softmax_cross_entropy_with_logits calcola l'entropia incrociata direttamente sulle etichette sparse invece di convertirle con una codifica one-hot .

Puoi verificarlo 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 creo un logitsvettore casuale di lunghezza dimse generi etichette codificate a caldo (dove l'elemento in posè 1 e gli altri sono 0).

Successivamente calcolo softmax e sparse softmax e confronto il loro output. Prova a rieseguirlo alcune volte per assicurarti che produca sempre lo stesso output

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.