版權聲明:本文為博主原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。
本文鏈接:https://blog.csdn.net/limiyudianzi/article/details/80697711
我主要分三篇文章給大家介紹tensorflow的損失函數,本篇為tensorflow自定義損失函數。
(一)tensorflow內置的四個損失函數
(二)其他損失函數
(三)自定義損失函數
自定義損失函數是損失函數章節的結尾,學習自定義損失函數,對於提高分類分割等問題的准確率很有幫助,同時探索新型的損失函數也可以讓你文章多多。這里我們介紹構建自定義損失函數的方法,並且介紹可以均衡正負例的loss,以及在多分類中可以解決樣本數量不均衡的loss的方法。
首先為了有足夠的知識學會自定義損失函數,我們需要知道tensorflow都能實現什么樣的操作。其實答案是你常見的數學運算都可以,所以說只要你能把心中的損失函數表達為數學式的形式,那么你就能夠將其轉變為損失函數的形式。下面介紹一些常見的函數:
四則運算:tf.add(Tensor1,Tensor2),tf.sub(Tensor1,Tensor2), tf.mul(Tensor1,Tensor2),tf.div(Tensor1,Tensor2)這里的操作也可以被正常的加減乘除的負號所取代。這里想要指出的是乘法和除法的規則和numpy庫是一樣的,是matlab中的點乘而不是矩陣的乘法,矩陣的乘法是tf.matmul(Tensor1, Tensor2)
基礎運算: 取模運算(tf.mod()),絕對值(tf.abs()),平方(tf.square()),四舍五入取整(tf.round()),取平方根(tf.sqrt()) ,自然對數的冪(tf.exp()) ,取對數(tf.log()) ,冪(tf.pow()) ,正弦運算(tf.sin())。以上的這些數學運算以及很多沒有被提及的運算在tensorflow中都可以自己被求導,所以大家不用擔心還需要自己寫反向傳播的問題,只要你的操作是由tensorflow封裝的基礎操作實現的,那么反向傳播就可以自動的實現。
條件判斷,通過條件判斷語句我們就可以實現分段的損失函數,利用tf.where(condition, tensor_x, tensor_y) 如果說條件condition是True那么就會返回tensor_x,如果是False則返回tensor_y。注:舊版本的tensorflow可以用tf.select實現這個操作。
比較操作,為了獲得condition這個參數,我們可以用tf.greater( tensor_x, tensor_y)如果說tensor_x大於tensor_y則返回True。
tf.reduce_sum(),tf.reduce_mean()這兩個操作是重要的loss操作,因為loss是一個數字,而通常計算得到的是一個高維的矩陣,因此用降維加法和降維取平均,可以將一個高維的矩陣變為一個數字。
有了上面的這些操作,我們就可以實現基本的損失函數的構建了,比如我們構建交叉熵損失函數:
cross_entropy = tf.reduce_mean(-tf.reduce_sum(y_ * tf.log(y)+(y_-1)* tf.log(1-y)))
再介紹一個均衡正負樣本數量的loss,首先在訓練數據中,通常來講正例比較少,負例比較多,如疾病篩查中,有病的占少數而絕大部分人是健康的,這種數量不均衡的數據可能會讓分類器傾向於將所有的示例都分為健康人,因為這樣整體的准確率可能就能達到90%以上,為此,可以用調整loss權重的方式來緩解樣本數量不均衡的問題,如:
pos_ratio=num_of_positive/num_all # 病人占總體的比例,較小如0.1
neg_ratio=num_of_negative/num_all # 正常人占總體的比例,較大如0.9
cross_entropy = tf.reduce_mean(-neg_ratio*tf.reduce_sum(y_ * tf.log(y)+pos_ratio*(y_-1)* tf.log(1-y)))
在這里我們給病人的損失項乘了一個較大的系數,使得一旦占少數的病人被錯分為健康人的時候,代價就非常的大。同樣的給正常人的損失項乘了一個較小的系數,使其診斷錯誤時對網絡的影像較小。
這也符合實際情況,即使健康人在篩查時被通知可能患病,只要再進一步檢查就可以。但是如果在篩查的時候將病人誤分為健康人,那么付出的就可能是生命的代價了。
以上是二分類的例子,那么在多分類的時候應該如何做呢?我們也可以通過乘系數這樣的方式解決問題,這里我們認為標簽是one_hot形式的如:
class1_weight=0.2 # 第一類的權重系數
class2_weight=0.5 # 第二類的權重系數
class3_weight=0.3 # 第三類的權重系數
cross_entropy = tf.reduce_mean(-class1_weight*tf.reduce
_sum(y_[:,0] * tf.log(y[:,0])-class2_weight*tf.reduce
_sum(y_[:,1] * tf.log(y[:,1])-class3_weight*tf.reduce
_sum(y_[:,2] * tf.log(y[:,2]))
因為標簽和預測的結果都是one_hot的形式,因此在這里y[:,0]就是第一類的概率值,其中第一個維度的長度是minibatch的大小。同理y[:,0]就是第二類的概率值,我們在不同的項上乘上不同類別的權重系數,就可以一定程度上解決樣本數量不均衡所帶來的困擾。
————————————————
版權聲明:本文為CSDN博主「Liu-Kevin」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/limiyudianzi/article/details/80697711