1、分類損失python
一、交叉熵損失函數git
公式:數組
交叉熵的原理網絡
交叉熵刻畫的是實際輸出(機率)與指望輸出(機率)的距離,也就是交叉熵的值越小,兩個機率分佈就越接近。假設機率分佈p爲指望輸出,機率分佈q爲實際輸出,H(p,q)爲交叉熵,則:函數
有這樣一個定理:當p=q時,交叉熵去的最小值.所以能夠利用交叉熵比較一個分佈與另外一個分佈的吻合狀況.交叉熵越接近與熵,q即是針對p更好的逼近,實際上,模型的輸出與指望輸出越接近,交叉熵也會越小,這正是損失函數所須要的.
在對熵進行最小化時,將log2替換爲log徹底沒有任何問題,由於二者只相差一個常係數.atom
在TensorFlow中實現交叉熵spa
cross_entropy = -tf.reduce_mean(y_ * tf.log(tf.clip_by_value(y, 1e-10, 1.0)))
其中y_表示指望的輸出,y表示實際的輸出(機率值),*爲矩陣元素間相乘,而不是矩陣乘。
上述代碼實現了第一種形式的交叉熵計算,須要說明的是,計算的過程其實和上面提到的公式有些區別,按照上面的步驟,平均交叉熵應該是先計算batch中每個樣本的交叉熵後取平均計算獲得的,而利用tf.reduce_mean函數其實計算的是整個矩陣的平均值,這樣作的結果會有差別,可是並不改變實際意義。
除了tf.reduce_mean函數,tf.clip_by_value函數是爲了限制輸出的大小,爲了不log0爲負無窮的狀況,將輸出的值限定在(1e-10, 1.0)之間,其實1.0的限制是沒有意義的,由於機率怎麼會超過1呢。orm
因爲在神經網絡中,交叉熵經常與Sorfmax函數組合使用,因此TensorFlow對其進行了封裝,即:xml
cross_entropy = tf.nn.sorfmax_cross_entropy_with_logits(y_ ,y)
二、sigmoid_cross_entropy_with_logits對象
函數定義
def sigmoid_cross_entropy_with_logits(_sentinel=None, labels=None, logits=None, name=None):
函數意義
這個函數的做用是計算經sigmoid 函數激活以後的交叉熵。
爲了描述簡潔,咱們規定 x = logits,z = targets,那麼 Logistic 損失值爲:
x−x∗z+log(1+exp(−x))
對於x<0的狀況,爲了執行的穩定,使用計算式:
−x∗z+log(1+exp(x))−x∗z+log(1+exp(x))
爲了確保計算穩定,避免溢出,真實的計算實現以下:
max(x,0)−x∗z+log(1+exp(−abs(x)))max(x,0)−x∗z+log(1+exp(−abs(x)))
logits 和 targets 必須有相同的數據類型和數據維度。
它適用於每一個類別相互獨立但互不排斥的狀況,在一張圖片中,同時包含多個分類目標(大象和狗),那麼就可使用這個函數。
輸入
_sentinel: 通常狀況下不怎麼使用的參數,能夠直接保持默認使其爲None
logits: 一個Tensor。數據類型是如下之一:float32或者float64。
targets: 一個Tensor。數據類型和數據維度都和 logits 相同。
name: 爲這個操做取個名字。
輸出
一個 Tensor ,數據維度和 logits 相同。
三、weighted_cross_entropy_with_logits
weighted_cross_entropy_with_logits(targets, logits, pos_weight, name=None):
此函數功能以及計算方式基本與tf_nn_sigmoid_cross_entropy_with_logits差很少,可是加上了權重的功能,是計算具備權重的sigmoid交叉熵函數
_sentinel:本質上是不用的參數,不用填
targets:一個和logits具備相同的數據類型(type)和尺寸形狀(shape)的張量(tensor)
shape:[batch_size,num_classes],單樣本是[num_classes]
logits:一個數據類型(type)是float32或float64的張量
pos_weight:正樣本的一個係數
name:操做的名字,可填可不填
四、softmax_cross_entropy_with_logits
def softmax_cross_entropy_with_logits(_sentinel=None, labels=None, logits=None, dim=-1, name=None)
這個函數的做用是計算 logits 經 softmax 函數激活以後的交叉熵。
對於每一個獨立的分類任務,這個函數是去度量機率偏差。好比,在 CIFAR-10 數據集上面,每張圖片只有惟一一個分類標籤:一張圖多是一隻狗或者一輛卡車,
但絕對不可能二者都在一張圖中。(這也是和 tf.nn.sigmoid_cross_entropy_with_logits(logits, targets, name=None)這個API的區別)
_sentinel: 這個參數通常狀況不使用,直接設置爲None就好 logits: 一個沒有縮放的對數張量。labels和logits具備相同的數據類型(type)和尺寸(shape) labels: 每一行 labels[i] 必須是一個有效的機率分佈值。 name: 爲這個操做取個名字。
一個 Tensor ,數據維度是一維的,長度是 batch_size,數據類型都和 logits 相同。
五、sparse_softmax_cross_entropy_with_logits
定義
sparse_softmax_cross_entropy_with_logits(_sentinel=None, labels=None, logits=None, name=None):
此函數大體與tf_nn_softmax_cross_entropy_with_logits的計算方式相同,
適用於每一個類別相互獨立且排斥的狀況,一幅圖只能屬於一類,而不能同時包含一條狗和一隻大象
可是在對於labels的處理上有不一樣之處,labels從shape來講此函數要求shape爲[batch_size],
labels[i]是[0,num_classes)的一個索引, type爲int32或int64,即labels限定了是一個一階tensor,
而且取值範圍只能在分類數以內,表示一個對象只能屬於一個類別
_sentinel:本質上是不用的參數,不用填
logits:shape爲[batch_size,num_classes],type爲float32或float64
name:操做的名字,可填可不填