import torch
import torch.nn.functional as F
x = torch.tensor([[0.5,0.25,0.25,0.25]])
F.cross_entropy(x,torch.tensor([0])) #结果是:tensor(1.2049)
我们先看一下F.cross_entropy的解释:
“This criterion combines log_softmax
and nll_loss
in a single
function.”
也就是说这里的cross_entropy将log_softmax函数和nll_loss函数结合起来了,那这两个函数又是什么呢?
- log_softmax 比较好理解,就是先log 后softmax
- nll_loss 是什么呢,看下面的例子:
y = torch.tensor([[-1.,-2.],[-4.,-3.]])
target = torch.tensor([1,0])
F.nll_loss(y,target) #结果是tensor(3.)
可以看到,y是一个2*2的tensor,y的第一行是[-1,-2],第二行是[-4,-3]
target的第一个数字是1,表示要从y的第一行取出索引是“1”的元素,即-2;
target的第二个数字是0,表示要从y的第一行取出索引是“0”的元素,即-4;
然后把取出来的全部元素求平均后再取负数,得到最终结果3
回到我们最初的问题,我们把这道题一步一步算一下:
F.cross_entropy(x,target)
- step1:求log_softmax(x)
log_softmax(x)=tensor([[-1.2049, -1.4549, -1.4549, -1.4549]]) - step2: 求nll_loss:
在本例中,我们的target就是torch.tensor([0])
那么我们就在log_softmax(x)的结果里取出索引为“0”的元素:-1.2049
然后求平均再取负数,得到最终结果:1.2049
再来一个例子:
x = torch.tensor([[0.5,0.25,0.25],[1,1,0],[100,50,200],[0,0,1]])
print(F.log_softmax(x))
F.cross_entropy(x,torch.tensor([0,1,2,0]))
'''
tensor([[ -0.9391, -1.1891, -1.1891],
[ -0.8620, -0.8620, -1.8620],
[-100.0000, -150.0000, 0.0000],
[ -1.5514, -1.5514, -0.5514]])
tensor(0.8381)
0.8381 = -(-0.9391-0.8620- 0.0000-1.5514)/4
'''
上面这个例子可以看成:
我有4个样本,一共有3中类别(x的size是4*3)
x是经过各种线性转换、激活函数后得到的结果
target 0,1,2,0表示:第一个样本是类别1,第二个样本是类别2,第三个样本是类别3,第四个样本是类别1
然后用F.cross_entropy计算预测的结果与target的交叉熵
另一种理解思路: