Logits, softmax ve softmax_cross_entropy_with_logits nedir?


352

Burada tensorflow API belgelerinden geçiyordum . Tensorflow belgelerinde adlı bir anahtar kelime kullandılar logits. Bu ne? API belgelerindeki birçok yöntemde şöyle yazılır:

tf.nn.softmax(logits, name=None)

Eğer logitsbunlar sadece yazıldıysa Tensors, neden farklı bir isim tutmak logits?

Başka bir şey, ayırt edemediğim iki yöntem olmasıdır. Onlar

tf.nn.softmax(logits, name=None)
tf.nn.softmax_cross_entropy_with_logits(logits, labels, name=None)

Aralarındaki farklar nelerdir? Dokümanlar bana açık değil. Ne yaptığını biliyorum tf.nn.softmax. Ama diğeri değil. Bir örnek gerçekten yardımcı olacaktır.

Yanıtlar:


427

Günlükler, işlevin daha önceki katmanların ölçeklendirilmemiş çıktısında çalıştığı ve birimleri anlamak için göreceli ölçeğin doğrusal olduğu anlamına gelir. Özellikle, girişlerin toplamı 1'e eşit olmayabilir, değerlerin olasılık olmadığı anlamına gelir (5'lik bir girişiniz olabilir).

tf.nn.softmaxsadece giriş tensörüne softmax fonksiyonunun uygulanmasının sonucunu verir . Softmax, girişleri "sıkıştırır", böylece sum(input) = 1: normalleştirmenin bir yolu. Bir softmax'ın çıkış şekli giriş ile aynıdır: sadece değerleri normalleştirir. SoftMax çıkışları olabilir olasılıkları olarak yorumlanabilir.

a = tf.constant(np.array([[.1, .3, .5, .9]]))
print s.run(tf.nn.softmax(a))
[[ 0.16838508  0.205666    0.25120102  0.37474789]]

Buna karşılık, tf.nn.softmax_cross_entropy_with_logitssoftmax fonksiyonunu uyguladıktan sonra sonucun çapraz entropisini hesaplar (ancak hepsini daha matematiksel olarak dikkatli bir şekilde yapar). Şunun sonucuna benzer:

sm = tf.nn.softmax(x)
ce = cross_entropy(sm)

Çapraz entropi özet bir metriktir: öğeler arasında toplanır. tf.nn.softmax_cross_entropy_with_logitsBir şekil [2,5]tensörünün çıktısı şekildedir [2,1](ilk boyut yığın olarak kabul edilir).

Çapraz entropiyi en aza indirmek için optimizasyon yapmak istiyorsanız VE son katınızdan sonra softmaxing tf.nn.softmax_cross_entropy_with_logitsyapıyorsanız, bunu kendiniz yapmak yerine kullanmalısınız , çünkü sayısal olarak kararsız köşe vakalarını matematiksel olarak doğru şekilde kapsar. Aksi takdirde, buraya ve orada küçük epsilons ekleyerek bunu hackleyeceksiniz.

Düzenlendi 2016-02-07: Bir nesnenin yalnızca bir sınıfa ait olabileceği tek sınıf etiketleriniz varsa, şimdi tf.nn.sparse_softmax_cross_entropy_with_logitsetiketlerinizi yoğun bir sıcak etkin diziye dönüştürmek zorunda kalmamanızı isteyebilirsiniz . Bu işlev, 0.6.0 sürümünden sonra eklenmiştir.


1
Softmax_cross_entropy_with_logits hakkında, doğru kullanıp kullanmadığımı bilmiyorum. Sonuç kodumda o kadar kararlı değil. Aynı kod iki kez çalışır, toplam doğruluk 0,6'dan 0,8'e değişir. cross_entropy = tf.nn.softmax_cross_entropy_with_logits(tf.nn.softmax(tf.add(tf.matmul(x,W),b)),y) cost=tf.reduce_mean(cross_entropy). Ama başka bir yol kullandığımda pred=tf.nn.softmax(tf.add(tf.matmul(x,W),b)) cost =tf.reduce_mean(-tf.reduce_sum(y*tf.log(pred),reduction_indices=1)), sonuç istikrarlı ve daha iyi.
Rida

