sigmoid_cross_entropy_with_logits
覺得有用的話,歡迎一起討論相互學習~
函數定義
def sigmoid_cross_entropy_with_logits(_sentinel=None, # pylint: disable=invalid-name
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)) \]
- 為了確保計算穩定,避免溢出,真實的計算實現如下:
\[max(x, 0) - x * z + log(1 + exp(-abs(x)) ) \]
- logits 和 targets 必須有相同的數據類型和數據維度。
- 它適用於每個類別相互獨立但互不排斥的情況,在一張圖片中,同時包含多個分類目標(大象和狗),那么就可以使用這個函數。
例子
import numpy as np
import tensorflow as tf
input_data = tf.Variable(np.random.rand(1, 3), dtype=tf.float32)
# np.random.rand()傳入一個shape,返回一個在[0,1)區間符合均勻分布的array
output = tf.nn.sigmoid_cross_entropy_with_logits(logits=input_data, labels=[[1.0, 0.0, 0.0]])
with tf.Session() as sess:
init = tf.global_variables_initializer()
sess.run(init)
print(sess.run(output))
# [[ 0.5583781 1.06925142 1.08170223]]
輸入與輸出
輸入
- _sentinel: 一般情況下不怎么使用的參數,可以直接保持默認使其為None
- logits: 一個Tensor。數據類型是以下之一:float32或者float64。
- targets: 一個Tensor。數據類型和數據維度都和 logits 相同。
- name: 為這個操作取個名字。
輸出 - 一個 Tensor ,數據維度和 logits 相同。
推導過程
設x = logits, z = labels.
- logistic loss 計算式為:
- 其中交叉熵(cross entripy)基本函數式
z * -log(sigmoid(x)) + (1 - z) * -log(1 - sigmoid(x))
= z * -log(1 / (1 + exp(-x))) + (1 - z) * -log(exp(-x) / (1 + exp(-x)))
= z * log(1 + exp(-x)) + (1 - z) * (-log(exp(-x)) + log(1 + exp(-x)))
= z * log(1 + exp(-x)) + (1 - z) * (x + log(1 + exp(-x))
= (1 - z) * x + log(1 + exp(-x))
= x - x * z + log(1 + exp(-x))
對於x<0時,為了避免計算exp(-x)時溢出,我們使用以下這種形式表示
x - x * z + log(1 + exp(-x))
= log(exp(x)) - x * z + log(1 + exp(-x))
= - x * z + log(1 + exp(x))
綜合x>0和x<0的情況,我們使用以下函數式
$$max(x, 0) - x * z + log(1 + exp(-abs(x)))$$
注意logits和labels必須具有相同的type和shape




