【tensorflow】tf里四种交叉熵损失函数使用说明

0 前言

tensorflow中自带四种交叉熵函数,tensorflow版本太低可能有的交叉熵函数没有,尽量版本高一些。

交叉熵计算输入的logits都不是softmax或sigmoid的输出,而是softmax或sigmoid函数的输入,也就是说在调用损失函数时会在内部进行sigmoid或softmax操作,直接喂给网络预测的输出值就可以了,而不能在调用函数前进行softmax或sigmoid,会导致计算会出错。

常用函数:

tf.nn.softmax_cross_entropy_with_logits()
tf.nn.sparse_softmax_cross_entropy_with_logits()
tf.nn.sigmoid_cross_entropy_with_logits()
tf.nn.weighted_cross_entropy_with_logits()

其次就是参数labels和logits的数据唯独、类型一定要按每个函数要求输入。可以在定义的时候指定或者调用交叉熵函数前转化。

  • 定义时指定:

    • y = np.array([[0, 1, 0], [1, 0, 0]],dtype=float32)
      y_pre = np.array([[12, 3, 2], [3, 10, 1]],dtype=float32) 
      
  • 调用前转化:

    • y = np.array([[1, 0, 0], [0, 1, 0]],dtype=float32)
      y = np.array(y).astype(np.float32)
      

1 softmax 交叉熵

tf.nn.softmax_cross_entropy_with_logits(labels=, logits=)
tf.nn.softmax_cross_entropy_with_logits_v2(labels=Truth,logits=Pred_logits)
  • logits:是NN网络计算的预测输出,维度是[batch_size, num_classes]
  • labels:是标签,和logits 类型相同
  • output:loss值,shape是[batch_size]

logits和labels数据类型和维度必须相同,float16, float32, or float64
文档解释如下:

logits and labels must have the same shape [batch_size, num_classes]
  and the same dtype (either float16, float32, or float64).

高版本tf官方推荐使用第二个 V2,和第一个区别在于:

第一个只对logits进行反向传播,labels保持不变。第二个在进行反向传播的时候,同时对logits和labels都进行反向传播,如果将labels传入的tensor设置为stop_gradients,就和1一样了。

import numpy as np
import tensorflow  as tf

y = np.array([[1, 0, 0], [0, 1, 0]],dtype=np.float32)
#y = np.array(y).astype(np.float32)
y_pre = np.array([[11, 4, 2], [4, 10, 2]],dtype=np.float32)
loss = tf.nn.softmax_cross_entropy_with_logits(labels=y, logits=y_pre)
with tf.Session() as sess:
    print(sess.run(loss))
    
    
'''
[ 0.00103468  0.00281022]
'''

2 sparse_softmax交叉熵

tf.nn.sparse_softmax_cross_entropy_with_logits(labels=None,logits=None)
  • logits:计算的输出,shape是是[batch_size, num_classes],类型时float32、float64
  • labels:shape是 [batch_size],类型必须为int32、int64
  • output:loss值,shape是[batch_size]

logits参数和上面函数一样,labels可以不同,可以不是典型的one-hot多维数组形式,而直接是每组类别对应的数字,也可以是高维。文档如下。

labels of shape `[batch_size]`. But higher dimensions are supported

使用这个函数时,可以理解tf自动将类别[0,1,2,3,…numclass]转换成one_hot数组形式[[1,0,0,0,…],[0,1,0…],[0,0,1,0…]],然后比较计算交叉熵。

  • 参数label是稀疏表示的,比如一个3分类样本的标签,非稀疏表示的形式为[0,0,1]这个表示这个样本为第3个分类,而稀疏表示就表示为2(从0开始,0,1,2,表示三类),同理[0,1,0]非稀疏表示为样本是第二类,而其稀疏表示为1。
y = np.array([0,1],dtype=np.int32)
y_pre = np.array([[11, 4, 2], [4, 10, 2]],dtype=np.float32)
loss = tf.nn.sparse_softmax_cross_entropy_with_logits(labels=y, logits=y_pre)
with tf.Session() as sess:
    print(sess.run(loss))

