Co to jest logits, softmax i softmax cross entropy z logitami?
Przeglądałem dokumenty API tensorflow tutaj . W dokumentacji tensorflow użyto słowa kluczowego o nazwie logits
. O co chodzi? W wielu metodach w dokumentach API jest to napisane jak
tf.nn.softmax(logits, name=None)
Jeśli to, co jest napisane, to te logits
są tylko Tensors
, to po co trzymać inną nazwę jak logits
?
Inną rzeczą jest to, że są dwie metody, których nie mogłem rozróżnić. Byli
tf.nn.softmax(logits, name=None)
tf.nn.softmax_cross_entropy_with_logits(logits, labels, name=None)
Jakie są różnice między nimi? Dokumenty nie są dla mnie jasne. I wiesz, co robi tf.nn.softmax
. Ale nie ten drugi. Przykład będzie bardzo pomocny.
5 answers
Logit oznacza po prostu, że funkcja działa na bezskalowanym wyjściu wcześniejszych warstw i że względna skala do zrozumienia jednostek jest liniowa. Oznacza to w szczególności, że suma wejść może nie być równa 1, że wartości są a nie prawdopodobieństwem(możesz mieć wejście 5).
tf.nn.softmax
generuje tylko wynik zastosowania funkcji softmax do tensora wejściowego. Softmax "zgniata" wejścia tak, że suma (input) = 1; jest to sposób normalizacja. Kształt wyjścia softmax jest taki sam jak wejście-po prostu normalizuje wartości. Wyjście softmax Może być interpretowane jako prawdopodobieństwo.
a = tf.constant(np.array([[.1, .3, .5, .9]]))
print s.run(tf.nn.softmax(a))
[[ 0.16838508 0.205666 0.25120102 0.37474789]]
Natomiast tf.nn.softmax_cross_entropy_with_logits
oblicza entropię krzyżową wyniku po zastosowaniu funkcji softmax (ale robi to wszystko razem w bardziej matematycznie ostrożny sposób). Jest podobny do wyniku:
sm = tf.nn.softmax(x)
ce = cross_entropy(sm)
Entropia krzyżowa jest metryką sumaryczną-sumuje elementy. Wyjście z tf.nn.softmax_cross_entropy_with_logits
Na kształcie [2,5]
tensor jest kształtu [2,1]
(pierwszy wymiar jest traktowany jako zbiór).
Jeśli chcesz zrobić optymalizację, aby zminimalizować entropię krzyżową, a miękisz po ostatniej warstwie, powinieneś użyć tf.nn.softmax_cross_entropy_with_logits
zamiast robić to samemu, ponieważ obejmuje ona numerycznie niestabilne przypadki narożne w matematycznie właściwy sposób. W przeciwnym razie skończysz hakując go, dodając małe epsilony tu i tam.
(edytowane 2016-02-07: jeśli masz etykiety jednoklasowe, jeśli obiekt może należeć tylko do jednej klasy, możesz teraz rozważyć użycie tf.nn.sparse_softmax_cross_entropy_with_logits
, aby nie trzeba było konwertować etykiet do gęstej tablicy o jednym rozgałęzieniu. Ta funkcja została dodana po wydaniu 0.6.0.)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-07 18:30:35
Krótka wersja:
Załóżmy, że masz dwa tensory, gdzie y_hat
zawiera obliczone wyniki dla każdej klasy (na przykład z y = W*x +b), a y_true
zawiera zakodowane na jednym gorąco prawdziwe etykiety.
y_hat = ... # Predicted label, e.g. y = tf.matmul(X, W) + b
y_true = ... # True label, one-hot encoded
Jeśli interpretujesz wyniki w y_hat
jako nieznormalizowane prawdopodobieństwo logowania, to są to logity .
Dodatkowo całkowita strata entropii krzyżowej obliczona w ten sposób:
y_hat_softmax = tf.nn.softmax(y_hat)
total_loss = tf.reduce_mean(-tf.reduce_sum(y_true * tf.log(y_hat_softmax), [1]))
Jest zasadniczo równoważna całkowitej utracie entropii krzyżowej obliczone z funkcją softmax_cross_entropy_with_logits()
:
total_loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(y_hat, y_true))
Wersja długa:
W warstwie wyjściowej Twojej sieci neuronowej prawdopodobnie obliczysz tablicę zawierającą wyniki klas dla każdej z instancji treningowych, na przykład z obliczeń y_hat = W*x + b
. Aby służyć jako przykład, poniżej stworzyłem y_hat
jako tablicę 2 x 3, gdzie wiersze odpowiadają instancjom treningowym, a kolumny klasom. Więc tutaj są 2 instancje treningowe i 3 klasy.
import tensorflow as tf
import numpy as np
sess = tf.Session()
# Create example y_hat.
y_hat = tf.convert_to_tensor(np.array([[0.5, 1.5, 0.1],[2.2, 1.3, 1.7]]))
sess.run(y_hat)
# array([[ 0.5, 1.5, 0.1],
# [ 2.2, 1.3, 1.7]])
Zauważ, że wartości nie są znormalizowane(tzn. wiersze nie sumują się do 1). Aby je znormalizować, możemy zastosować funkcję softmax, która interpretuje dane wejściowe jako nieznormalizowane prawdopodobieństwa logów (aka logits) i wyprowadza znormalizowane prawdopodobieństwa liniowe.
y_hat_softmax = tf.nn.softmax(y_hat)
sess.run(y_hat_softmax)
# array([[ 0.227863 , 0.61939586, 0.15274114],
# [ 0.49674623, 0.20196195, 0.30129182]])
Ważne jest, aby w pełni zrozumieć, co mówi wyjście softmax. Poniżej pokazałem tabelę, która bardziej wyraźnie przedstawia dane wyjściowe powyżej. Widać, że na przykład prawdopodobieństwo wystąpienia szkolenia 1 jako "klasa 2" wynosi 0,619. Prawdopodobieństwo klasowe dla każdej instancji treningowej jest znormalizowane, więc suma każdego wiersza wynosi 1,0.
Pr(Class 1) Pr(Class 2) Pr(Class 3)
,--------------------------------------
Training instance 1 | 0.227863 | 0.61939586 | 0.15274114
Training instance 2 | 0.49674623 | 0.20196195 | 0.30129182
Teraz mamy prawdopodobieństwo klasowe dla każdej instancji treningowej, gdzie możemy użyć argmax () każdego wiersza, aby wygenerować ostateczną klasyfikację. Z góry możemy wygenerować, że instancja szkoleniowa 1 należy do" klasy 2", a instancja szkoleniowa 2 należy do"klasy 1".
Czy te klasyfikacje są poprawne? Potrzebujemy aby zmierzyć się z prawdziwymi etykietami z zestawu treningowego. Będziesz potrzebował jednej gorącej tablicy y_true
, gdzie znowu wiersze są instancjami treningowymi, a kolumny klasami. Poniżej stworzyłem przykład y_true
one-hot array, gdzie prawdziwą etykietą dla instancji treningowej 1 jest "Class 2", a prawdziwą etykietą dla instancji treningowej 2 jest "Class 3".
y_true = tf.convert_to_tensor(np.array([[0.0, 1.0, 0.0],[0.0, 0.0, 1.0]]))
sess.run(y_true)
# array([[ 0., 1., 0.],
# [ 0., 0., 1.]])
Czy rozkład prawdopodobieństwa w y_hat_softmax
jest bliski rozkładowi prawdopodobieństwa w y_true
? Możemy użyć straty entropii krzyżowej do zmierz błąd.
Możemy obliczyć stratę entropii krzyżowej na podstawie rzędu i zobaczyć wyniki. Poniżej widzimy, że instancja treningowa 1 ma stratę 0,479, podczas gdy instancja treningowa 2 ma wyższą stratę 1,200. Wynik ten ma sens, ponieważ w naszym powyższym przykładzie y_hat_softmax
pokazano, że największe prawdopodobieństwo wystąpienia szkolenia 1 było dla "klasy 2", która pasuje do wystąpienia szkolenia 1 w y_true
; jednak przewidywanie wystąpienia szkolenia 2 pokazało najwyższe prawdopodobieństwo dla "klasy 1", która nie odpowiada prawdziwej klasie "klasy 3".
loss_per_instance_1 = -tf.reduce_sum(y_true * tf.log(y_hat_softmax), reduction_indices=[1])
sess.run(loss_per_instance_1)
# array([ 0.4790107 , 1.19967598])
To, czego naprawdę chcemy, to całkowita strata wszystkich instancji treningowych. Możemy więc obliczyć:
total_loss_1 = tf.reduce_mean(-tf.reduce_sum(y_true * tf.log(y_hat_softmax), reduction_indices=[1]))
sess.run(total_loss_1)
# 0.83934333897877944
Korzystanie z softmax_cross_entropy_with_logits()
Możemy zamiast tego obliczyć całkowitą stratę entropii krzyżowej za pomocą funkcji tf.nn.softmax_cross_entropy_with_logits()
, Jak pokazano poniżej.
loss_per_instance_2 = tf.nn.softmax_cross_entropy_with_logits(y_hat, y_true)
sess.run(loss_per_instance_2)
# array([ 0.4790107 , 1.19967598])
total_loss_2 = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(y_hat, y_true))
sess.run(total_loss_2)
# 0.83934333897877922
Zauważ, że total_loss_1
i total_loss_2
dają zasadniczo równoważne wyniki z niewielkimi różnicami w ostatnie cyfry. Jednak równie dobrze możesz użyć drugiego podejścia: zajmuje o jedną linię kodu mniej i gromadzi mniej błędów numerycznych, ponieważ softmax jest wykonywany za ciebie wewnątrz softmax_cross_entropy_with_logits()
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-16 06:19:43
tf.nn.softmax
oblicza propagację do przodu przez warstwę softmax. Używasz go podczas ewaluacji Modelu, kiedy obliczasz prawdopodobieństwo, że model wykaże.
tf.nn.softmax_cross_entropy_with_logits
oblicza koszt warstwy softmax. Jest stosowany tylko podczas treningu .
Logity są nieznormalizowane prawdopodobieństwa logów wyprowadzają model (wartości wyjściowe przed normalizacją softmax są stosowane do nich).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-11 23:06:12
Powyższe odpowiedzi mają wystarczająco dużo opisu dla zadanego pytania.
Dodając do tego, Tensorflow zoptymalizował działanie zastosowania funkcji aktywacji, a następnie obliczenia kosztów za pomocą własnej aktywacji, a następnie funkcji kosztów. Dlatego dobrym rozwiązaniem jest użycie: tf.nn.softmax_cross_entropy()
over tf.nn.softmax(); tf.nn.cross_entropy()
Można znaleźć wyraźną różnicę między nimi w modelu zasobochłonnym.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-19 07:25:41
Logit jest funkcją odwzorowującą prawdopodobieństwa [0, 1] na [-inf, +inf]. Tensorflow "z logitem": oznacza to, że stosujesz funkcję softmax do liczb logitowych w celu jej normalizacji. Input_vector / logit nie jest znormalizowany i może skalować się z [- inf, inf].
Ta normalizacja jest używana do problemów klasyfikacji wieloklasowej. A dla wielowarstwowych problemów klasyfikacyjnych stosuje się normalizację sigmoidalną tj. tf.nn.sigmoid_cross_entropy_with_logits
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-08 06:44:12