版權聲明:本文爲博主原創文章,遵循 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