class torch.nn.NLLLoss(weight=None, size_average=True)
作用:训练一个n类的分类器
参数
weight:可选的,应该是一个tensor,里面的值对应类别的权重,如果样本不均衡的话,这个参数非常有用,长度是类别数目
szie_average:默认是True,会将mini-batch的loss求平均值;否则就是把loss累加起来
loss
loss = nn.NLLLoss()
loss(x,target)=-x[class]
x和target的形状
x:(N,C)N代表BatchSize的大小,C代表类别个数
target:长度为n的tensor,而且0 <= targets[i] <= C-1
这个损失函数的数据流程是:输入原始数据->取softmax->取log->进行loss的计算,进行loss计算的时候也就是把input_log中对应的数据加起来然后除mini-batch。
# input is of size N x C = 3 x 5
input = torch.randn(3, 5, requires_grad=True)
# each element in target has to have 0 <= value < C
target = torch.tensor([1, 0, 4])
output = loss(input, target)
output
#tensor(-0.3095, grad_fn=<NllLossBackward>)
sm=nn.Softmax(dim=1)
sm(input)
# Softmax后的数值都在0~1之间,所以ln之后值域是负无穷到0。
torch.log(sm(input))
tensor([[-2.9870, -1.5195, -1.6582, -1.1737, -1.4651],
[-0.9201, -1.9510, -1.4355, -2.1239, -2.2845],
[-1.7455, -3.2369, -1.4234, -0.8828, -2.0277]], grad_fn=<LogBackward>)
NLLLoss的结果就是把上面的输出与Label对应的那个值拿出来,再去掉负号,再求均值。
1.5195 0.9201 2.0277
torch.nn.CrossEntropyLoss(weight=None,
size_average=None, ignore_index=-100, reduce=None, reduction='mean')
上面的函数综合了torch.nn.LogSoftmax和torch.nn.NLLLoss两个损失函数。
作用:训练一个多类别分类器
本质:将LogSoftmax和NLLLoss集成到一个类别中去
但是测试为何NLL不等于CE???
loss_CE=torch.nn.CrossEntropyLoss()
loss_NLL=torch.nn.NLLLoss()
input_ =torch.tensor([[ 0.2286, 0.4226, -1.3743],
[-2.5661, -0.3380, 0.4873],
[ 0.0445, 0.4939, -0.7239]])
target = torch.tensor([0, 2, 1])
output_NLL =loss_NLL(input_,target)
sm=nn.Softmax(dim=1)
torch.log(sm(input_))
output_ce=loss_CE(input_,target)###CE是softmax+log 求平均