信息熵 条件熵 交叉熵 联合熵 相对熵(KL散度) 互信息(信息增益)

粗略版快速总结

条件熵 H ( Q ∣ P ) = 联合熵 H ( P , Q ) − H ( P ) 条件熵H(Q∣P)=联合熵H(P,Q)−H(P) 条件熵H(QP)=联合熵H(P,Q)H(P)

信息增益 I ( P , Q ) = H ( P ) − H ( P ∣ Q ) = H ( P ) + H ( Q ) − H ( P , Q ) 信息增益 I(P,Q)=H(P)−H(P∣Q)=H(P)+H(Q)-H(P,Q) 信息增益I(P,Q)=H(P)H(PQ)=H(P)+H(Q)H(P,Q),也就是Information Gain,互信息

KL散度(相对熵) K L ( P , Q ) = − H ( P ) + 交叉熵 C E ( P , Q ) KL(P,Q)=-H(P)+交叉熵CE(P,Q) KL(P,Q)=H(P)+交叉熵CE(P,Q)

详细定义

如果一个样本是n类其中之一,也就是说target是onehot形式,例如三类那么target=[0,0,1],拿target=[0,0,1]来说就是 p 0 = 0 p_0=0 p0=0 p 1 = 0 p_1=0 p1=0 p 2 = 1 p_2=1 p2=1。写成表达式可以是 p i p_i pi,n=3
那么经过神经网络运算出来的Logits可能是在(-inf,inf)之间,那么一般会通过softmax归一化到(0,1)之间,这个归一化到(0,1)之间的数我们可以用 q i q_i qi来表示,当然对于上面有3类的例子来说,n=3
好了,既然明确了 p i p_i pi是第i个类的在(0,1)之间target q i q_i qi是第i个类的logit归一化到(0,1)之间的结果,那么开始各种定义了

相对熵(KL散度)

K L ( P , Q ) = ∑ i ∈ [ 0 , n − 1 ] p i l o g p i q i KL(P,Q)=\sum _{i \in[0,n-1]}p_i log \frac{p_i}{q_i} KL(P,Q)=i[0,n1]pilogqipi

交叉熵(CE Loss)

C E ( P , Q ) = − ∑ i ∈ [ 0 , n − 1 ] p i l o g q i K L ( P , Q ) = H ( P ) + C E ( P , Q ) CE(P,Q)=-\sum _{i \in[0,n-1]}p_i log q_i \\ KL(P,Q) = H(P)+CE(P,Q) CE(P,Q)=i[0,n1]pilogqiKL(P,Q)=H(P)+CE(P,Q)
来看一下Pytorch里的交叉熵是怎么实现的,手动验证下:

import torch
from torch import nn
import mathloss_f = nn.CrossEntropyLoss(reduction='mean')
output = torch.randn(2,3) #表示2个样本,3个类别
# target = torch.from_numpy(np.array([1, 0])).type(torch.LongTensor)
target = torch.LongTensor([0,2]) #表示label0和label2
loss = loss_f(output, target)print('CrossEntropy loss: ', loss)
print(f'reduction=none,所以可以看到每一个样本loss,输出为[{loss}]')def manual_cal(sample_index, target, output):#输入是样本下标sample_output = output[sample_index]sample_target = target[sample_index]x_class = sample_output[sample_target]sample_output_len = len(sample_output)log_sigma_exp_x = math.log(sum(math.exp(sample_output[i]) for i in range(sample_output_len)))sample_loss = -x_class + log_sigma_exp_xprint(f'交叉熵手动计算loss{sample_index}{sample_loss}')return sample_lossfor i in range(2):manual_cal(i, target, output)# 如果nn.CrossEntropyLoss(reduction='mean')模式,刚好是手动计算的每个样本的loss取平均,最后输出的是一个值
# 如果nn.CrossEntropyLoss(reduction='none')模式,手动计算的loss0和loss1都会被列出来

在这里插入图片描述

