西安市干部教育网站建设,python做互金网站,seo优化内页排名,广西seo网站粗略版快速总结 条件熵 H ( Q ∣ P ) 联合熵 H ( P , Q ) − H ( P ) 条件熵H(Q∣P)联合熵H(P,Q)−H(P) 条件熵H(Q∣P)联合熵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) 信息…粗略版快速总结 条件熵 H ( Q ∣ P ) 联合熵 H ( P , Q ) − H ( P ) 条件熵H(Q∣P)联合熵H(P,Q)−H(P) 条件熵H(Q∣P)联合熵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(P∣Q)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_00 p00 p 1 0 p_10 p10 p 2 1 p_21 p21。写成表达式可以是 p i p_i pin3 那么经过神经网络运算出来的Logits可能是在(-inf,inf)之间那么一般会通过softmax归一化到(0,1)之间这个归一化到(0,1)之间的数我们可以用 q i q_i qi来表示当然对于上面有3类的例子来说n3 好了既然明确了 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,n−1]∑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,n−1]∑pilogqiKL(P,Q)H(P)CE(P,Q) 来看一下Pytorch里的交叉熵是怎么实现的手动验证下
import torch
from torch import nn
import mathloss_f nn.CrossEntropyLoss(reductionmean)
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(freductionnone所以可以看到每一个样本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(reductionmean)模式刚好是手动计算的每个样本的loss取平均最后输出的是一个值
# 如果nn.CrossEntropyLoss(reductionnone)模式手动计算的loss0和loss1都会被列出来(class torch.nn.CrossEntropyLoss(weightNone, size_averageNone, ignore_index-100, reduceNone, 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(reductionnone)(y_pred, y_true)
print(ce)输出shape是2,tensor([4.5418e-05, 1.0986e00])
# NLLLoss要求target只能是第几类下标例如[0,2]表示[label0,label2]转成onehot就是[[1,0,0],[0,0,1]]
nll_log_softmax nn.NLLLoss(reductionnone)(F.log_softmax(y_pred, dim-1), y_true)
print(nll_log_softmax)输出shape是2,tensor([4.5418e-05, 1.0986e00])
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(reductionnone)(F.log_softmax(y_pred, dim-1), one_hot.float())
print(kl) #输出shape是2*3tensor([[4.5418e-05, 0.0000e00, 0.0000e00],[0.0000e00, 0.0000e00, 1.0986e00]])
a F.softmax(torch.randn(2,3))
print(nn.KLDivLoss(reductionnone)(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,n−1]∑P(pi,qi)logP(pi,qi)
条件熵
注意下面 P ( q i ∣ p i ) P(q_i|p_i) P(qi∣pi)表示 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|Pp_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(Q∣P)i∈[0,n−1]∑piH(Q∣Ppi)H(Q∣P)−i∈[0,n−1]∑pi∗P(qi∣pi)logP(qi∣pi)H(Q∣P)−i∈[0,n−1]∑P(pi,qi)logP(qi∣pi) 上面就解释了为啥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(Q∣P)−i∈[0,n−1]∑P(pi,qi)logP(qi∣pi)H(Q∣P)−H(P,Q)−i∈[0,n−1]∑P(pi,qi)logP(pi)H(Q∣P)−H(P,Q)H(P)
至于熵为什么是这个定义请参考 为什么信息熵要定义成 − Σ p ∗ l o g ( p ) -Σp*log(p) −Σp∗log(p)(https://blog.csdn.net/taoqick/article/details/72852255)。简单来说就是-log§就是信息量单位用比特表示例如中国队夺世界杯的信息量远比法国队夺世界杯信息量大。把一个系统里所有的-log§再乘以p就是熵表示所有信息量加权平均或者说熵就是信息量的数学期望
还有3个重要结论 最小化交叉熵和极大似然本质上是一样的更多推导参考最小化交叉熵损失与极大似然 - 知乎https://zhuanlan.zhihu.com/p/51099880 为什么分类问题用相对熵不用MSE原因之一是求解时相对熵的梯度下降更快一些这样可以实现错误越大下降的越快的效果更多推导请参考 分类问题中为什么用交叉熵而不用MSE KL散度和交叉熵的关系_taoqick的专栏-CSDN博客_mse和交叉熵 (https://blog.csdn.net/taoqick/article/details/102621605) 李航老师书里说的最大熵模型是条件熵最大化想法就是某些知识已经先验知道了剩下的随机变量尽量等概率随机这样条件熵最大。学习概率模型时在满足约束(特征函数)的所有的可能的概率分布中熵最大的模型就是最大的模型。最大熵模型是判别式模型。
更多推导请参考李航老师的书和数学之美。