(1) 二分类
在二分的情况下,模型最后需要预测的结果只有两种情况,对于每个类别我们的预测得到的概率为 p 和1-p 。此时表达式为:
其中:
(2) 多分类
多分类的情况实际上就是对二分类的扩展:
其中:
CrossEntropyLoss()的实现可以参考如下代码
import torch
import torch.nn as nn
loss = nn.CrossEntropyLoss()
input = torch.tensor([[-1., 1],[-1, 1],[1, -1]]) # raw scores correspond to the correct class
# input = torch.tensor([[-3., 3],[-3, 3],[3, -3]]) # raw scores correspond to the correct class with higher confidence
# input = torch.tensor([[1., -1],[1, -1],[-1, 1]]) # raw scores correspond to the incorrect class
# input = torch.tensor([[3., -3],[3, -3],[-3, 3]]) # raw scores correspond to the incorrect class with incorrectly placed confidence
target = torch.tensor([1, 1, 0])
output = loss(input, target)
print(output)
output:tensor(0.1269)
可以注意到target的元素是scalar的列表,它的含义是指定table对应class的index(可以回忆一下one-hot,label class处的值为1而其余为0),而不是y的值。
注意到input是未经sigmoid处理(多分类则是通过softmax处理,sigmoid可以看做是特殊的softmax),这是因为nn.CrossEntropyLoss会对input进行softmax处理。
计算过程如下:
input:
[-1, 1]
[-1, 1]
[1, -1]
target:
[1, 1, 0] 即,选择index=1, 1, 0的input进行loss的计算;
对应的 pic 的计算公式为: e p i c / ∑ i = 0 N e p i c e^{p_{ic}}/{\sum_{i=0}^{N}e^{p_{ic}}} epic/∑i=0Nepic,即 e x e x + e − x \frac{e^x}{e^x+e^{-x}} ex+e−xex, e x e x + e − x \frac{e^x}{e^x+e^{-x}} ex+e−xex, e x e x + e − x \frac{e^x}{e^x+e^{-x}} ex+e−xex(注意第三个还是 e x e x + e − x \frac{e^x}{e^x+e^{-x}} ex+e−xex)
因此, l o s s = 1 / 3 ∗ 3 ∗ ( − l n e x e x + e − x ) = 0.1269 loss = 1/3 *3 * (-ln\frac{e^x}{e^x+e^{-x}}) =0.1269 loss=1/3∗3∗(−lnex+e−xex)=0.1269
交叉熵的计算公式为:
c r o s s _ e n t r o p y = − ∑ k = 1 N ( p k ∗ log q k ) cross\_entropy=-\sum_{k=1}^{N}\left(p_{k} * \log q_{k}\right) cross_entropy=−∑k=1N(pk∗logqk)
其中p表示真实值,在这个公式中是one-hot形式;q是预测值,在这里假设已经是经过softmax后的结果了。
如果此处有表述不清,可以参考以下文段,转自https://www.cnblogs.com/marsggbo/p/10401215.html
仔细观察可以知道,因为p的元素不是0就是1,而且又是乘法,所以很自然地我们如果知道1所对应的index,那么就不用做其他无意义的运算了。所以在pytorch代码中target不是以one-hot形式表示的,而是直接用scalar表示。所以交叉熵的公式(m表示真实类别)可变形为:
c r o s s _ e n t r o p y = − ∑ k = 1 N ( p k ∗ log q k ) = − l o g q m cross\_entropy=-\sum_{k=1}^{N}\left(p_{k} * \log q_{k}\right)=-log \, q_m cross_entropy=−∑k=1N(pk∗logqk)=−logqm
即同于log_softmax和nll_loss两个步骤。
所以Pytorch中的F.cross_entropy会自动调用上面介绍的log_softmax和nll_loss来计算交叉熵,其计算方式如下:
loss ( x , class ) = − log ( exp ( x [ class ] ) ∑ j exp ( x [ j ] ) ) \operatorname{loss}(x, \text {class})=-\log \left(\frac{\exp (x[\operatorname{class}])}{\sum_{j} \exp (x[j])}\right) loss(x,class)=−log(∑jexp(x[j])exp(x[class]))