我跟着this tutorial,我对作者定义负对数似然丢失函数的部分感到困惑。
def nll(input, target):
return -input[range(target.shape[0]), target].mean()
loss_func = nll
在这里,target.shape[0]
是64
和target
是一个长度为64的向量
tensor([5, 0, 4, 1, 9, 2, 1, 3, 1, 4, 3, 5, 3, 6, 1, 7, 2, 8, 6, 9, 4, 0, 9, 1, 1, 2, 4, 3, 2, 7, 3, 8, 6, 9, 0, 5, 6, 0, 7, 6, 1, 8, 7, 9, 3, 9, 8, 5, 9, 3, 3, 0, 7, 4, 9, 8, 0, 9, 4, 1, 4, 4, 6, 0])
。
这个numpy索引如何导致损失函数?而且,当在方括号内有range()和另一个数组时,numpy数组的输出应该是什么?
在教程中,input
和target
都是torch.tensor
。
负对数似然丢失计算如下:
nll = -(1/B) * sum(logPi_(target_class)) # for all sample_i in the batch.
哪里:
B
:批量大小C
:课程数量Pi
:形状[num_classes,]样本i
的预测概率向量。它是通过样本logit
的i
向量的softmax值获得的。logPi
:Pi
的对数,我们可以简单地通过F.log_softmax(logit_i)
得到它。让我们分解一个简单的例子:
input
预计作为log_softmax
值,形状[B, C]
。target
被期待作为形状[B, ]
的地面真相类。为了减少混乱,让我们采取
B = 4
和C = 3
。
import torch
B, C = 4, 3
input = torch.randn(B, C)
"""
>>> input
tensor([[-0.5043, 0.9023, -0.4046],
[-0.4370, -0.8637, 0.1674],
[-0.5451, -0.5573, 0.0531],
[-0.6751, -1.0447, -1.6793]])
"""
target = torch.randint(low=0, high=C, size=(B, ))
"""
>>> target
tensor([0, 2, 2, 1])
"""
# The unrolled version
nll = 0
nll += input[0][target[0]] # add -0.5043
nll += input[1][target[1]] # add -0.1674
nll += input[2][target[2]] # add 0.0531
nll += input[3][target[3]] # add -1.0447
nll *= (-1/B)
print(nll)
# tensor(0.3321)
# The compact way using numpy indexing
_nll = -input[range(0, B), target].mean()
print(_nll)
# tensor(0.3321)
两种计算方式类似。希望这可以帮助。