Jaka jest różnica między sparse_softmax_cross_entropy_with_logits i softmax_cross_entropy_with_logits?

111

Niedawno natknąłem się na tf.nn.sparse_softmax_cross_entropy_with_logits i nie mogę zrozumieć, jaka jest różnica w porównaniu do tf.nn.softmax_cross_entropy_with_logits .

Czy jedyną różnicą jest to, że wektory szkoleniowe ymuszą być zakodowane na gorąco podczas używania sparse_softmax_cross_entropy_with_logits?

Czytając API, nie mogłem znaleźć żadnej innej różnicy w porównaniu z softmax_cross_entropy_with_logits. Ale dlaczego potrzebujemy wtedy dodatkowej funkcji?

Czy nie powinien softmax_cross_entropy_with_logitsdawać takich samych wyników, jak sparse_softmax_cross_entropy_with_logitsgdyby był dostarczany z zakodowanymi na gorąco danymi / wektorami uczącymi?

daniel451
źródło
1
Interesuje mnie porównanie ich wydajności, jeśli można użyć obu (np. Z ekskluzywnymi etykietami graficznymi); Spodziewałbym się, że rzadka wersja będzie bardziej wydajna, przynajmniej pod względem pamięci.
Yibo Yang
1
Zobacz także to pytanie , które omawia wszystkie funkcje cross-entropii w tensorflow (okazuje się, że jest ich wiele).
Maxim

Odpowiedzi:

175

Posiadanie dwóch różnych funkcji jest wygodą , ponieważ dają ten sam wynik.

Różnica jest prosta:

  • W przypadku sparse_softmax_cross_entropy_with_logitsetykiety muszą mieć kształt [rozmiar_batchu] i typ dtype int32 lub int64. Każda etykieta jest int w zakresie [0, num_classes-1].
  • W przypadku softmax_cross_entropy_with_logitsetykiety muszą mieć kształt [batch_size, num_classes] i dtype float32 lub float64.

Etykiety używane w programie softmax_cross_entropy_with_logitsto jedyna gorąca wersja etykiet używanych w programie sparse_softmax_cross_entropy_with_logits.

Inną niewielką różnicą jest to sparse_softmax_cross_entropy_with_logits, że możesz podać -1 jako etykietę, aby uzyskać stratę 0na tej etykiecie.

Olivier Moindrot
źródło
15
Czy -1 jest poprawne? Jak czytamy w dokumentacji: "Każdy wpis w etykietach musi być indeksem w [0, num_classes). Inne wartości spowodują wyjątek, gdy ta operacja zostanie uruchomiona na CPU i zwrócą NaN dla odpowiednich strat i rzędów gradientu na GPU."
user1761806
1
[0, num_classes) = [0, num_classes-1]
Karthik C
24

Chciałbym tylko dodać 2 rzeczy do zaakceptowanej odpowiedzi, które można również znaleźć w dokumentacji TF.

Pierwszy:

tf.nn.softmax_cross_entropy_with_logits

UWAGA: Chociaż klasy wykluczają się wzajemnie, ich prawdopodobieństwa nie muszą. Wymagane jest tylko, aby każdy wiersz etykiet był prawidłowym rozkładem prawdopodobieństwa. Jeśli tak nie jest, obliczenie gradientu będzie nieprawidłowe.

Druga:

tf.nn.sparse_softmax_cross_entropy_with_logits

UWAGA: W przypadku tej operacji prawdopodobieństwo danej etykiety jest traktowane jako wyłączne. Oznacza to, że miękkie klasy są niedozwolone, a wektor etykiet musi zapewniać jeden określony indeks dla prawdziwej klasy dla każdego wiersza logitów (każdego wpisu w minibatch).

Drag0
źródło
4
Czego powinniśmy użyć, jeśli klasy nie wykluczają się wzajemnie. Mam na myśli, jeśli łączymy wiele etykiet kategorialnych?
Hayro
Ja też to czytałem. Oznacza to, że stosujemy prawdopodobieństwo klasowe do entropii krzyżowej, zamiast traktować ją jako wektor jednostronny.
Shamane Siriwardhana
@Hayro - Czy masz na myśli to, że nie możesz wykonać jednego gorącego kodowania? Myślę, że musiałbyś spojrzeć na inny model. Wspomniano o czymś w rodzaju: „właściwsze byłoby zbudowanie 4 binarnych klasyfikatorów regresji logistycznej”. Aby najpierw upewnić się, że można rozdzielić klasy.
Ashley
21

Obie funkcje obliczają te same wyniki, a sparse_softmax_cross_entropy_with_logits oblicza entropię krzyżową bezpośrednio na rzadkich etykietach zamiast konwertować je za pomocą kodowania na gorąco .

Możesz to sprawdzić, uruchamiając następujący program:

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

Tutaj tworzę losowy logitswektor długości dimsi generuję zakodowane na gorąco etykiety (gdzie element w posto 1, a inne to 0).

Następnie obliczam softmax i sparse softmax i porównuję ich wyniki. Spróbuj uruchomić go ponownie kilka razy, aby upewnić się, że zawsze daje ten sam wynik

Salvador Dali
źródło