交叉熵损失概念

交叉熵是信息论中的一个概念,要想了解交叉熵的本质,需要先从最基本的概念讲起。

1. 信息量

首先是信息量。假设我们听到了两件事,分别如下:

事件A:巴西队进入了2018世界杯决赛圈。

事件B:中国队进入了2018世界杯决赛圈。

仅凭直觉来说,显而易见事件B的信息量比事件A的信息量要大。究其原因,是因为事件A发生的概率很大,事件B发生的概率很小。所以当越不可能的事件发生了,我们获取到的信息量就越大。越可能发生的事件发生了,我们获取到的信息量就越小。那么信息量大小应该和事件发生的概率是负相关


假设$X$是一个离散型随机变量,其取值集合为$\chi$,概率分布函数$p(x)=Pr(X=x),x \in \chi$,则定义事件$X=x_0$的信息量为:

$I(x_0) = -log(p(x_0))$

由于是概率,所以$p(x_0)$的取值范围是$|0,1|$,绘制为图形如下:

 

2. 熵

对于某个事件,有n种可能性,每一种可能性都有一个概率$p(x_i)$

这样就可以计算出某一种可能性的信息量。举一个例子,假设你拿出了你的电脑,按下开关,会有三种可能性,下表列出了每一种可能的概率及其对应的信息量

 注:文中的对数均为自然对数

 

3. 相对熵(KL散度)

相对熵又称KL散度,如果我们对于同一个随机变量 x 有两个单独的概率分布 P(x) 和 Q(x),我们可以使用 KL 散度(Kullback-Leibler (KL) divergence)来衡量这两个分布的差异

在机器学习中,P往往用来表示样本的真实分布,比如[1,0,0]表示当前样本属于第一类。Q用来表示模型所预测的分布,比如[0.7,0.2,0.1]

4. 交叉熵

对KL散度的公式变形,可以得到:

其中p代表label或者叫ground truth, q代表预测值

在机器学习中,我们需要评估label和predicts之间的差距,使用KL散度刚刚好,即

D{KL}(p||q)

由于KL散度中的前一部分恰巧就是p的熵,p代表label或者叫ground truth,故−H(p(x))不变,故在优化过程中,只需要关注交叉熵就可以了,所以一般在机器学习中直接用用交叉熵做loss,评估模型。

交叉熵公式:

$H(p,q)=-\sum^{n}_{i=1}p(x_i)log(q(x_i))$

CrossEntropyLoss

pytorch在计算二分类或者互斥的多分类问题时,使用的是softmax交叉熵损失计算。

具体计算过程:

  1. 对输入进行softmax

     假设有一个数组a,a_i表示a中的第i个元素。计算的是元素的指数越所有元素指数的比值。

    假设输入a=[0.5,1.5,0.1],那么经过softmax层后就会得到[0.227863, 0.61939586, 0.15274114],这三个数字表示这个样本属于第1,2,3类的概率分别是0.227863, 0.61939586, 0.15274114。

import numpy as np
arr = np.array([[0.5,1.5,0.1]])
def softmax(x):
    exp = np.exp(x)
    sum_exp = np.sum(np.exp(x), axis=1, keepdims=True)
    softmax = exp / sum_exp
    return softmax
print(softmax(arr))

输出:[[0.227863 0.61939586 0.15274114]]

通过pytorch的softmax方法可以更直接获得结果

import torch
tensor = torch.tensor([[0.5,1.5,0.1]])
print(tensor.softmax(1).numpy())

from torch import nn
m = nn.Softmax(dim=1)
print(m(tensor).numpy())

tensor = torch.tensor([[0.5,1.5,0.1]])
print(tensor.log_softmax(dim=1).numpy())
# 或
m = nn.LogSoftmax(dim=1)
print(m(tensor).numpy())

输出:[[-1.4790106 -0.47901064 -1.8790107 ]]

由于损失函数要求得到是一个值,通常计算得到的,是对数平均损失。pytorch中的NLLLoss(negative log likelihood loss)完成的就是对数平均损失的计算。

tensor = torch.tensor([[0.5,1.5,0.1]])
m = tensor.log_softmax(dim=1)
loss = torch.nn.NLLLoss()
target = torch.empty(1, dtype=torch.long).random_(0, 3)
print(loss(m,target))

输出:1.8790107

当然,最后回到我们文章开头提到的交叉熵损失 —— cross_entropy。

Pytorch中的cross_entropy会自动调用上面介绍的log_softmaxnll_loss来计算交叉熵,其计算公式如下:

loss(x,class) = -log(\frac{exp(x[class])}{\sum_j exp(x[j])})

tensor = torch.tensor([[0.5,1.5,0.1]])
loss = nn.CrossEntropyLoss()
target = torch.randint(3,(1,), dtype=torch.int64)
print(loss(tensor, target).numpy())

binary_cross_entropy

binary_cross_entropy 是二分类的交叉熵,实际是多分类 CrossEntropyLoss 的一种特殊情况,当多分类中,类别只有两类时,即 0 或者 1,即为二分类,二分类也是一个逻辑回归问题,也可以套用逻辑回归的损失函数。

target = torch.tensor([[1., 0.], [0., 1.] ])
pred = torch.tensor([[0.8,0.2], [0.4,0.6]])
loss = nn.functional.binary_cross_entropy(pred, target, reduction="mean")
print(loss.numpy())

实际在计算中如果使用binary_cross_entropy_with_logits 就不需要先做softmax处理。

  • 5
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Sonhhxg_柒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值