菜鸟笔记
提升您的技术认知

交叉熵-ag真人游戏

 

一.什么是交叉熵

交叉熵是一个信息论中的概念,它原来是用来估算平均编码长度的。给定两个概率分布p和q,通过q来表示p的交叉熵为:

     注意,交叉熵刻画的是两个概率分布之间的距离,或可以说它刻画的是通过概率分布q来表达概率分布p的困难程度,p代表正确答案,q代表的是预测值,交叉熵越小,两个概率的分布约接近。

     那么,在神经网络中怎样把前向传播得到的结果也变成概率分布呢?softmax回归就是一个非常有用的方法。(所以面试官会经常问你,为什么交叉熵经常要个softmax一起使用?)

    假设原始的神经网络的输出为,那么经过softmax回归处理之后的输出为: 

                                                                

这样就把神经网络的输出也变成了一个概率分布,从而可以通过交叉熵来计算预测的概率分布和真实答案的概率分布之间的距离了。

   举个例子,假设有一个3分类问题,某个样例的正确答案是(1,0,0),这个模型经过softmax回归之后的预测答案是(0.5,0.4,0.1),那么预测和正确答案之间的交叉熵为:

                                                            

如果另一个模型的预测是(0.8,0.1,0.1),那么这个预测值和真实值之间的交叉熵是:

                                                           

显然我们看到第二个预测要优于第一个。这里的(1,0,0)就是正确答案p,(0.5,0.4,0.1)和(0.8,0.1,0.1)就是预测值q,显然用(0.8,0.1,0.1)表达(1,0,0)的困难程度更小。

二.为什么要用交叉熵来做损失函数

在逻辑回归问题中,常常使用mse(mean squared error)作为loss函数,此时:

                                                                      

这里的就表示期望输出,表示原始的实际输出(就是还没有加softmax)。这里的m表示有m个样本,loss为m个样本的loss均值。mse在逻辑回归问题中比较好用,那么在分类问题中还是如此么?我们来看看loss曲线。

   首先,将原始的实际输出节点都经过softmax,

                                                                                

现在,拿出一个样例来看,使用mse的loss为:

                                                               

其中:和都是常数,那么loss就可以简化为:

                                                                               

取c1=1,c2=2,绘制图像:

 

大家可以看到,这是一个非凸函数。(后面我会再写一篇来说明只有当损失函数为凸函数时,梯度下降算法才能保证达到全局最优解),如果落在左半平面,由于梯度太小,训练困难。由此可以说,mse在分类问题中,并不是一个好的loss函数。(现在知道如何回答面试官的问题了吗?如果面试官问你为什么在分类的时候不选用mse而是交叉熵作为损失函数?)那么我们来看看交叉熵作为损失函数的时候的loss曲线,看完你就清楚了。

如果利用交叉熵作为损失函数的话,那么:

                                                                

还是一样,就表示期望输出,表示原始的实际输出(就是还没有加softmax),由于one-hot标签的特殊性,一个1,剩下全是0,loss可以简化为: 

                                                                                   

加入(softmax)得: 

                                                                                     (这一步咋来的,哪来的c1-)

取c1=1,c2=2绘制曲线如下 :                                                                                             

相对mse而言,曲线整体呈单调性,loss越大,梯度越大。便于梯度下降反向传播,利于优化。所以一般针对分类问题采用交叉熵作为loss函数。

三.利用tensorflow实现交叉熵

cross_entropy=-tf.reduce_mean(y_*tf.log(tf.clip_by_value(y,1e-10,1.0)))

其中y_就代表p,也就是正确结果(或者说标签),y代表q,也就是预测结果(或者说实际输出)。

这里的tf.reduce_mean()是求一个平均值,具体是这样的:

tf.reduce_mean(x):就是求所有元素的平均值;

tf.reduce_mean(x,0):就是求维度为0的平均值,也就是求列平均;

tf.reduce_mean(x,1):就是求维度为1的平均值,也就是求行平均。

这里的tf.clip_by_value(v,a,b):表示把v限制在a~b的范围内,小于a的让它等于a,大于b的让它等于b。(通俗易懂)

给出一个tf.clip_by_value()的样例。

 
  1. v=tf.constant([[1.0,2.0,3.0],[4.0,5.0,6.0]])

  2. print(tf.clip_by_value(v,2.5,4.5).eval())

  3. #输出为[[2.5 2.5 3.][4. 4.5 4.5]]

可以看到把一个2*3维的张量v的所有元素都限制在2.5~4.5之内,这样做的目的是可以避免一些运算错误(比如说log0是无效的)。还有一个要注意的点:代码中的*,这里的*不是矩阵相乘,而是元素之间直接相乘。矩阵乘法需要用tf.matmul函数来完成。

因为交叉熵一般会与softmax回归一起使用,所以tensorflow对这两个功能进行了同一封装,并提供了tf.nn.softmax_cross_entropy_with_logits函数。比如可以直接通过以下代码实现了sotfmax回归之后的交叉熵损失函数:

cross_entropy=tf.nn.sparse_sotfmax_cross_entropy_with_logits(label=y_,logits=y)

这里y代表神经网络的原始输出(就是还没有经过sotfmax的输出),而y_是给出的标准答案。

 

四种交叉熵计算函数

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
tf.nn.sigmoid_cross_entropy_with_logits(logits=logits, labels=labels)
  • 测量每个类别独立且不相互排斥的离散分类任务中的概率。(可以执行多标签分类,其中图片可以同时包含大象和狗。)
  • 计算方式:对输入的logits先通过sigmoid函数计算,再计算它们的交叉熵,但是它对交叉熵的计算方式进行了优化,使得的结果不至于溢出。
  • 适用:每个类别相互独立但互不排斥的情况:例如一幅图可以同时包含一条狗和一只大象。
  • output不是一个数,而是一个batch中每个样本的loss,所以一般配合tf.reduce_mean(loss)使用。
  • 计算公式:

     

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)使用。
  • 计算公式:

     

sparse_softmax_cross_entropy_with_logits

sparse_softmax_cross_entropy_with_logits 是 softmax_cross_entropy_with_logits 的易用版本,除了输入参数不同,作用和算法实现都是一样的。

区别是:softmax_cross_entropy_with_logits 要求传入的 labels 是经过 one_hot encoding 的数据,而 sparse_softmax_cross_entropy_with_logits 不需要。

 

 

tf.nn.weighted_cross_entropy_with_logits(labels,logits, pos_weight, name=none) 
  • 计算具有权重的sigmoid交叉熵sigmoid_cross_entropy_with_logits()
  • 计算公式:

     

    weighted_cross_entropy_with_logits 是 sigmoid_cross_entropy_with_logits 的拓展版,输入参数和实现和后者差不多,可以多支持一个 pos_weight 参数,目的是可以增加或者减小正样本在算 cross entropy 时的 loss 。

 

网站地图