Kısa versiyon:
y_hat
Her sınıf için hesaplanmış puanlar içeren (örneğin, y = G * x + b'den) ve y_true
tek 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_hat
normal 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_hat
satı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_true
diziye 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_softmax
yakın y_true
mı? Biz kullanabilirsiniz çapraz entropi kaybı hatasını ölçmek için.
Ç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_softmax
eğ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_1
ve total_loss_2
son 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()
.
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ığımdapred=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.