返回顶部

请叫我杨先生

导航

Pytorch 3.4.2 softmax回归 交叉熵损失函数

交叉熵损失函数

关于信息熵我们已经在上一篇文章中有详细的讲解了"Click here to visit", 对于二分类的问题,信息熵计算公式为:

\[H(X) = -\Sigma_{i = 1}^{n} p(x_i)\log p(x_i) = -(p(x)\log p(x) +(1-p(x))\log(1- p(x))) \]

相对熵(KL散度)

相对熵(relative entropy)又被称为 Kullback-Leibler 散度( Kullback-leibler divergence),是两个概率分布间差异的一种度量, 在信息论中,相对熵等于两个概率分布的信息熵的差值。相对熵的计算公式为:设 \(P(x),Q(x)\)\(X\)上的两个概率分布, 在离散情况下相对熵的定义分别为:

\[KL(p||q) = \Sigma [P(x)\log P(x) - P(x)\log Q(x)]= \Sigma P(x_i) \log \frac{P(x)}{Q(x)} \]

\[KL(p||q) = \int P(x)\log \frac{P(x)}{Q(x)}\mathrm{d}x \]

其中\(P(x)\) 是我们事件真实的概率,\(Q(x)\)使我们预测的概率。比如三类分类问题的标签为\((1,0,0)\) ,预测的标签为\((0.7,0.1,0.2)\)

因此该公式的字面上含义就是真实事件的信息熵

