前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >TensorFlow交叉熵函数(cross_entropy)·理解

TensorFlow交叉熵函数(cross_entropy)·理解

作者头像
狼啸风云
修改2022-09-02 20:49:53
3.4K0
修改2022-09-02 20:49:53
举报
文章被收录于专栏:计算机视觉理论及其实现

内容参考: Tensorflow四种交叉熵函数计算公式:tf.nn.cross_entropy TensorFlow四种Cross Entropy算法实现和应用

交叉熵(Cross Entropy)

交叉熵(Cross Entropy)是Loss函数的一种(也称为损失函数或代价函数),用于描述模型预测值与真实值的差距大小,常见的Loss函数就是均方平方差(Mean Squared Error),定义如下。

C=\frac{(y-a)^{2}}{2}

注意:tensorflow交叉熵计算函数输入中的logits都不是softmax或sigmoid的输出,而是softmax或sigmoid函数的输入,因为它在函数内部进行sigmoid或softmax操作

TensorFlow交叉熵函数

TensorFlow针对分类问题,实现了四个交叉熵函数,分别是

  • tf.nn.sigmoid_cross_entropy_with_logits
  • tf.nn.softmax_cross_entropy_with_logits
  • tf.nn.sparse_softmax_cross_entropy_with_logits
  • tf.nn.weighted_cross_entropy_with_logits
  • 详细内容参考API文档

1. sigmoid_cross_entropy_with_logits

代码语言:javascript
复制
tf.nn.sigmoid_cross_entropy_with_logits(logits=logits, labels=labels)
  • 计算方式:对输入的logits先通过sigmoid函数计算,再计算它们的交叉熵,但是它对交叉熵的计算方式进行了优化,使得的结果不至于溢出。
  • 适用:每个类别相互独立但互不排斥的情况:例如一幅图可以同时包含一条狗和一只大象。
  • output不是一个数,而是一个batch中每个样本的loss,所以一般配合tf.reduce_mean(loss)使用。
  • 计算公式:

\begin{array}{l} y=\text { labels } \quad p_{i j}=\operatorname{sigmoid}\left(\operatorname{logits}_{i j}\right)=\frac{1}{1+e^{-\operatorname{logits}_{i j}}} \\ \operatorname{loss}_{i j}=-\left[y_{i j} * \ln p_{i j}+\left(1-y_{i j}\right) \ln \left(1-p_{i j}\right)\right] \end{array}

  • 用例:
代码语言:javascript
复制
import tensorflow as tf
import numpy as np

def sigmoid(x):
    return 1.0/(1+np.exp(-x))

