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?


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.


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).


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

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.