tensorflow中的幾種交叉熵

2022-09-03 04:15:10 字數 2894 閱讀 8094

準備1、先說一下什麼是logit,logit函式定義為:

是一種將取值範圍在[0,1]內的概率對映到實數域[-inf,inf]的函式,如果p=0.5,函式值為0;p<0.5,函式值為負;p>0.5,函式值為正。

相對地,softmax和sigmoid則都是將[-inf,inf]對映到[0,1]的函式。

在tensorflow裡的"logits"指的其實是,該方法是在logit數值上使用softmax或者sigmoid來進行normalization的,也暗示使用者不要將網路輸出進行sigmoid或者softmax,這些過程可以在函式內部更高效地計算。

準備2、獨立和互斥

有事件a和b

獨立:p(anb) = p(a) * p(b)

互斥:p(aub) = p(a) + p(b), p(anb) = 0

準備3、cross entropy loss + softmax + sigmoid

請看之前的文章,複習:常見的損失函式

sigmoid_cross_entropy_with_logits(

_sentinel=none,

labels=none,

logits=none,

name=none

)

計算網路輸出logits和標籤labels的sigmoid cross entropy loss,衡量獨立不互斥離散分類任務的誤差,說獨立不互斥離散分類任務是因為,在這些任務中類與類之間是獨立但是不互斥的,拿多分類任務中的多目標檢測來舉例子,一張圖中可以有各種instance,比如有乙隻狗和乙隻貓。對於乙個總共有五類的多目標檢測任務,假如網路的輸出層有5個節點,label的形式是[1,1,0,0,1]這種,1表示該有某種instance,0表示沒有。那麼,每個instance在這張圖中有沒有這顯然是獨立事件,但是多個instance可以存在一張圖中,這就說明事件們並不是互斥的。所以我們可以直接將網路的輸出用作該方法的logits輸入,從而進行輸出與label的cross entropy loss。

更加直白的來說,這種網路的輸入不需要進行one hot處理,網路輸出即是函式logits引數的輸入。

剖開函式內部,因為labels和logits的形狀都是[batch_size, num_classes],那麼如何計算他們的交叉熵呢,畢竟它們都不是有效的概率分布(乙個batch內輸出結果經過sigmoid後和不為1)。其實loss的計算是element-wise的,方法返回的loss的形狀和labels是相同的,也是[batch_size, num_classes],再呼叫reduce_mean方法計算batch內的平均loss。所以這裡的cross entropy其實是一種class-wise的cross entropy,每乙個class是否存在都是乙個事件,對每乙個事件都求cross entropy loss,再對所有的求平均,作為最終的loss。

softmax_cross_entropy_with_logits(

_sentinel=none,

labels=none,

logits=none,

dim=-1,

name=none

)

計算網路輸出logits和標籤labels的softmax cross entropy loss,衡量獨立互斥離散分類任務的誤差,說獨立互斥離散分類任務是因為,在這些任務中類與類之間是獨立而且互斥的,比如voc classification、imagenet、cifar-10甚至mnist,這些都是多分類任務,但是一張圖就對應著乙個類,class在中是否存在是獨立的,並且一張圖中只能有乙個class,所以是獨立且互斥事件。

該函式要求每乙個label都是乙個有效的概率分布,對於imagenet中的ilsvrc2012這種任務,那麼label應該就對應乙個one hot編碼,ilsvrc2012提供的資料集中一共有1000個類,那麼label就應該是乙個1x1000的vector,形式為[0,0,...,1,0,....0],1000個元素中有且只有乙個元素是1,其餘都是0。

這樣要求的原因很簡單,因為網路的輸出要進行softmax,得到的就是乙個有效的概率分布,這裡不同與sigmoid,因為sigmoid並沒***網路所有的輸出經過sigmoid後和為1,不是乙個有效的概率分布。

有了labels和softmax後的logits,就可以計算交叉熵損失了,最後得到的是形狀為[batch_size, 1]的loss。

sparse_softmax_cross_entropy_with_logits(

_sentinel=none,

labels=none,

logits=none,

name=none

)

這個版本是tf.nn.softmax_cross_entropy_with_logits的易用版本,這個版本的logits的形狀依然是[batch_size, num_classes],但是labels的形狀是[batch_size, 1],每個label的取值是從[0, num_classes)的離散值,這也更加符合我們的使用習慣,是哪一類就標哪個類對應的label。

如果已經對label進行了one hot編碼,則可以直接使用tf.nn.softmax_cross_entropy_with_logits。

到底是用sigmoid版本的cross entropy還是softmax版本的cross entropy主要取決於我們模型的目的,以及label的組織方式,這個需要大家在使用的時候去揣摩,到底使用哪一種loss比較合理。

在我最近訓練的segmentation模型中,使用的就是sparse softmax cross entropy,使用的思路就是將輸出的結果從nhwc(這裡c=1,表示該pixel所屬的class),進行一次reshape,形狀變為[n*h*w, 1],label也是如此,傳入函式中進行計算,從而產生loss。從模型訓練的結果來看,這種使用方法沒有錯誤。

如有錯誤還望指正。

tensorflow框架中幾種計算梯度的方式

tf.gradients ys,xs,grad ys none,name gradients colocate gradients with ops false,gate gradients false,aggregation method none,stop gradients none,unco...

tensorflow的幾種優化器

最近自己用cnn跑了下minist,準確率很低 迭代過程中 跑了幾個epoch,我就直接stop了,感覺哪有問題,隨即排查了下,同時查閱了網上其他人的blog,並沒有發現什麼問題 之後copy了一篇別人的 發現在第二個epoch的時候,準確率已經在80左右了,當時對比了下 自己的 是沒有問題的,問題...

Tensorflow中的Lazy load問題

用tensorflow訓練或者inference模型的時候,有時候會遇到執行越來越慢,最終記憶體被佔滿,導致電腦宕機的問題,我們稱之為記憶體溢位。出現這種問題很可能是因為在乙個session中,graph迴圈建立重複的節點所導致的lazy load問題。舉個例子,用tensorflow迴圈做多次加法...