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.