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−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 = logitsz = 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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章