NLLLoss和CrossEntropyLoss

2021年5月23日23:05:39 发表评论

NLLLoss

在图片单标签分类时,输入m张图片,输出一个m*N的Tensor,其中N是分类个数。比如输入3张图片,分三类,最后的输出是一个3*3的Tensor,举个例子:

input = torch.randn(3,3)
tensor([[-0.1342,-2.5835,-0.9810],
        [0.1867,-1.4513,-0.3225],
        [0.6272,-0.1120,-0.3048],])

第123行分别是第123张图片的结果,假设第123列分别是猫、狗和猪的分类得分。可以看出模型认为第123张都更可能是猫。然后对每一行使用Softmax,这样可以得到每张图片的概率分布。

sm = nn.Softmax(dim=1)
sm(input)
tensor([[0.6600,0.0570,0.2830],
        [0.5570,0.1083,0.3347],
        [0.4542,0.2169,0.3290]])

这里dim的意思是计算Softmax的维度,这里设置dim=1,可以看到每一行的加和为1。比如第一行0.6600+0.0570+0.2830=1。

然后对Softmax的结果取自然对数:

torch.log(sm(input))
tensor([[-0.4155,-2.8648,-1.2643],
        [-0.5852,-2.2232,-1.0945],
        [-0.7893,-1.5285,-1.1117]])

Softmax后的数值都在0~1之间,所以ln之后值域是负无穷到0。NLLLoss的结果就是把上面的输出与Label对应的那个值拿出来,再去掉负号,再求均值。

假设我们现在Target是[0,2,1](第一张图片是猫,第二张是猪,第三张是狗)。第一行取第0个元素,第二行取第2个,第三行取第1个,去掉负号,结果是:[0.4155,1.0945,1.5285]。再求个均值,结果是:

(0.4155+1.0945+1.5285)/3=1.0128333333333

下面使用NLLLoss函数验证一下:

nn.NLLLoss(torch.log(sm(input)),torch.tensor([0,2,1]))
tensor(1.0128)

嘻嘻,果然是1.0128!

CrossEntropyLoss

CrossEntropyLoss就是把以上Softmax–Log–NLLLoss合并成一步,我们用刚刚随机出来的input直接验证一下结果是不是1.0128:

nn.CrossEntropyLoss(input,torch.tensor([0,2,1]))
tensor(1.0128)

真的是1.0128哈哈哈哈!我也太厉害了吧!

如果你也觉得我很厉害,请打赏以鼓励我做的更好,非常感谢!

flyingsheep

发表评论