函數定義
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−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 必須有相同的數據類型和數據維度。
它適用於每個類別相互獨立但互不排斥的情況,在一張圖片中,同時包含多個分類目標(大象和狗),那麼就可以使用這個函數。
例子
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)))max(x,0)−x∗z+log(1+exp(−abs(x)))
注意logits和labels必須具有相同的type和shape