TensorFlow損失函數(shù)專題詳解
一、分類問(wèn)題損失函數(shù)——交叉熵(crossentropy)
交叉熵刻畫了兩個(gè)概率分布之間的距離,是分類問(wèn)題中使用廣泛的損失函數(shù)。給定兩個(gè)概率分布p和q,交叉熵刻畫的是兩個(gè)概率分布之間的距離:
我們可以通過(guò)Softmax回歸將神經(jīng)網(wǎng)絡(luò)前向傳播得到的結(jié)果變成交叉熵要求的概率分布得分。在TensorFlow中,Softmax回歸的參數(shù)被去掉了,只是一個(gè)額外的處理層,將神經(jīng)網(wǎng)絡(luò)的輸出變成一個(gè)概率分布。
代碼實(shí)現(xiàn):
import tensorflow as tf y_ = tf.constant([[1.0, 0, 0]]) # 正確標(biāo)簽 y1 = tf.constant([[0.9, 0.06, 0.04]]) # 預(yù)測(cè)結(jié)果1 y2 = tf.constant([[0.5, 0.3, 0.2]]) # 預(yù)測(cè)結(jié)果2 # 以下為未經(jīng)過(guò)Softmax處理的類別得分 y3 = tf.constant([[10.0, 3.0, 2.0]]) y4 = tf.constant([[5.0, 3.0, 1.0]]) # 自定義交叉熵 cross_entropy1 = -tf.reduce_mean(y_ * tf.log(tf.clip_by_value(y1, 1e-10, 1.0))) cross_entropy2 = -tf.reduce_mean(y_ * tf.log(tf.clip_by_value(y2, 1e-10, 1.0))) # TensorFlow提供的集成交叉熵 # 注:該操作應(yīng)該施加在未經(jīng)過(guò)Softmax處理的logits上,否則會(huì)產(chǎn)生錯(cuò)誤結(jié)果 # labels為期望輸出,且必須采用labels=y_, logits=y的形式將參數(shù)傳入 cross_entropy_v2_1 = tf.nn.softmax_cross_entropy_with_logits(labels=y_, logits=y3) cross_entropy_v2_2 = tf.nn.softmax_cross_entropy_with_logits(labels=y_, logits=y4) sess = tf.InteractiveSession() print('[[0.9, 0.06, 0.04]]:', cross_entropy1.eval()) print('[[0.5, 0.3, 0.2]]:', cross_entropy2.eval()) print('v2_1', cross_entropy_v2_1.eval()) print('v2_2',cross_entropy_v2_2.eval()) sess.close() ''''' [[0.9, 0.06, 0.04]]: 0.0351202 [[0.5, 0.3, 0.2]]: 0.231049 v2_1 [ 0.00124651] v2_2 [ 0.1429317] '''
tf.clip_by_value()函數(shù)可將一個(gè)tensor的元素?cái)?shù)值限制在指定范圍內(nèi),這樣可防止一些錯(cuò)誤運(yùn)算,起到數(shù)值檢查作用。
* 乘法操作符是元素之間直接相乘,tensor中是每個(gè)元素對(duì)應(yīng)相乘,要去別去tf.matmul()函數(shù)的矩陣相乘。
tf.nn.softmax_cross_entropy_with_logits(labels=y_,logits=y)是TensorFlow提供的集成交叉熵函數(shù)。該操作應(yīng)該施加在未經(jīng)過(guò)Softmax處理的logits上,否則會(huì)產(chǎn)生錯(cuò)誤結(jié)果;labels為期望輸出,且必須采用labels=y_, logits=y3的形式將參數(shù)傳入。
二、回歸問(wèn)題損失函數(shù)——均方誤差(MSE,mean squared error)
均方誤差亦可用于分類問(wèn)題的損失函數(shù),其定義為:
三、自定義損失函數(shù)
對(duì)于理想的分類問(wèn)題和回歸問(wèn)題,可采用交叉熵或者M(jìn)SE損失函數(shù),但是對(duì)于一些實(shí)際的問(wèn)題,理想的損失函數(shù)可能在表達(dá)上不能完全表達(dá)損失情況,以至于影響對(duì)結(jié)果的優(yōu)化。例如:對(duì)于產(chǎn)品銷量預(yù)測(cè)問(wèn)題,表面上是一個(gè)回歸問(wèn)題,可使用MSE損失函數(shù)。可實(shí)際情況下,當(dāng)預(yù)測(cè)值大于實(shí)際值時(shí),損失值應(yīng)是正比于商品成本的函數(shù);當(dāng)預(yù)測(cè)值小于實(shí)際值,損失值是正比于商品利潤(rùn)的函數(shù),多數(shù)情況下商品成本和利潤(rùn)是不對(duì)等的。自定義損失函數(shù)如下:
TensorFlow中,通過(guò)以下代碼實(shí)現(xiàn)loss= tf.reduce_sum(tf.where(tf.greater(y, y_), (y-y_)*loss_more,(y_-y)*loss_less))。
tf.greater(x,y),返回x>y的判斷結(jié)果的bool型tensor,當(dāng)tensor x, y的維度不一致時(shí),采取廣播(broadcasting)機(jī)制。
tf.where(condition,x=None, y=None, name=None),根據(jù)condition選擇x (if true) or y (if false)。
代碼實(shí)現(xiàn):
import tensorflow as tf from numpy.random import RandomState batch_size = 8 x = tf.placeholder(tf.float32, shape=(None, 2), name='x-input') y_ = tf.placeholder(tf.float32, shape=(None, 1), name='y-input') w1 = tf.Variable(tf.random_normal([2,1], stddev=1, seed=1)) y = tf.matmul(x, w1) # 根據(jù)實(shí)際情況自定義損失函數(shù) loss_less = 10 loss_more = 1 # tf.select()在1.0以后版本中已刪除,tf.where()替代 loss = tf.reduce_sum(tf.where(tf.greater(y, y_), (y-y_)*loss_more, (y_-y)*loss_less)) train_step = tf.train.AdamOptimizer(learning_rate=0.001).minimize(loss) rdm = RandomState(seed=1) # 定義一個(gè)隨機(jī)數(shù)生成器并設(shè)定隨機(jī)種子 dataset_size = 128 X = rdm.rand(dataset_size, 2) Y = [[x1 + x2 +rdm.rand()/10.0 - 0.05] for (x1, x2) in X] # 增加一個(gè)-0.05~0.05的噪聲 sess = tf.InteractiveSession() tf.global_variables_initializer().run() for i in range(5000): start = (i * batch_size) % dataset_size end = min(start+batch_size, dataset_size) train_step.run({x: X[start: end], y_: Y[start: end]}) if i % 500 == 0: print('step%d:\n' % i, w1.eval()) print('final w1:\n', w1.eval()) sess.close() ''''' loss_less = 10 loss_more = 1 final w1: [[ 1.01934695] [ 1.04280889]] loss_less = 1 loss_more = 10 final w1: [[ 0.95525807] [ 0.9813394 ]] loss_less = 1 loss_more = 1 final w1: [[ 0.9846065 ] [ 1.01486754]] '''
根據(jù)程序輸出可見(jiàn),當(dāng)我們將loss_less=10時(shí),表明我們對(duì)預(yù)測(cè)值過(guò)小表征的損失值更大,優(yōu)化得到的參數(shù)均略大于1;當(dāng)loss_more=10時(shí),表明我們對(duì)預(yù)測(cè)值過(guò)大表征的損失值更大,優(yōu)化得到的參數(shù)均略小于1;當(dāng)兩者均設(shè)為1時(shí),得到的參數(shù)約等于1。
四、TensorFlow的Cross_Entropy實(shí)現(xiàn)
1. tf.nn.softmax_cross_entropy_with_logits(_sentinel=None,labels=None, logits=None, dim=-1, name=None)
該函數(shù)的功能是自動(dòng)計(jì)算logits(未經(jīng)過(guò)Softmax)與labels之間的cross_entropy交叉熵。
該操作應(yīng)該施加在未經(jīng)過(guò)Softmax處理的logits上,否則會(huì)產(chǎn)生錯(cuò)誤結(jié)果;labels為期望輸出,且必須采用labels=y_,logits=y3的形式將參數(shù)傳入。
第一個(gè)參數(shù)logits:就是神經(jīng)網(wǎng)絡(luò)最后一層的輸出,如果有batch的話,它的大小就是[batchsize,num_classes],單樣本的話,大小就是num_classes
第二個(gè)參數(shù)labels:實(shí)際的標(biāo)簽,大小同上。
注意:如果labels的每一行是one-hot表示,也就是只有一個(gè)地方為1,其他地方為0,可以使用tf.sparse_softmax_cross_entropy_with_logits()
警告: (1)這個(gè)操作的輸入logits是未經(jīng)縮放的,該操作內(nèi)部會(huì)對(duì)logits使用softmax操作;(2)參數(shù)labels,logits必須有相同的形狀 [batch_size, num_classes] 和相同的類型(float16, float32,float64)中的一種。
該函數(shù)具體的執(zhí)行過(guò)程分兩步:首先對(duì)logits做一個(gè)Softmax,
第二步就是將第一步的輸出與樣本的實(shí)際標(biāo)簽labels做一個(gè)交叉熵。
注意?。?!這個(gè)函數(shù)的返回值并不是一個(gè)數(shù),而是一個(gè)向量,如果要求交叉熵,我們要再做一步tf.reduce_sum操作,就是對(duì)向量里面所有元素求和,最后才得到交叉熵,如果求loss,則要做一步tf.reduce_mean操作,對(duì)向量求均值!
2. tf.nn.sparse_softmax_cross_entropy_with_logits(_sentinel=None,labels=None, logits=None, name=None)
該函數(shù)與tf.nn.softmax_cross_entropy_with_logits(_sentinel=None,labels=None, logits=None, dim=-1, name=None)十分相似,唯一的區(qū)別在于labels,該函數(shù)的標(biāo)簽labels要求是排他性的即只有一個(gè)正確類別,labels的形狀要求是[batch_size] 而值必須是從0開(kāi)始編碼的int32或int64,而且值范圍是[0, num_class),對(duì)比于tf.nn.softmax_cross_entropy_with_logits的[batchsize,num_classes]格式的得分編碼。
其他使用注意事項(xiàng)參見(jiàn)tf.nn.softmax_cross_entropy_with_logits的說(shuō)明。
3. tf.nn.sigmoid_cross_entropy_with_logits(_sentinel=None,labels=None, logits=None, name=None)
sigmoid_cross_entropy_with_logits是TensorFlow最早實(shí)現(xiàn)的交叉熵算法。這個(gè)函數(shù)的輸入是logits和labels,logits就是神經(jīng)網(wǎng)絡(luò)模型中的 W * X矩陣,注意不需要經(jīng)過(guò)sigmoid,而labels的shape和logits相同,就是正確的標(biāo)簽值,例如這個(gè)模型一次要判斷100張圖是否包含10種動(dòng)物,這兩個(gè)輸入的shape都是[100, 10]。注釋中還提到這10個(gè)分類之間是獨(dú)立的、不要求是互斥,這種問(wèn)題我們稱為多目標(biāo)(多標(biāo)簽)分類,例如判斷圖片中是否包含10種動(dòng)物中的一種或幾種,標(biāo)簽值可以包含多個(gè)1或0個(gè)1。
4. tf.nn.weighted_cross_entropy_with_logits(targets, logits, pos_weight, name=None)
weighted_sigmoid_cross_entropy_with_logits是sigmoid_cross_entropy_with_logits的拓展版,多支持一個(gè)pos_weight參數(shù),在傳統(tǒng)基于sigmoid的交叉熵算法上,正樣本算出的值乘以某個(gè)系數(shù)。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Python中if __name__ == ''__main__''作用解析
這篇文章主要介紹了Python中if __name__ == '__main__'作用解析,這斷代碼在Python中非常常見(jiàn),它有作用?本文就解析了它的作用,需要的朋友可以參考下2015-06-06python 用opencv調(diào)用訓(xùn)練好的模型進(jìn)行識(shí)別的方法
今天小編就為大家分享一篇python 用opencv調(diào)用訓(xùn)練好的模型進(jìn)行識(shí)別的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-12-12Pytorch之8層神經(jīng)網(wǎng)絡(luò)實(shí)現(xiàn)Cifar-10圖像分類驗(yàn)證集準(zhǔn)確率94.71%
這篇文章主要介紹了Pytorch之8層神經(jīng)網(wǎng)絡(luò)實(shí)現(xiàn)Cifar-10圖像分類驗(yàn)證集準(zhǔn)確率94.71%問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-03-03python 殺死自身進(jìn)程的實(shí)現(xiàn)方法
今天小編就為大家分享一篇python 殺死自身進(jìn)程的實(shí)現(xiàn)方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-07-07淺談python中的getattr函數(shù) hasattr函數(shù)
下面小編就為大家?guī)?lái)一篇淺談python中的getattr函數(shù) hasattr函數(shù)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-06-06python獲取當(dāng)前文件所在目錄、獲取上級(jí)目錄的坑及解決
這篇文章主要介紹了python獲取當(dāng)前文件所在目錄、獲取上級(jí)目錄的坑及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-08-08使用Python抓取豆瓣影評(píng)數(shù)據(jù)的方法
今天小編就為大家分享一篇關(guān)于使用Python抓取豆瓣影評(píng)數(shù)據(jù)的方法,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2018-10-10