\[Entropy(p_1,p_2,p_3) = -(p_1*\log_2 p_1 + p_2 * \log_2 p_2 +p_3 *\log_2 p_3 = \Sigma_{i=1}^3 P(x_i) log P(x_i) \]

与理论拟合的事件的香农信息量\(Entropy(q_1,q_2,q_3)\)与真实事件的概率的乘积的差的累加。

\[Relative Entropy = \Sigma_{i=1}^{3}P(x_i)[\log P(x_i) - \log Q(x_i)] \]

当p(x)和q(x)相等时相对熵为0,其它情况下大于0。证明如下:

要证明:\(KL(p||q) = \Sigma_{i=1}^{N} P(x_i) \log \frac{P(x)}{Q(x)} ≥ 0\)

即证明:\(\Sigma_{i=1}^{N} p(x_i)\log \frac{Q(x_i)}{P(x_i)} ≤ 0\)

又因为: \(ln(x) ≤ x -1\)(证明省略,可自行导数验证)当且仅当\(x=1\)的时候等号成立

故有: \(\Sigma_{i=1}^{N} P(x_i) \log \frac{Q(x_i)}{P(x_i)} ≤\Sigma_{i=1}^{N}P(x_i) (\frac{Q(x_i)}{P(x_i)} - 1 )\)

当且仅当 \(P(x_i) = Q(x_i)\) 的时候 , \(KL(p||q) = 0\)

交叉熵

除此之外 相对熵还可以写成 :\(Relative Entropy(p,q) = - Entropy(p_1,p_2,p_3) + Entropy(q_1,q_2,q_3)\) 的形式

\[\Sigma_{i = 1}^{n} p(x_i)\log q(x_i) +\Sigma_{i = 1}^{n} p(x_i)\log q(x_i) = -H(P(x))-\Sigma_{i = 1}^{n} p(x_i)\log q(x_i) \]

而等式中的前面的一项:\(-H(P(x))\)就是我们的真实熵 , \(-\Sigma_{i = 1}^{n} p(x_i)\log q(x_i)\) 就是我们要的交叉熵

我们一般使用 \(H(P,Q) = -\Sigma_{i = 1}^{n} p(x_i)\log q(x_i)\) 表示

在机器学习中,使用KL散度就可以评价真实标签与预测标签间的差异,但由于KL散度的第一项是个定值(我们使用one-hot的真实标签进行预测,一般来说都是0),故在优化过程中只关注交叉熵就可以了。一般大多数机器学习算法会选择交叉熵作为损失函数。

Pytorch 实现

在Pytorch中是使用torch.nn.CrossEntropyLoss(weight=None, size_average=None, ignore_index=-100, reduce=None, reduction='mean')实现的。
假设 我们使用mini_batch gradient decent ,进行求梯度 ,batch_size= 4 ,待分类标签有三个,隐藏层的输出为:

features = torch.tensor([[ 1.1330, -0.6136, -1.3633],
        [ 0.4169,  1.2200, -0.2169],
        [-0.7368,  0.6024, -1.2759],
        [ 0.7969, -1.2343,  0.5294]],requires_grad=True)

经过softmax激活函数之后得到预测值:

output = torch.nn.Softmax(dim=1)(features)
output:
tensor([[0.7957, 0.1387, 0.0656],
        [0.2657, 0.5933, 0.1410],
        [0.1852, 0.7068, 0.1080],
        [0.5273, 0.0692, 0.4035]], grad_fn=<SoftmaxBackward0>)
import torch
import torch.nn as nn

features = torch.tensor([[ 1.1330, -0.6136, -1.3633],
        [ 0.4169,  1.2200, -0.2169],
        [-0.7368,  0.6024, -1.2759],
        [ 0.7969, -1.2343,  0.5294]],requires_grad=True)  # 我们定义一个4*3的矩阵,四个样本每个样本三个类别 
target = torch.tensor([1,0,2,1])

loss = nn.CrossEntropyLoss()
output = loss(features, target)
# output.backward()
output

输出:

tensor(2.0492, grad_fn=<NllLossBackward0>)

假设我们输入的 \(labels = [1,0,2,1]\) ,\([1,0,2,1]\)指的是第[2个类别,第1个类别,第3个类别,第2个类别](因为Corss Entropy Loss Function 不能够传入 one-hot 形式的数据) 则输出的应该是 (2.409是根据下面的数据计算得到)

\[Loss = -\frac{1}{4}[\log 0.1387 + \log 0.2657 + \log 0.1080 + \log 0.0692] = 8.1969/4 = 2.409 \]

softmax函数的输出结果每一行相加为1。 假设这一个mini batch的标签为 [1,0,2,1]

除了 torch.nn.CrossEntropyLoss() 这个函数之外,Pytorch还有另外一个计算交叉熵的函数。 torch.nn.BCELoss()
与之前不同的是该函数主要计算的是 (0-1)分布的交叉熵 因此输出层只有一个神经元(只能输出0或者1)。其公式为:

\[loss = -\frac{1}{n}\Sigma_{i=1}^{n}[y_i\log y_i + (1-y_i)\log (1-y_i)] \]

torch.nn.BCELoss(weight=None, size_average=None, reduce=None, reduction='mean')
import torch  
import torch.nn as nn  

features = torch.tensor([-0.6168, -0.2976, -0.4502],requires_grad=True)
target = torch.tensor([0.,0.,1.],requires_grad=True) 

m = nn.Sigmoid() # 我们分类的是互斥的,要使用Sigmoid函数 
loss = nn.BCELoss()  
output = loss(m(features),target)

输出:features,output

(tensor([-0.6168, -0.2976, -0.4502], requires_grad=True),
 tensor(0.6434, grad_fn=<BinaryCrossEntropyBackward0>))

我们来分析一下计算的过程:

m(features) # tensor([0.3505, 0.4261, 0.3893], grad_fn=<SigmoidBackward0>) 

根据二项分布的交叉熵 :

\[loss = -\frac{1}{3}\Sigma_{i=1}^{3}[y_i\log y_i + (1-y_i)\log (1-y_i)] = -\log_e (1-0.3505) - \log_e(1-0.4261) - \log_e 0.3505 = 0.6434 \]

#得证
参考文献/文章:
百度百科-相对熵
简书-学有余力的小心同学
【导数】有趣的lnx≤x-1

posted on 2021-12-24 23:04  YangShusen'  阅读(474)  评论(0)    收藏  举报