เวอร์ชั่นสั้น:
สมมติว่าคุณมีเทนเซอร์สองตัวโดยที่y_hat
มีคะแนนที่คำนวณได้สำหรับแต่ละคลาส (เช่นจาก y = W * x + b) และy_true
มีป้ายกำกับจริงที่เข้ารหัสร้อนแรงหนึ่งรายการ
y_hat = ... # Predicted label, e.g. y = tf.matmul(X, W) + b
y_true = ... # True label, one-hot encoded
หากคุณตีความคะแนนในy_hat
ขณะที่ความน่าจะเป็นบันทึก unnormalized แล้วพวกเขาจะlogits
นอกจากนี้การสูญเสียข้ามเอนโทรปีทั้งหมดที่คำนวณในลักษณะนี้:
y_hat_softmax = tf.nn.softmax(y_hat)
total_loss = tf.reduce_mean(-tf.reduce_sum(y_true * tf.log(y_hat_softmax), [1]))
เป็นหลักเทียบเท่ากับการสูญเสียข้ามเอนโทรปีทั้งหมดที่คำนวณด้วยฟังก์ชันsoftmax_cross_entropy_with_logits()
:
total_loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(y_hat, y_true))
รุ่นยาว:
y_hat = W*x + b
ในชั้นการส่งออกของเครือข่ายประสาทของคุณคุณอาจจะคำนวณอาร์เรย์ที่มีคะแนนระดับสำหรับแต่ละกรณีการฝึกอบรมของคุณเช่นจากการคำนวณหนึ่ง เพื่อเป็นตัวอย่างด้านล่างฉันได้สร้างy_hat
อาร์เรย์แบบ 2 x 3 ที่แถวตรงกับอินสแตนซ์การฝึกอบรมและคอลัมน์สอดคล้องกับคลาส ดังนั้นที่นี่มี 2 กรณีการฝึกอบรมและ 3 ชั้นเรียน
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]])
โปรดทราบว่าค่าจะไม่ได้รับการทำให้เป็นมาตรฐาน (เช่นแถวไม่รวมกันไม่เกิน 1) เพื่อทำให้เป็นมาตรฐานพวกเราสามารถใช้ฟังก์ชั่น softmax ซึ่งตีความอินพุตเป็นความน่าจะเป็นบันทึกไม่ปกติ (aka บันทึก ) และเอาท์พุทความน่าจะเป็นเชิงเส้นปกติ
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 กำลังพูดอย่างเต็มที่ ด้านล่างฉันได้แสดงตารางที่แสดงผลลัพธ์ที่ด้านบนอย่างชัดเจนยิ่งขึ้น จะเห็นได้ว่าตัวอย่างเช่นความน่าจะเป็นของการฝึกอบรมอินสแตนซ์ 1 คือ "Class 2" คือ 0.619 ความน่าจะเป็นของคลาสสำหรับแต่ละอินสแตนซ์การฝึกอบรมถูกทำให้เป็นมาตรฐานดังนั้นผลรวมของแต่ละแถวคือ 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
ดังนั้นตอนนี้เรามีคลาสน่าจะเป็นสำหรับแต่ละตัวอย่างการฝึกอบรมโดยเราสามารถใช้ argmax () ของแต่ละแถวเพื่อสร้างการจำแนกขั้นสุดท้าย จากด้านบนเราอาจสร้างอินสแตนซ์การฝึกอบรมที่ 1 เป็นของ "คลาส 2" และอินสแตนซ์การฝึกอบรม 2 เป็นของ "คลาส 1"
การจำแนกประเภทเหล่านี้ถูกต้องหรือไม่ เราต้องวัดกับฉลากจริงจากชุดฝึกอบรม คุณจะต้องใช้y_true
อาเรย์แบบเข้ารหัสหนึ่งครั้งที่แถวนั้นเป็นอินสแตนซ์การฝึกอบรมและคอลัมน์เป็นคลาสอีกครั้ง ด้านล่างฉันได้สร้างตัวอย่างy_true
หนึ่งแถวร้อนที่ป้ายกำกับที่แท้จริงสำหรับการฝึกอบรมอินสแตนซ์ 1 คือ "Class 2" และป้ายกำกับที่แท้จริงสำหรับอินสแตนซ์การฝึกอบรม 2 คือ "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.]])
การกระจายความน่าจะเป็นy_hat_softmax
ใกล้กับการกระจายความน่าจะเป็นy_true
หรือไม่ เราสามารถใช้การสูญเสียข้ามเอนโทรปีในการวัดข้อผิดพลาด
เราสามารถคำนวณการสูญเสียข้ามเอนโทรปีบนพื้นฐานของแถวและดูผลลัพธ์ ด้านล่างเราจะเห็นได้ว่าอินสแตนซ์การฝึกอบรม 1 มีการสูญเสีย 0.479 ในขณะที่อินสแตนซ์การฝึกอบรม 2 มีการสูญเสียที่สูงกว่า 1.200 ผลลัพธ์นี้สมเหตุสมผลเนื่องจากในตัวอย่างของเราด้านบนy_hat_softmax
แสดงให้เห็นว่าความน่าจะเป็นที่สูงที่สุดของการฝึกอบรม 1 สำหรับ "คลาส 2" ซึ่งตรงกับอินสแตนซ์การฝึกอบรม 1 ในy_true
; อย่างไรก็ตามการคาดการณ์สำหรับอินสแตนซ์การฝึกอบรม 2 แสดงความน่าจะเป็นสูงสุดสำหรับ "คลาส 1" ซึ่งไม่ตรงกับคลาส "คลาส 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])
สิ่งที่เราต้องการคือการสูญเสียทั้งหมดในทุกกรณีการฝึกอบรม ดังนั้นเราสามารถคำนวณ:
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 ()
เราสามารถคำนวณการสูญเสียเอนโทรปีโดยรวมได้โดยใช้tf.nn.softmax_cross_entropy_with_logits()
ฟังก์ชั่นดังที่แสดงด้านล่าง
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
โปรดทราบว่าtotal_loss_1
และtotal_loss_2
ให้ผลลัพธ์ที่เทียบเท่าเป็นหลักโดยมีความแตกต่างเล็กน้อยในหลักสุดท้าย แต่คุณอาจรวมทั้งใช้วิธีการที่สองจะใช้เวลาหนึ่งบรรทัดน้อยของรหัสและสะสมข้อผิดพลาดน้อยลงเพราะตัวเลข softmax 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)
. แต่เมื่อฉันใช้วิธีอื่น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))
ผลที่ได้คือมั่นคงและดีกว่า