(class torch.nn.CrossEntropyLoss(weight=None, size_average=None, ignore_index=-100, reduce=None, reduction=‘elementwise_mean’)
功能: 将输入经过softmax激活函数之后,再计算其与target的交叉熵损失。即该方法将nn.LogSoftmax()和 nn.NLLLoss()进行了结合。严格意义上的交叉熵损失函数应该是nn.NLLLoss()。
在这里插入图片描述
补充:交叉熵损失(cross-entropy Loss) 又称为对数似然损失(Log-likelihood Loss)、对数损失;二分类时还可称之为逻辑斯谛回归损失(Logistic Loss)。交叉熵损失函数表达式为 L = - sigama(y_i * log(x_i))。pytroch这里不是严格意义上的交叉熵损失函数(下面会详细解释,pytorch中交叉熵不够严格主要是因为只能接受one hot),而是先将input经过softmax激活函数,将向量“归一化”成概率形式,然后再与target计算严格意义上交叉熵损失。 在多分类任务中,经常采用softmax激活函数+交叉熵损失函数,因为交叉熵描述了两个概率分布的差异,然而神经网络输出的是向量,并不是概率分布的形式。所以需要softmax激活函数将一个向量进行“归一化”成概率分布的形式,再采用交叉熵损失函数计算loss。 再回顾PyTorch的CrossEntropyLoss(),官方文档中提到时将nn.LogSoftmax()和 nn.NLLLoss()进行了结合,nn.LogSoftmax() 相当于激活函数 , nn.NLLLoss()是损失函数;

来感受一下交叉熵取值的妙处:当 q i q_i qi很接近1时, − l o g q i -logq_i logqi很接近0,如果此时 p i p_i pi是1,这时候整体loss会很小;当 q i q_i qi很接近0时, − l o g q i -logq_i logqi很大, p i p_i pi是1,这时候整体loss会很大。所以 p i p_i pi就是筛选的功能,在Pytorch中CrossEntropyLoss等于LogSoftmax和NLLLoss的结合:LogSoftmax是上面公式里的 l o g ( e x p ( x [ c l a s s ] ) ∑ j e x p ( x [ j ] ) ) log(\frac{exp(x[class])}{\sum_jexp(x[j])}) log(jexp(x[j])exp(x[class])),实现了整个 l o g q i logq_i logqi的效果;NLLLoss就是给前面加了一个负号。所以在torch中的CrossEntropy = NLLLoss(LogSoftmax)
pytorch中交叉熵不够严格主要是因为只能接受one hot,也就是说torch中的target只能明确指明是哪个target,而不是上面公式 p i p_i pi是(0,1)之间,所以在Pytorch中还保留了KLDivLoss这个loss来接受广泛的取值:

import torch.nn.functional as F
import torch
import torch.nn as nn
# nn.CrossEntropyLoss() 和  KLDivLoss 关系y_pred = torch.tensor([[10.0, 0.0, -10.0], [8.0, 8.0, 8.0]])
y_true = torch.tensor([0, 2])
ce = nn.CrossEntropyLoss(reduction="none")(y_pred, y_true)
print(ce)
'''
输出shape是2,tensor([4.5418e-05, 1.0986e+00])
'''# NLLLoss要求target只能是第几类下标,例如[0,2]表示[label0,label2],转成onehot就是[[1,0,0],[0,0,1]]
nll_log_softmax = nn.NLLLoss(reduction="none")(F.log_softmax(y_pred, dim=-1), y_true)
print(nll_log_softmax)
'''
输出shape是2,tensor([4.5418e-05, 1.0986e+00])
'''one_hot = F.one_hot(y_true) #将第几类的下标转换成onehot形式,例如输入[0,2]表示[label0,label2],输出onehot就是[[1,0,0],[0,0,1]]
'''
# KLDivLoss要求target为float形式编码,one_hot是longtensor,所以要one_hot.float();如果是普通的logics,要过一下softmax# KLDivLoss也要求Logits经过LogSoftmax激活。LogSoftmax会把(-inf,inf)的Logits映射到(0,1)再映射到(-inf,0):当用NLLLoss时,刚好多个负号loss变成(0,inf);当用KLDivLoss时,刚好多个熵。回顾klLoss的公式 p_i*log(p_i/q_i),其中p_i是(0,1)范围内的targets
q_i是将logits映射到(0,1)范围内的结果,所以p_i和q_i都是(0,1)之间
KLDivLoss这个函数的特点就是把log(q_i)这一步扔给输入自己算,这个函数管的只是p_i*log(p_i)-p_i*inputNLLLoss这个函数的特点就是把p_i*log(p_i)也没了,只有-p_i*input,所以和LogSoftmax组合起来是CE
'''kl = nn.KLDivLoss(reduction="none")(F.log_softmax(y_pred, dim=-1), one_hot.float())
print(kl) #输出shape是2*3
'''
tensor([[4.5418e-05, 0.0000e+00, 0.0000e+00],[0.0000e+00, 0.0000e+00, 1.0986e+00]])
'''a = F.softmax(torch.randn(2,3))
print(nn.KLDivLoss(reduction="none")(torch.log(a), a))
'''
输出是
tensor([[0., 0., 0.],[0., 0., 0.]])回顾klLoss的公式 p_i*log(p_i/q_i),其中p_i是(0,1)范围内的targets
q_i是将logits映射到(0,1)范围内的结果,所以p_i和q_i都是(0,1)之间
KLDivLoss这个函数的特点就是把log(q_i)这一步扔给输入自己算,这个函数管的只是p_i*log(p_i)-p_i*inputNLLLoss这个函数的特点就是把p_i*log(p_i)也没了,只有-p_i*input,所以和LogSoftmax组合起来是CE
'''

为什么既有 KL 散度又有交叉熵?在信息论中,熵的意义是对 𝑃
事件的随机变量编码所需的最小字节数
,KL 散度的意义是**“额外所需的编码长度”如果我们使用 𝑄的编码来表示 𝑃**,交叉熵指的是当你使用 𝑄作为密码来表示 𝑃 是所需要的 “平均的编码长度”。但是在机器学习评价两个分布之间的差异时,由于分布 𝑃 会是给定的,所以此时 KL 散度和交叉熵的作用其实是一样的,而且因为交叉熵少算一项,更加简单,所以选择交叉熵会更好。

Label Smoothing

Label Smoothing是一种防止网络过拟合的手段,在Pytorch的CrossEntropy中已经自带了这个参数,下图截自Hinton的论文When Does Label Smoothing Help? 从公式来看只把我们上面说的label/target做了一个衰减,更多细节可以参考https://blog.csdn.net/taoqick/article/details/121717218 :
在这里插入图片描述

联合熵

H ( P , Q ) = − ∑ i ∈ [ 0 , n − 1 ] P ( p i , q i ) l o g P ( p i , q i ) H(P,Q)=-\sum _{i \in[0,n-1]}P(p_i,q_i)logP(p_i,q_i) H(P,Q)=i[0,n1]P(pi,qi)logP(pi,qi)

条件熵

注意下面 P ( q i ∣ p i ) P(q_i|p_i) P(qipi)表示 p i p_i pi q i q_i qi对应变量的条件概率, P ( p i , q i ) P(p_i,q_i) P(pi,qi)表示 p i p_i pi q i q_i qi对应变量的联合概率,写成这样只是为了简化但不够严谨。
H ( Q ∣ P ) = ∑ i ∈ [ 0 , n − 1 ] p i H ( Q ∣ P = p i ) H ( Q ∣ P ) = − ∑ i ∈ [ 0 , n − 1 ] p i ∗ P ( q i ∣ p i ) l o g P ( q i ∣ p i ) H ( Q ∣ P ) = − ∑ i ∈ [ 0 , n − 1 ] P ( p i , q i ) l o g P ( q i ∣ p i ) H(Q|P)=\sum _{i \in[0,n-1]}p_iH(Q|P=p_i) \\ H(Q|P)=-\sum _{i \in[0,n-1]}p_i*P(q_i|p_i)logP(q_i|p_i) \\ H(Q|P)=-\sum _{i \in[0,n-1]}P(p_i,q_i)logP(q_i|p_i) H(QP)=i[0,n1]piH(QP=pi)H(QP)=i[0,n1]piP(qipi)logP(qipi)H(QP)=i[0,n1]P(pi,qi)logP(qipi)
上面就解释了为啥log里面是条件,外面是联合,更进一步地把里面也展开
H ( Q ∣ P ) = − ∑ i ∈ [ 0 , n − 1 ] P ( p i , q i ) l o g P ( q i ∣ p i ) H ( Q ∣ P ) = − H ( P , Q ) − ∑ i ∈ [ 0 , n − 1 ] P ( p i , q i ) l o g P ( p i ) H ( Q ∣ P ) = − H ( P , Q ) + H ( P ) H(Q|P)=-\sum _{i \in[0,n-1]}P(p_i,q_i)logP(q_i|p_i) \\ H(Q|P)=-H(P,Q)-\sum _{i \in[0,n-1]}P(p_i,q_i)logP(p_i) \\ H(Q|P)=-H(P,Q)+H(P) H(QP)=i[0,n1]P(pi,qi)logP(qipi)H(QP)=H(P,Q)i[0,n1]P(pi,qi)logP(pi)H(QP)=H(P,Q)+H(P)


至于熵为什么是这个定义请参考 为什么信息熵要定义成 − Σ p ∗ l o g ( p ) -Σp*log(p) Σplog(p)?(https://blog.csdn.net/taoqick/article/details/72852255)。简单来说就是-log§就是信息量,单位用比特表示,例如中国队夺世界杯的信息量远比法国队夺世界杯信息量大。把一个系统里所有的-log§再乘以p就是熵,表示所有信息量加权平均,或者说熵就是信息量的数学期望

还有3个重要结论:

  1. 最小化交叉熵和极大似然本质上是一样的,更多推导参考:最小化交叉熵损失与极大似然 - 知乎(https://zhuanlan.zhihu.com/p/51099880)

  2. 为什么分类问题用相对熵不用MSE,原因之一是求解时相对熵的梯度下降更快一些,这样可以实现错误越大,下降的越快的效果,更多推导请参考: 分类问题中为什么用交叉熵而不用MSE KL散度和交叉熵的关系_taoqick的专栏-CSDN博客_mse和交叉熵 (https://blog.csdn.net/taoqick/article/details/102621605)

  3. 李航老师书里说的最大熵模型是条件熵最大化,想法就是某些知识已经先验知道了,剩下的随机变量尽量等概率随机,这样条件熵最大。学习概率模型时,在满足约束(特征函数)的所有的可能的概率分布中,熵最大的模型就是最大的模型。最大熵模型是判别式模型。

更多推导请参考李航老师的书和数学之美。



本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/66249.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

企业架构LNMP学习笔记10

1、Nginx版本,在实际的业务场景中,需要使用软件新版本的功能、特性。就需要对原有软件进行升级或重装系统。 Nginx的版本需要升级迭代。那么如何进行升级呢?线上服务器如何升级,我们选择稳定版本。 从nginx的1.14版本升级到ngin…

Linux系统中驱动入门设备树DTS(经典)

设备树(DTS:device tree source),字面意思就是一块电路板上设备如上图中CPU、DDR、I2C、GPIO、SPI等,按照树形结构描绘成的一棵树。按照策略和功能分离的思路,就是驱动代码(功能)和设备树DTS配置…

IIR滤波器

IIR滤波器原理 IIR的特点是:非线性相位、消耗资源少。 IIR滤波器的系统函数与差分方程如下所示: 由差分方程可知IIR滤波器存在反馈,因此在FPGA设计时要考虑到有限字长效应带来的影响。差分方程中包括两个部分:输入信号x(n)的M节…

Git中smart Checkout与force checkout

Git中smart Checkout与force checkout 使用git进行代码版本管理,当我们切换分支有时会遇到这样的问题: 这是因为在当前分支修改了代码,但是没有commit,所以在切换到其他分支的时候会弹出这个窗口, 提示你选force checkout或者smart checko…

Redis缓存和持久化

目录 Redis缓存 什么是缓存 缓存更新策略​编辑 业务场景 缓存穿透 常见的解决方案 缓存雪崩 解决方案 缓存击穿 解决方案 Redis持久化 RDB持久化 执行时机 RDB方式bgsave的基本流程 AOF持久化 RDB和AOF的对比​编辑 Redis主从 数据同步原理 总结 Redis缓存 …

2、Nginx 安装

文章目录 2、Nginx 安装2.1 官网下载2.2 安装 nginx2.2.1 第一步2.2.2 第二步2.2.3 第三步,安装 nginx2.2.4 第四步,修改防火漆规则 【尚硅谷】尚硅谷Nginx教程由浅入深 志不强者智不达;言不信者行不果。 2、Nginx 安装 2.1 官网下载 nginx…

iOS - 资源按需加载 - ODR

一、瘦身技术大图 二、On-Demand Resources 简介 将其保存管理在苹果的服务器,按需使用资源、优化包体积,实现更小的应用程序。ODR 的好处: 应用体积更小,下载更快,提升初次启动速度资源会在后台下载操作系统将会在磁…

openGauss学习笔记-59 openGauss 数据库管理-相关概念介绍

文章目录 openGauss学习笔记-59 openGauss 数据库管理-相关概念介绍59.1 数据库59.2 表空间59.3 模式59.4 用户和角色59.5 事务管理 openGauss学习笔记-59 openGauss 数据库管理-相关概念介绍 59.1 数据库 数据库用于管理各类数据对象,与其他数据库隔离。创建数据…

【数据结构】树和二叉树的概念及结构(一)

目录 一,树的概念及结构 1,树的定义 2,树结点的分类及关系 3,树的表示 二,二叉树的概念及结构 1,二叉树的定义 2,特殊的二叉树 3,二叉树的性质 4,二叉树的存储结构 1&…

无涯教程-Android Intent Standard Extra Data函数

下表列出了各种重要的Android Intent Standard Extra Data。您可以查看Android官方文档以获取额外数据的完整列表- Sr.NoExtra Data & Description1 EXTRA_ALARM_COUNT 用作AlarmManager intents(意图)中的int Extra字段,以告诉正在调用的应用程序intents(意图)释放了多少…

【数据结构】二叉树篇|超清晰图解和详解:二叉树的序列化和反序列化

博主简介:努力学习的22级计算机科学与技术本科生一枚🌸博主主页: 是瑶瑶子啦每日一言🌼: 你不能要求一片海洋,没有风暴,那不是海洋,是泥塘——毕淑敏 目录 一、核心二、题目2.1:前序遍历2.2&…

2.4 关系数据库

思维导图: 前言: 这段话描述了“关系数据库”及其背后的理论基础。首先,我们来拆分这段话并逐步解释每部分。 关系数据库是采用关系模型作为数据组织方式的数据库。 这句话的关键是“关系模型”。关系模型是一种表示和操作数据库的理论模型…

操作系统清华同步笔记:定义概述+计算机内存和硬盘布局+启动流程顺序+中断、异常和系统调用

定义概述 从用户角度来看,操作系统是一个控制软件,用以管理应用程序,为应用程序提供服务,杀死应用程序等。从内部文件角度来看,操作系统是一个资源管理器,用以管理外设,分配资源。层次结构&…

命令行编译VS工程

先输入以下命令,因为命令出错了,就会弹出帮助,如下: "C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE\devenv.exe" /help 反正就是Microsoft Visual Studio 的安装路径。 帮助界面如下&#xff1a…

core dump管理在linux中的前世今生

目录 一、什么是core dump? 二、coredump是怎么来的? 三、怎么限制coredump文件的产生? ulimit 半永久限制 永久限制 四、从源码分析如何对coredump文件的名字和路径管理 命名 管理 一些问题的答案 1、为什么新的ubuntu不能产生c…

java设计模式---策略模式

策略模式的定义 策略设计模式是一种行为设计模式。当在处理一个业务时,有多种处理方式,并且需要再运行时决定使哪一种具体实现时,就会使用策略模式。 策略模式的类图: 策略模式的实现 在支付业务中,有三种付款方式&…

RabbitMQ工作模式-工作队列

官网关于工作模式的解释地址:https://www.rabbitmq.com/getstarted.html Work Queue(工作队列) 生产者发消息,启动多个消费者来消费消息,每个消费者仅消费部分消息,可达到负载均衡的效果。 创建生产者 i…

使用docker、docker-compose部署微服务

使用docker、docker-compose部署微服务 一、使用docker部署1、准备2、上传jar包3、编写dockerfile文件3、构建镜像和容器 二、使用docker-compose部署1、准备服务的jar包和dockerfile文件2、编写docker-compose.yml文件3、docker-compose常用命令(1)、前…

【Linux】以太网协议以及MTU

以太网协议 数据链路层的功能以太网的数据格式MTUMTU对IP协议的影响MTU对UDP协议的影响MTU对TCP协议的影响 数据链路层的功能 数据链路层的主要功能是:控制链路。包括数据链路的建立、链路的维护和释放。MAC寻址也是它的功能,寻址是指计算机网卡的MAC地…

无涯教程-JavaScript - CUBERANKEDMEMBER函数

描述 CUBERANKEDMEMBER函数返回集合中的第n个或排序的成员。 使用此功能可返回一组中的一个或多个元素,如销售业绩最好的人或前十名的学生。 语法 CUBERANKEDMEMBER (connection, set_expression, rank, [caption])争论 Argument描述Required/OptionalconnectionThe name …