深度学习中softmax交叉熵损失函数的理解

2018-08-11 23:49:43 lilong117194 阅读数 5198更多

分类专栏: Deep learning
 
版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。

1. softmax层的作用

通过神经网络解决多分类问题时,最常用的一种方式就是在最后一层设置n个输出节点,无论在浅层神经网络还是在CNN中都是如此,比如,在AlexNet中最后的输出层有1000个节点,即便是ResNet取消了全连接层,但1000个节点的输出层还在。

一般情况下,最后一个输出层的节点个数与分类任务的目标数相等。 
假设最后的节点数为N,那么对于每一个样例,神经网络可以得到一个N维的数组作为输出结果,数组中每一个维度会对应一个类别。在最理想的情况下,如果一个样本属于k,那么这个类别所对应的的输出节点的输出值应该为1,而其他节点的输出都为0,即 [0,0,1,0,….0,0][0,0,1,0,….0,0],这个数组也就是样本的Label,是神经网络最期望的输出结果,但实际是这样的输出[0.01,0.01,0.6,....0.02,0.01][0.01,0.01,0.6,....0.02,0.01],这其实是在原始输出的基础上加入了softmax的结果,原始的输出是输入的数值做了复杂的加权和与非线性处理之后的一个值而已,这个值可以是任意的值,但是经过softmax层后就成了一个概率值,而且概率和为1。 
假设神经网络的原始输出为y_1,y_2,….,y_n,那么经过Softmax回归处理之后的输出为 :

 
y′=softmax(yi)=eyi∑nj=1eyjy′=softmax(yi)=eyi∑j=1neyj

以上可以看出:∑y′=1∑y′=1 
这也是为什么softmax层的每个节点的输出值成为了概率和为1的概率分布。

2. 交叉熵损失函数的数学原理

上面说过实际的期望输出,也就是标签是[0,0,1,0,….0,0][0,0,1,0,….0,0]这种形式,而实际的输出是[0.01,0.01,0.6,....0.02,0.01][0.01,0.01,0.6,....0.02,0.01]这种形式,这时按照常理就需要有一个损失函数来判定实际输出和期望输出的差距,交叉熵就是用来判定实际的输出与期望的输出的接近程度!下面就简单介绍下交叉熵的原理。

交叉熵刻画的是实际输出(概率)与期望输出(概率)的距离,也就是交叉熵的值越小,两个概率分布就越接近。假设概率分布p为期望输出(标签),概率分布q为实际输出,H(p,q)为交叉熵。

  • 第一种交叉熵损失函数的形式:

     
    H(p,q)=−∑xp(x)logq(x)H(p,q)=−∑xp(x)logq(x)

举个例子: 
假设N=3,期望输出为p=(1,0,0),实际输出q1=(0.5,0.2,0.3),q2=(0.8,0.1,0.1)q1=(0.5,0.2,0.3),q2=(0.8,0.1,0.1),这里的q1,q2两个输出分别代表在不同的神经网络参数下的实际输出,通过计算其对应的交叉熵来优化神经网络参数,计算过程: 
H(p,q1)=−1(1×log0.5+0×log0.2+0×log0.3)H(p,q1)=−1(1×log0.5+0×log0.2+0×log0.3) 
假设结果:H(p,q1)=0.3H(p,q1)=0.3 
H(p,q2)=−1(1×log0.8+0×log0.1+0×log0.1)H(p,q2)=−1(1×log0.8+0×log0.1+0×log0.1) 
假设结果:H(p,q2)=0.1H(p,q2)=0.1 
这时得到了q2q2是相对正确的分类结果。

  • 第二种交叉熵损失函数形式:

     
    H(p,q)=−∑x(p(x)logq(x)+(1−p(x))log(1−q(x)))H(p,q)=−∑x(p(x)logq(x)+(1−p(x))log(1−q(x)))

    下面简单推到其过程: 
    我们知道,在二分类问题模型:例如逻辑回归「Logistic Regression」、神经网络「Neural Network」等,真实样本的标签为 [0,1],分别表示负类和正类。模型的最后通常会经过一个 Sigmoid 函数,输出一个概率值,这个概率值反映了预测为正类的可能性:概率越大,可能性越大。 
    Sigmoid 函数的表达式和图形如下所示:g(s)=11+e−sg(s)=11+e−s 
    其中 s 是模型上一层的输出,Sigmoid 函数有这样的特点:s = 0 时,g(s) = 0.5;s >> 0 时, g ≈ 1,s << 0 时,g ≈ 0。显然,g(s) 将前一级的线性输出映射到 [0,1] 之间的数值概率上。 
    其中预测输出即 Sigmoid 函数的输出g(s)表征了当前样本标签为 1 的概率: 
    P(y=1|x)=y^P(y=1|x)=y^ 
    p(y=0|x)=1−y^p(y=0|x)=1−y^ 
    这个时候从极大似然性的角度出发,把上面两种情况整合到一起: 
    p(y|x)=y^y(1−y^)(1−y)p(y|x)=y^y(1−y^)(1−y) 
    这个函数式表征的是: 
    当真实样本标签 y = 1 时,上面式子第二项就为 1,概率等式转化为: 
    P(y=1|x)=y^P(y=1|x)=y^ 
    当真实样本标签 y = 0 时,上面式子第一项就为 1,概率等式转化为: 
    P(y=0|x)=1−y^P(y=0|x)=1−y^ 
    两种情况下概率表达式跟之前的完全一致,只不过我们把两种情况整合在一起了。那这个时候应用极大似然估计应该得到的是所有的概率值乘积应该最大,即: 
    L=∑Ni=1y^yii(1−y^i)(1−yi)L=∑i=1Ny^iyi(1−y^i)(1−yi) 
    引入log函数后得到: 
    L′=log(L)=∑Ni=1yilogy^i+(1−yi)log(1−y^i)L′=log(L)=∑i=1Nyilogy^i+(1−yi)log(1−y^i) 
    这时令loss=-log(L)=-L',也就是损失函数越小越好,而此时也就是 L'越大越好。

