[tensorflow损失函数系列]sigmoid_cross_entropy_with_logits

2020-08-14 10:48:56 浏览数 (2)

函数定义

代码语言:javascript复制
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 必须有相同的数据类型和数据维度。
  • 它适用于每个类别相互独立但互不排斥的情况,在一张图片中,同时包含多个分类目标(大象和狗),那么就可以使用这个函数。

例子

代码语言:javascript复制
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)基本函数式
代码语言:javascript复制
      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)时溢出,我们使用以下这种形式表示

代码语言:javascript复制
        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

0 人点赞