随着Pytorch的不断学习,我们步伐来到了对模型评估方面的探讨,本期我们来对损失函数做一些基本的介绍。
损失函数是衡量模型预测值与真实值之间差距的一种方法。通过数学方式对差距进行量化,评估模型的预测精度并进行优化。当模型预测值与真实值之间的误差较小时,损失函数的值也会较小。
有了损失函数,整个模型才有了训练的基石,更重要的是损失函数在指导模型目标的同时,还从反面倒逼模型的架构。
其本质意义是,通过损失的最小化,来指导神经网络的预测不断逼近真实情况
换言之:只有定义好了损失的计算方式,才有模型的搭建思路。
它的优点是可导,在梯度下降法中可以很方便地求解损失函数的最小值。
对于给定的训练数据集,其损失函数定义为所有训练样本预测值与真实值之差的平方和的平均值。公式为 1 2 ( y − y ^ ) 2 \frac{1}{2}(y - \hat{y})^2 21(y−y^)2,在回归问题中经常使用。
Pytorch中的API:
nn.MSELoss
它的实现方法非常简单,主要是调用PyTorch中的torch.pow
和torch.mean
函数。
下面是nn.MSELoss
的部分源代码(示例):
class MSELoss(_Loss):
def forward(self, input: Tensor, target: Tensor) -> Tensor:
return torch.mean(torch.pow(input - target, 2))
在这段代码中,MSELoss继承自_Loss类,它定义了一个forward方法,用于计算损失函数的值。该方法接收两个参数:input表示模型的预测值,target表示目标值。该方法的实现非常简单,只需要计算预测值与目标值之差的平方和,然后计算这些值的平均值即可得到损失函数的值。
它的优点是对异常值不敏感,可以很好地避免因异常值的存在而使模型的预测结果变得不准确。
与平方损失函数类似,它也是对于给定的训练数据集,其损失函数定义为所有训练样本预测值与真实值之差的绝对值的和的平均值。公式为 ∣ y − y ^ ∣ |y - \hat{y}| ∣y−y^∣,在回归问题中也常用。
Pytorch中的API:
nn.L1Loss
它的实现方法类似于nn.MSELoss,主要是调用PyTorch中的torch.abs
和torch.mean
函数。
下面是nn.L1Loss
的部分源代码(示例):
class L1Loss(_Loss):
def forward(self, input: Tensor, target: Tensor) -> Tensor:
return torch.mean(torch.abs(input - target))
在这段代码中,L1Loss类也继承自_Loss类,它定义了一个forward方法,用于计算损失函数的值。该方法接收两个参数:input表示模型的预测值,target表示目标值。该方法的实现非常简单,只需要计算预测值与目标值之差的绝对值和,然后计算这些值的平均值即可得到损失函数的值。
它的优点是可以很好地表示模型的预测结果与真实值之间的差距,可以很方便地计算损失函数的最小值。
它是用来衡量两个概率分布之间的差异。公式为 − ∑ i n y i log ( y i ^ ) -\sum_{i}^{n} y_i \log(\hat{y_i}) −∑inyilog(yi^),在分类问题中常用。
Pytorch中的API:
nn.CrossEntropyLoss
它的实现方法比前面两个类略微复杂一些,主要是调用PyTorch中的torch.nn.functional.nll_loss
函数。
下面是nn.CrossEntropyLoss
的部分源代码:
class CrossEntropyLoss(_WeightedLoss):
def forward(self, input: Tensor, target: Tensor) -> Tensor:
return torch.nn.functional.nll_loss(input, target, weight=self.weight, reduction=self.reduction)
在这段代码中,CrossEntropyLoss类继承自_WeightedLoss类,它定义了一个forward方法,用于计算损失函数的值。该方法接收两个参数:input表示模型的预测值,target表示目标值。该方法的实现主要是调用PyTorch中的torch.nn.functional.nll_loss函数,它能够计算模型预测值与目标值之间的交叉熵损失。
Pytorch中的API:
nn.MSELoss
、nn.L1Loss
、nn.CrossEntropyLoss
import torch
from torch import nn
# 定义模型
class Model(nn.Module):
def __init__(self):
super(Model, self).__init__()
self.linear1 = nn.Linear(1, 1)
self.linear2 = nn.Linear(1, 2)
def forward(self, x):
return self.linear1(x), self.linear2(x)
# 实例化模型
model = Model()
# 定义损失函数
mse_loss = nn.MSELoss()
l1_loss = nn.L1Loss()
ce_loss = nn.CrossEntropyLoss()
# 计算损失
input = torch.tensor([[1.0]])
target1 = torch.tensor([[2.0]])
target2 = torch.tensor([[0, 1]])
output1, output2 = model(input)
loss1 = mse_loss(output1, target1)
loss2 = l1_loss(output1, target1)
loss3 = ce_loss(output2, target2)
total_loss = loss1 + loss2 + loss3
print(total_loss)
在这个示例中,我们定义了一个线性模型,它能够分别输出一个数值和一个二元分类的预测值。然后,我们定义了三个损失函数:nn.MSELoss用于计算数值的平方损失,nn.L1Loss用于计算数值的绝对损失,nn.CrossEntropyLoss用于计算二元分类的交叉熵损失。最后,我们将三个损失函数的结果求和,得到总损失值。
以上就是今天要讲的内容,这三种损失函数都是常用的,选择损失函数应该根据实际问题的类型和要求来决定。例如,对于回归问题,可以选择平方损失函数或绝对损失函数;对于分类问题,可以选择交叉熵损失函数。