L o s s ( x , y ) = 1 N ∑ i ( ∣ x i − y i ∣ ) Loss(x,y)=\frac{1}{N} \sum_{i}( |x_i-y_i|) Loss(x,y)=N1i∑(∣xi−yi∣)
简单而言,就是两个向量的绝对值的误差。 默认求平均,可以设置为sum。 也是mean absolute error(MAE)
举例而言:
loss = nn.L1Loss() ''' L1 Loss ''' predict_ar = [0,2,3] target_ar = [2,2,3] input = torch.FloatTensor(predict_ar) input.requires_grad = True target = torch.FloatTensor(target_ar) output = loss(input, target) print(output)结果则是0.667
这个也容易理解,则是平方误差。 mean squared error。
loss = nn.MSELoss() ''' L1 Loss ''' predict_ar = [0, 2, 3] target_ar = [2, 2, 3] input = torch.FloatTensor(predict_ar) input.requires_grad = True target = torch.FloatTensor(target_ar) output = loss(input, target) print(output)这个结果应该是4/3= 1.333
https://pytorch.org/docs/stable/generated/torch.nn.NLLLoss.html#torch.nn.NLLLoss
The negative log likelihood loss. It is useful to train a classification problem with C classes.
这个loss有点不是非常容易理解,它主要的目标是衡量分类问题里,标签和真值的差异,只是用了log和取负。
loss(input, class) = -input[class]
你没有看错,就是这么简单。 input=[-1.233, 2.657, 0.534], 真实标签为2(class=2),则loss为-0.534
但实际上,大部分情况,input需要做log_softmax喂给NLLLoss。
最好的例子就是看代码。 输出结果:
input: tensor([[-0.8539, -1.0684, -1.4668], [-1.4419, -1.0158, -0.9127], [-0.9002, -1.1611, -1.2716]]) target: tensor([0, 2, 1]) loss_manual: 0.9758999999999999 loss_value: 0.97590446计算公式: H ( p , q ) = − ∑ ∀ x p ( x ) log ( q ( x ) ) H(p,q) = -\sum_{\forall x} p(x) \log(q(x)) H(p,q)=−∀x∑p(x)log(q(x))
大部分计算的公式 J = − 1 N ( ∑ i = 1 N y i ⋅ log ( y ^ i ) ) J = - \frac{1}{N}\left(\sum_{i=1}^{N} \mathbf{y_i} \cdot \log(\mathbf{\hat{y}_i})\right) J=−N1(i=1∑Nyi⋅log(y^i))
为何交叉熵可以评估多分类?
A就是数据的真实分布: p(x) B就是模型从训练数据上学到的分布:q(x) 交叉熵可以很好的表示分布的差异,所以利用最小化交叉熵来达到拟合分布。 具体细节可以参考:https://www.zhihu.com/question/65288314
将输入经过softmax激活函数之后,再计算其与target的交叉熵损失。即该方法将nn.LogSoftmax()和 nn.NLLLoss()进行了结合。严格意义上的交叉熵损失函数应该是nn.NLLLoss()。
仔细观察下面的官网的公式(是不是有softmax的影子,是不是有log,是不是还有nll操作(x[class]). 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]))
我们利用上面的例子验证一下结果:
def nll_loss(): #input = torch.rand(3,3) raw_input = torch.FloatTensor([[0.8065, 0.5920, 0.1936], [0.0985, 0.5246, 0.6277], [0.7537, 0.4928, 0.3823] ]) #每一行是一个预测结果, 分为三类; # 如果我们的真值是[0,2,1]类别,那么nllloss如何计算? #预处理logsoftmax ls = nn.LogSoftmax(dim=1) #行操作; input = ls(raw_input) target = torch.tensor([0,2,1]) # 手算 loss_manual =(0.8539+0.9127+1.1611)/3 print("input:",input) print("target:", target) print("loss_manual:",loss_manual) # 机算 loss_f = nn.NLLLoss() loss_value = loss_f(input,target) print("loss_value:",loss_value.numpy()) loss_f_crossentropy = nn.CrossEntropyLoss() loss_ce = loss_f_crossentropy(raw_input,target) print("loss_ce:", loss_ce.numpy())输出结果:
input: tensor([[-0.8539, -1.0684, -1.4668], [-1.4419, -1.0158, -0.9127], [-0.9002, -1.1611, -1.2716]]) target: tensor([0, 2, 1]) loss_manual: 0.9758999999999999 loss_value: 0.97590446 loss_ce: 0.97590446