# 5个样本三分类问题,且一个样本可以同时拥有多类
y = np.array([[1,0,0],[0,1,0],[0,0,1],[1,1,0],[0,1,0]] 
logits = np.array([[12,3,2],[3,10,1],[1,2,5],[4,6.5,1.2],[3,6,1]])
# 按计算公式计算
y_pred = sigmoid(logits)
E1 = -y*np.log(y_pred)-(1-y)*np.log(1-y_pred)
print(E1)     # 按计算公式计算的结果
# 按封装方法计算
sess =tf.Session()
y = np.array(y).astype(np.float64) # labels是float64的数据类型
E2 = sess.run(tf.nn.sigmoid_cross_entropy_with_logits(labels=y,logits=logits))
print(E2)     # 按 tf 封装方法计算

if E1.all() == E2.all():
    print("True")
else:
    print("False")
# 输出的E1,E2结果相同

2. softmax_cross_entropy_with_logits

代码语言:javascript
复制
tf.nn.softmax_cross_entropy_with_logits(_sentinel=None, labels=None, logits=None, dim=-1, name=None)
  • labels:和logits具有相同type和shape的张量(tensor),,是一个有效的概率,sum(labels)=1, one_hot=True(向量中只有一个值为1.0,其他值为0.0)。
  • 计算方式:对输入的logits先通过softmax函数计算,再计算它们的交叉熵,但是它对交叉熵的计算方式进行了优化,使得结果不至于溢出。
  • 适用:每个类别相互独立且排斥的情况,一幅图只能属于一类,而不能同时包含一条狗和一只大象。
  • output:不是一个数,而是一个batch中每个样本的loss,所以一般配合tf.reduce_mean(loss)使用。
  • 计算公式:

\begin{array}{c} y=\text { labels } \quad p_{i}=\text { softmax }\left(\operatorname{logits}_{i}\right)=\left[\frac{e^{\text {logits }_{i j}}}{\sum_{j=0}^{\text {numclasses-1 }} e^{\text {logits }_{i j}}}\right] \\ \operatorname{loss}_{i}=-\sum_{j=0}^{\text {numclasses-1 }} y_{i j} * \ln p_{i j} \end{array}

  • 用例:
代码语言:javascript
复制
import tensorflow as tf
import numpy as np

def softmax(x):
    sum_raw = np.sum(np.exp(x),axis=-1)
    x1 = np.ones(np.shape(x))
    for i in range(np.shape(x)[0]):
        x1[i] = np.exp(x[i])/sum_raw[i]
    return x1

y = np.array([[1,0,0],[0,1,0],[0,0,1],[1,0,0],[0,1,0]])# 每一行只有一个1
logits =np.array([[12,3,2],[3,10,1],[1,2,5],[4,6.5,1.2],[3,6,1]])
# 按计算公式计算
y_pred =softmax(logits)
E1 = -np.sum(y*np.log(y_pred),-1)
print(E1)
# 按封装方法计算
sess = tf.Session()
y = np.array(y).astype(np.float64)
E2 = sess.run(tf.nn.softmax_cross_entropy_with_logits(labels=y,logits=logits))
print(E2)

if E1.all() == E2.all():
    print("True")
else:
    print("False")
# 输出的E1,E2结果相同

3. sparse_softmax_cross_entropy_with_logits

代码语言:javascript
复制
tf.nn.sparse_softmax_cross_entropy_with_logits(_sentinel=None,labels=None,logits=None, name=None)
  • labels:shape为[batch_size],labels[i]是{0,1,2,……,num_classes-1}的一个索引, type为int32或int64
  • 计算方式:对输入的logits先通过softmax函数计算,再计算它们的交叉熵,但是它对交叉熵的计算方式进行了优化,使得结果不至于溢出。
  • 适用:每个类别相互独立且排斥的情况,一幅图只能属于一类,而不能同时包含一条狗和一只大象 。
  • output不是一个数,而是一个batch中每个样本的loss,所以一般配合tf.reduce_mean(loss)使用。
  • 计算公式: 和tf.nn.softmax_cross_entropy_with_logits()的计算公式一样,只是要将labels转换成tf.nn.softmax_cross_entropy_with_logits()中labels的形式

4. weighted_cross_entropy_with_logits

代码语言:javascript
复制
tf.nn.weighted_cross_entropy_with_logits(labels,logits, pos_weight, name=None) 
  • 计算具有权重的sigmoid交叉熵sigmoid_cross_entropy_with_logits()
  • 计算公式:

\begin{array}{c} y=\text { labels } \quad p_{i}=\text { softmax }\left(\operatorname{logits}_{i}\right)=\left[\frac{e^{\text {logits }_{i j}}}{\sum_{j=0}^{\text {numclasses-1 }} e^{\text {logits }_{i j}}}\right] \\ \operatorname{loss}_{i}=-\sum_{j=0}^{\text {numclasses-1 }} y_{i j} * \ln p_{i j} \end{array}

总结

根据业务需求(分类目标是否独立和互斥)来选择基于sigmoid或者softmax的实现。

TensorFlow提供的Cross Entropy函数基本cover了多目标和多分类的问题,但如果同时是多目标多分类的场景,肯定是无法使用softmax_cross_entropy_with_logits,如果使用sigmoid_cross_entropy_with_logits我们就把多分类的特征都认为是独立的特征,而实际上他们有且只有一个为1的非独立特征,计算Loss时不如Softmax有效。这里可以预测下,未来TensorFlow社区将会实现更多的op解决类似的问题,我们也期待更多人参与TensorFlow贡献算法和代码 !

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020/08/26 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 交叉熵(Cross Entropy)
  • TensorFlow交叉熵函数
  • 1. sigmoid_cross_entropy_with_logits
  • 2. softmax_cross_entropy_with_logits
  • 3. sparse_softmax_cross_entropy_with_logits
  • 4. weighted_cross_entropy_with_logits
  • 总结
相关产品与服务
批量计算
批量计算(BatchCompute,Batch)是为有大数据计算业务的企业、科研单位等提供高性价比且易用的计算服务。批量计算 Batch 可以根据用户提供的批处理规模,智能地管理作业和调动其所需的最佳资源。有了 Batch 的帮助,您可以将精力集中在如何分析和处理数据结果上。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档