लघु संस्करण:
मान लीजिए कि आपके पास दो टेनर्स हैं, 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
को अस्वाभाविक लॉग संभावनाओं के रूप में व्याख्या करते हैं , तो वे लॉगिट हैं ।
इसके अतिरिक्त, कुल क्रॉस-एन्ट्रापी नुकसान की गणना इस तरीके से की गई है:
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 तक नहीं जुड़ती हैं)। उन्हें सामान्य करने के लिए, हम सॉफ्टमैक्स फ़ंक्शन को लागू कर सकते हैं, जो इनपुट को अस्वाभाविक रूप से लॉग प्रायिकताओं (उर्फ लॉगिट्स ) के रूप में व्याख्या करता है और सामान्यीकृत रैखिक संभावनाओं को आउटपुट करता है।
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]])
यह समझना महत्वपूर्ण है कि सॉफ्टमैक्स आउटपुट क्या कह रहा है। नीचे मैंने एक तालिका दिखाई है जो अधिक स्पष्ट रूप से उपरोक्त आउटपुट का प्रतिनिधित्व करती है। यह देखा जा सकता है कि, उदाहरण के लिए, प्रशिक्षण उदाहरण 1 "कक्षा 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 के लिए सही लेबल "क्लास 2" है और प्रशिक्षण उदाहरण 2 के लिए सही लेबल "क्लास 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_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))
तो परिणाम स्थिर और बेहतर होता है।