而在实际的使用训练过程中,数据往往是组合成为一个batch来使用,所以对用的神经网络的输出应该是一个m*n的二维矩阵,其中m为batch的个数,n为分类数目,而对应的Label也是一个二维矩阵,还是拿上面的数据,组合成一个batch=2的矩阵

 
q=[0.50.80.20.10.30.1]q=[0.50.20.30.80.10.1]
 
p=[110000]p=[100100]

根据第一种交叉熵的形式得到:

 
H(p,q)=[0.30.1]H(p,q)=[0.30.1]

而对于一个batch,最后取平均为0.2。

3. 在TensorFlow中实现交叉熵

在TensorFlow可以采用这种形式:

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

其中y_表示期望的输出,y表示实际的输出(概率值),*为矩阵元素间相乘,而不是矩阵乘。 
并且通过tf.clip_by_value函数可以将一个张量中的数值限制在一个范围之内,这样可以避免一些运算错误(比如log0是无效的),tf.clip_by_value函数是为了限制输出的大小,为了避免log0为负无穷的情况,将输出的值限定在(1e-10, 1.0)之间,其实1.0的限制是没有意义的,因为概率怎么会超过1呢。比如:

import tensorflow as tf

v=tf.constant([[1.0,2.0,3.0],[4.0,5.0,6.0]])
with tf.Session() as sess:
print(tf.clip_by_value(v,2.5,4.5).eval(session=sess))
  • 1
  • 2
  • 3
  • 4
  • 5

结果:

[[2.5 2.5 3. ]
[4. 4.5 4.5]]
  • 1
  • 2

上述代码实现了第一种形式的交叉熵计算,需要说明的是,计算的过程其实和上面提到的公式有些区别,按照上面的步骤,平均交叉熵应该是先计算batch中每一个样本的交叉熵后取平均计算得到的,而利用tf.reduce_mean函数其实计算的是整个矩阵的平均值,这样做的结果会有差异,但是并不改变实际意义。

import tensorflow as tf

v=tf.constant([[1.0,2.0,3.0],[4.0,5.0,6.0]])
with tf.Session() as sess:
# 输出3.5
print(tf.reduce_mean(v).eval())
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

由于在神经网络中,交叉熵常常与Sorfmax函数组合使用,所以TensorFlow对其进行了封装,即:

cross_entropy = tf.nn.sorfmax_cross_entropy_with_logits(y_ ,y)
 
  • 1

与第一个代码的区别在于,这里的y用神经网络最后一层的原始输出就好了,而不是经过softmax层的概率值。

参考:https://blog.csdn.net/red_stone1/article/details/80735068 
https://blog.csdn.net/chaipp0607/article/details/73392175