'''
[ 0.00103468  0.00281022]
'''

3 sigmoid 交叉熵

labels和logits的维度和类型必须相同,float32或者float64

tf.nn.sigmoid_cross_entropy_with_logits(labels=, logits=)
  • logits:计算的输出,shape:[batch_size, num_classes]
  • labels:标签,同维度类型
  • output:loss,shape是[batch_size,num_classes]
labels: A Tensor of the same type and shape as logits.
logits: A Tensor of type float32 or float64

对于输入的logits先通过sigmoid函数计算,再计算它们的交叉熵,但是它对交叉熵的计算方式进行了优化。

output不是每类对应的数,而是一个batch中每个样本的loss,所以一般配合tf.reduce_min(loss,axis=)使用。

y = np.array([[1, 0, 0], [0, 1, 0]],dtype=np.float32)
pre = np.array([[11, 4, 2], [4, 10, 2]],dtype=np.float32)
loss = tf.nn.sigmoid_cross_entropy_with_logits(labels=y,logits=y_pre)
with tf.Session() as sess:
    print(sess.run(loss))

'''
[[1.6701561e-05 4.0181499e+00 2.1269281e+00]
 [4.0181499e+00 4.5398898e-05 2.1269281e+00]]
'''

sess = tf.Session()
a = sess.run(loss)
print(sess.run(tf.reduce_min(a,axis=1)))

‘’‘
[1.6701561e-05 4.5398898e-05]
’‘’

4 weighted交叉熵

有权重的sigmoid交叉熵sigmoid_cross_entropy_with_logits(),正负样本数量不均衡时使用。

标签和预测也需要同类型同维度

  • logits and targets must have the same type and shape.
  • float32 or float64
weighted_cross_entropy_with_logits(targets, logits, pos_weight, name=None)
  • logits:shape为[batch_size,num_classes],单样本是[num_classes]
  • targets:
  • pos_weight:正样本的系数
  • output:loss值,shape:[batch_size,num_classes]

输出的也是每一组batch的所有loss,需要配合tf.reduce_min(loss,axis=)筛选

sess.run(tf.nn.weighted_cross_entropy_with_logits(logits=y,targets=y_pre,pos_weight=2.0))

和sigmoid基本一样,就是多了个正样本权重。

使用过程中可以使用 help(函数名) 查看定义和如何使用。

参考博客:带公式的交叉熵:
简书
博客
博客2

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
TensorFlow中,可以使用`tf.nn.softmax_cross_entropy_with_logits()`函数来定义交叉熵损失函数。 下面是一个简单的示例: ```python import tensorflow as tf # 定义输入和标签 x = tf.placeholder(tf.float32, [None, 10]) y = tf.placeholder(tf.float32, [None, 10]) # 定义模型 W = tf.Variable(tf.zeros([10, 10])) b = tf.Variable(tf.zeros([10])) logits = tf.matmul(x, W) + b y_pred = tf.nn.softmax(logits) # 定义损失函数 cross_entropy = tf.nn.softmax_cross_entropy_with_logits(labels=y, logits=logits) loss = tf.reduce_mean(cross_entropy) # 定义训练操作 optimizer = tf.train.GradientDescentOptimizer(0.5) train_op = optimizer.minimize(loss) # 训练模型 with tf.Session() as sess: sess.run(tf.global_variables_initializer()) # 训练过程... ``` 在上面的示例中,我们首先定义了输入和标签的占位符。然后,我们定义了一个简单的线性模型,其中权重矩阵W和偏置向量b都初始化为零。接下来,我们使用`tf.nn.softmax_cross_entropy_with_logits()`函数来计算交叉熵损失,然后使用`tf.reduce_mean()`函数将所有样本的损失求平均。最后,我们使用梯度下降优化器来最小化损失函数。 需要注意的是,`tf.nn.softmax_cross_entropy_with_logits()`函数要求我们传递logits和labels参数,其中logits是模型的输出,labels是真实标签。在上面的示例中,我们使用了softmax函数来将logits转换为概率分布,然后将其传递给了`tf.nn.softmax_cross_entropy_with_logits()`函数。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值