15
İlk çizginizde çift softmaxing var. softmax_cross_entropy_with_logits, tf.nn.softmax çıktısını değil, ölçeklendirilmemiş günlükleri bekler. Sadece davanda istiyorsun tf.nn.softmax_cross_entropy_with_logits(tf.add(tf.matmul(x, W, b)).
dga

7
@ dga Kodunuzda bir yazım hatası olduğunu düşünüyorum b, parantez dışında olması gerekiyor,tf.nn.softmax_cross_entropy_with_logits(tf.add(tf.matmul(x, W), b)
jrieke

1
"birimleri anlamak için göreceli ölçeğin doğrusal olduğunu" ilk cümlenizin bir kısmı ne demek?
Charlie Parker

5
Oy verildi - ama "[t] bir softmax'ın çıktı şeklinin girdi ile aynı olduğunu söylediğinizde cevabınız biraz yanlış - sadece değerleri normalleştirir". Softmax değerleri sadece "ezmek" değildir, böylece toplamları 1'e eşittir. Ayrıca bunları yeniden dağıtır ve muhtemelen kullanılmasının ana nedeni budur. Bkz. Stackoverflow.com/questions/17187507/… , özellikle Piotr Czapla'nın yanıtı.
Paolo Perrotta

282

Kısa versiyon:

y_hatHer sınıf için hesaplanmış puanlar içeren (örneğin, y = G * x + b'den) ve y_truetek etkin kodlanmış gerçek etiketler içeren iki tansörünüz olduğunu varsayalım .

y_hat  = ... # Predicted label, e.g. y = tf.matmul(X, W) + b
y_true = ... # True label, one-hot encoded

Skorları y_hatnormal olmayan günlük olasılıkları olarak yorumlarsanız, bunlar logit olur .

Ek olarak, toplam çapraz entropi kaybı bu şekilde hesaplanır:

y_hat_softmax = tf.nn.softmax(y_hat)
total_loss = tf.reduce_mean(-tf.reduce_sum(y_true * tf.log(y_hat_softmax), [1]))

esasen fonksiyonla hesaplanan toplam çapraz entropi kaybına eşdeğerdir softmax_cross_entropy_with_logits():

total_loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(y_hat, y_true))

Uzun versiyon:

Sinir ağınızın çıkış katmanında, muhtemelen hesaplama gibi her bir eğitim örneğiniz için sınıf puanlarını içeren bir dizi hesaplayacaksınız y_hat = W*x + b. Örnek olarak hizmet etmek için, aşağıda y_hatsatırların eğitim örneklerine ve sütunların sınıflara karşılık geldiği 2 x 3 dizisi olarak oluşturdum . Burada 2 eğitim örneği ve 3 sınıf var.

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

Değerlerin normalleştirilmediğine dikkat edin (yani satırlar 1'e kadar eklemez). Bunları normalleştirmek için, girişi normalleştirilmemiş log olasılıkları (aka logits ) olarak değerlendiren ve normalize lineer olasılıklar çıkaran softmax fonksiyonunu uygulayabiliriz .

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

Softmax çıktısının ne dediğini tam olarak anlamak önemlidir. Aşağıda yukarıdaki çıktıyı daha net bir şekilde temsil eden bir tablo gösterdim. Örneğin, eğitim örneği 1'in "Sınıf 2" olma olasılığının 0.619 olduğu görülebilir. Her eğitim örneği için sınıf olasılıkları normalleştirilmiştir, bu nedenle her satırın toplamı 1,0'dır.

                      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

Şimdi, her bir eğitim örneği için, sınıflandırma yapmak için her bir satırın argmax () yöntemini alabileceğimiz sınıf olasılıklarımız var. Yukarıdan, eğitim örneği 1'in "Sınıf 2" ye ve eğitim örneği 2'nin "Sınıf 1" e ait olduğunu oluşturabiliriz.

Bu sınıflandırmalar doğru mu? Eğitim setindeki gerçek etiketlere karşı ölçüm yapmalıyız. Tek bir sıcak kodlanmış y_truediziye ihtiyacınız olacaktır ; burada tekrar satırlar eğitim örnekleri ve sütunlar sınıflardır. Aşağıda y_true, eğitim örneği 1 için gerçek etiketin "Sınıf 2" ve eğitim örneği 2 için gerçek etiketin "Sınıf 3" olduğu bir örnek bir sıcak dizi oluşturdum.

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

Olasılık dağılımı olasılık dağılımına y_hat_softmaxyakın y_truemı? Biz kullanabilirsiniz çapraz entropi kaybı hatasını ölçmek için.

Çapraz entropi kaybı formülü

Çapraz entropi kaybını satır bazında hesaplayabilir ve sonuçları görebiliriz. Aşağıda, eğitim örneği 1'in 0.479'luk bir kaybı olduğunu, eğitim örneği 2'nin ise 1.200'ün daha yüksek bir kaybının olduğunu görebiliriz. Bu sonuç mantıklıdır, çünkü yukarıdaki örneğimizde, y_hat_softmaxeğitim örneği 1'in en yüksek olasılığının, eğitim örneği 1'de eşleşen "Sınıf 2" için olduğunu gösterdi y_true; ancak, eğitim örneği 2 için tahmin, "Sınıf 1" için gerçek sınıf "Sınıf 3" ile eşleşmeyen en yüksek olasılığı göstermiştir.

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

Gerçekten istediğimiz, tüm eğitim vakalarındaki toplam kayıptır. Böylece hesaplayabiliriz:

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

Softmax_cross_entropy_with_logits () kullanma

Bunun yerine tf.nn.softmax_cross_entropy_with_logits(), aşağıda gösterildiği gibi , fonksiyonu kullanarak toplam çapraz entropi kaybını hesaplayabiliriz .

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

Unutmayın total_loss_1ve total_loss_2son basamaklarda bazı küçük farklılıklar ile temelde eşdeğer sonuçlar üretin. Bununla birlikte, ikinci yaklaşımı da kullanabilirsiniz: daha az bir kod satırı alır ve daha az sayısal hata biriktirir, çünkü softmax sizin için yapılır softmax_cross_entropy_with_logits().


Yukarıdakilerin tümünü onaylıyorum. Basit kod: M = tf.random.uniform([100, 10], minval=-1.0, maxval=1.0); labels = tf.one_hot(tf.random.uniform([100], minval=0, maxval=10 , dtype='int32'), 10); tf.nn.softmax_cross_entropy_with_logits(labels=labels, logits=M) - tf.reduce_sum(-tf.nn.log_softmax(M)*tf.one_hot(labels, 10), -1)her yerde sıfıra yakın döndürür
Sami A. Haija

51

tf.nn.softmaxsoftmax tabakası ile ileriye doğru yayılımı hesaplar. Modelin çıktısını alma olasılığını hesaplarken modeli değerlendirirken kullanırsınız .

tf.nn.softmax_cross_entropy_with_logitssoftmax katmanının maliyetini hesaplar. Sadece eğitim sırasında kullanılır .

Logits olan normalize edilmemiş günlük olasılıkları modeli (SoftMax normalleştirme önce değerleri çıkış uygulanmış olan) çıkış.


2
Anladım. Neden tf.nn.softmax_cross_entropy_sans_normalization fonksiyonunu çağırmıyorsunuz?
auro

8
@auro çünkü çapraz entropi hesaplaması sırasında değerleri (dahili olarak) normalleştirir. Noktası tf.nn.softmax_cross_entropy_with_logitsmodeli normalleştirilmiş bir çıkış sağlamak için değil, altın etiket saptığı ne kadar değerlendirmektir.
erickrf

1
Tf.nn.sparse_softmax_cross_entropy_with_logits () kullanılması durumunda, seyrek bir softmax katmanının maliyetini hesaplar ve bu nedenle sadece yeni veriye karşı modeli çalıştırırken alternatifin ne olacağı eğitim sırasında kullanılmalıdır, bundan olasılıklar elde etmek mümkün mü bir.
SeriDev

2
@SerialDev, olasılıkları almak mümkün değil tf.nn.sparse_softmax_cross_entropy_with_logits. Olasılıkları elde etmek için kullanın tf.nn.softmax.
Nandeesh

4

Yukarıdaki cevaplar, sorulan soru için yeterli açıklamaya sahiptir.

Buna ek olarak, Tensorflow aktivasyon fonksiyonunu uygulama ve ardından kendi aktivasyonunu ve ardından maliyet fonksiyonlarını kullanarak maliyeti hesaplama işlemini optimize etti. Bu nedenle kullanım için iyi bir uygulamadır: tf.nn.softmax_cross_entropy()overtf.nn.softmax(); tf.nn.cross_entropy()

Kaynak yoğun bir modelde aralarındaki belirgin farkı bulabilirsiniz.


1
yukarıdaki cevap açıkça soruyu okumamıştır .. Hepsi aynı şeyleri söyler, ki bunlar bilinen, ama sorunun kendisine cevap vermiyorlar
Euler_Salter

@abhish Eğer kastettiniz tf.nn.softmaxizledi tf.losses.softmax_cross_entropy?
ankurrc

4

Şimdiye kadar softmaxgidilen şey logit, J. Hinton'un ders videolarında her zaman tekrarladığı şey bu.


1

Tensorflow 2.0 Uyumlu Cevap : Logit'ler ve ilgili Fonksiyonlar hakkında açıklamalar dgave stackoverflowuser2010çok detaylı.

Tüm bu işlevler, kullanıldığında Tensorflow 1.xiyi çalışır, ancak kodunuzu 'den' 1.x (1.14, 1.15, etc)e taşırsanız 2.x (2.0, 2.1, etc..), bu işlevleri kullanmak hataya neden olur.

Bu nedenle, tüm işlevler için 2.0 Uyumlu Çağrıları belirterek 1.x to 2.x, topluluğun yararı için göç edersek yukarıda tartıştık .

1.x'deki fonksiyonlar :

  1. tf.nn.softmax
  2. tf.nn.softmax_cross_entropy_with_logits
  3. tf.nn.sparse_softmax_cross_entropy_with_logits

1.x'ten 2.x'e Geçtiğinde Saygı Fonksiyonları :

  1. tf.compat.v2.nn.softmax
  2. tf.compat.v2.nn.softmax_cross_entropy_with_logits
  3. tf.compat.v2.nn.sparse_softmax_cross_entropy_with_logits

1.x'den 2.x'e geçiş hakkında daha fazla bilgi için lütfen bu Taşıma Kılavuzuna bakın .


0

Logit olarak kesinlikle vurgulamak istediğim bir şey daha sadece ham bir çıktı, genellikle son katmanın çıktısı. Bu da negatif bir değer olabilir. Eğer aşağıda belirtildiği gibi "çapraz entropi" değerlendirmesi için kullanırsak:

-tf.reduce_sum(y_true * tf.log(logits))

o zaman işe yaramaz. -Ve günlüğü tanımlanmadığı için. Yani o softmax aktivasyonunu kullanmak, bu sorunun üstesinden gelecektir.

Bu benim anlayışım, lütfen yanılıyorsam beni düzeltin.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.