【转载】深度学习中softmax交叉熵损失函数的理解的更多相关文章

  1. softmax交叉熵损失函数求导

    来源:https://www.jianshu.com/p/c02a1fbffad6 简单易懂的softmax交叉熵损失函数求导 来写一个softmax求导的推导过程,不仅可以给自己理清思路,还可以造福 ...

  2. 深度学习原理与框架-神经网络结构与原理 1.得分函数 2.SVM损失函数 3.正则化惩罚项 4.softmax交叉熵损失函数 5. 最优化问题(前向传播) 6.batch_size(批量更新权重参数) 7.反向传播

    神经网络由各个部分组成 1.得分函数:在进行输出时,对于每一个类别都会输入一个得分值,使用这些得分值可以用来构造出每一个类别的概率值,也可以使用softmax构造类别的概率值,从而构造出loss值, ...

  3. 机器学习之路:tensorflow 深度学习中 分类问题的损失函数 交叉熵

    经典的损失函数----交叉熵 1 交叉熵: 分类问题中使用比较广泛的一种损失函数, 它刻画两个概率分布之间的距离 给定两个概率分布p和q, 交叉熵为: H(p, q) = -∑ p(x) log q( ...

  4. 简单易懂的softmax交叉熵损失函数求导

    参考: https://blog.csdn.net/qian99/article/details/78046329

  5. 深度学习面试题07:sigmod交叉熵、softmax交叉熵

    目录 sigmod交叉熵 Softmax转换 Softmax交叉熵 参考资料 sigmod交叉熵 Sigmod交叉熵实际就是我们所说的对数损失,它是针对二分类任务的损失函数,在神经网络中,一般输出层只 ...

  6. 深度学习中交叉熵和KL散度和最大似然估计之间的关系

    机器学习的面试题中经常会被问到交叉熵(cross entropy)和最大似然估计(MLE)或者KL散度有什么关系,查了一些资料发现优化这3个东西其实是等价的. 熵和交叉熵 提到交叉熵就需要了解下信息论 ...

  7. 深度学习基础系列(五)| 深入理解交叉熵函数及其在tensorflow和keras中的实现

    在统计学中,损失函数是一种衡量损失和错误(这种损失与“错误地”估计有关,如费用或者设备的损失)程度的函数.假设某样本的实际输出为a,而预计的输出为y,则y与a之间存在偏差,深度学习的目的即是通过不断地 ...

  8. [ch03-02] 交叉熵损失函数

    系列博客,原文在笔者所维护的github上:https://aka.ms/beginnerAI, 点击star加星不要吝啬,星越多笔者越努力. 3.2 交叉熵损失函数 交叉熵(Cross Entrop ...

  9. 关于交叉熵损失函数Cross Entropy Loss

    1.说在前面 最近在学习object detection的论文,又遇到交叉熵.高斯混合模型等之类的知识,发现自己没有搞明白这些概念,也从来没有认真总结归纳过,所以觉得自己应该沉下心,对以前的知识做一个 ...

随机推荐

  1. Acwing-168-生日蛋糕(搜索, 剪枝)

    链接: https://www.acwing.com/problem/content/170/ 题意: 7月17日是Mr.W的生日,ACM-THU为此要制作一个体积为Nπ的M层生日蛋糕,每层都是一个圆 ...

  2. 浅谈Spring @Order注解的使用(转)

    注解@Order或者接口Ordered的作用是定义Spring IOC容器中Bean的执行顺序的优先级,而不是定义Bean的加载顺序,Bean的加载顺序不受@Order或Ordered接口的影响: 1 ...

  3. shareSDK集成遇到的问题汇总

    问题一.平台添加应用时需要输入的签名(下图)的获取方式 第一步.通过android studio生成签名保存在本地 第二步.查看签名的信息 问题二.由于同事集成了QQ登录和微信登录,后来又需要加入微博 ...

  4. Java进阶知识07 Hibernate一对一双向外键关联(Annotation+XML实现)

    1.Annotation 注解版 1.1.创建Husband类和Wife类 package com.shore.model; import javax.persistence.Entity; impo ...

  5. matlab函数 bsxfun浅谈(转载)

    关于matlab函数 bsxfun本文来源:http://blog.sina.com.cn/s/blog_9e67285801010ttn.html a=[1 2 3];b=[1 2 3]';c=bs ...

  6. ssh以及双机互信

    当我们要远程到其他主机上面时就需要使用ssh服务了. 我们就来安装一下sshd服务以及ssh命令的使用方法. 服务安装: 需要安装OpenSSH 四个安装包: 安装包: openssh-5.3p1-1 ...

  7. 2016 Multi-University Training Contest 4 部分题解

    1001,官方题解是直接dp,首先dp[i]表示到i位置的种类数,它首先应该等于dp[i-1],(假设m是B串的长度)同时,如果(i-m+1)这个位置开始到i这个位置的这一串是和B串相同的,那么dp[ ...

  8. [CSP-S模拟测试]:慢无止境的八月(乱搞)

    题目传送门(内部题102) 输入格式 第一行三个正整数$n,k,q$,分别表示数列长度,操作长度和修改个数. 第二行$n$个数,表示给出的终止数列. 接下来$q$行,每行两个数$pos,dx$,表示将 ...

  9. BZOJ3331压力

    码量略大. 题意就是求路径必经点. tarjan缩点,所有的非割点只有是起点终点时才必经,直接开个ans数组就OK了. 至于割点,因为缩完点之后的图是vDcc和割点共同组成的,而且题目说连通,那就是棵 ...

  10. zookeeper系列(二)zookeeper的使用--javaAPI

    作者:leesf    掌控之中,才会成功:掌控之外,注定失败: 出处:http://www.cnblogs.com/leesf456/ (尊重原创,感谢作者整理的这么好,作者的部分内容添加了我的理解 ...