机器学习任务大概可以分为两类问题,分别是回归问题和分类问题。回归问题预测的是一个连续的数值,例如房价,气温等。而分类问题是将输入预测为不同的类别,例如猫狗分类等。总的来说,回归问题输出是一个实数范围,可以是任何数值;分类问题输出是离散的类别标签,通常是整数或特定的类别名称。接下来对回归问题和分类问题常用的损失函数进行介绍。
MSE损失(Mean Squared Error)也称为 L 2 L_2 L2 Loss,是回归问题中比较常用的损失函数。其公式为:
其中,
y
y
y为模型的预测值,
y
^
\hat{y}
y^为标签值。
优点:由于平方操作,MSE对较大的误差给予更大的惩罚,这有助于模型学习减少大的预测偏差。
缺点:MSE对异常值或离群点非常敏感,这可能会影响模型的泛化能力。
代码实现:
import torch
import torch.nn as nn
y = torch.Tensor([1,2,3])
label = torch.Tensor([3,5,1])
criterion = nn.MSELoss()
loss = criterion(y,label)
print(loss)
输出为tensor(5.6667)
RMSE误差(Root Mean Squared Error)的公式为:
其相当于在MSE的基础上加了一个根号。
优点:与MSE一样,RMSE对较大的误差给予更大的惩罚,同时因为开根号的缘故,它的单位与原始数据的单位相同,这使得它在解释预测误差时更加直观。
缺点:对异常值或离群点非常敏感,计算量较大,RMSE比较难优化,因为它不是一个严格凸函数。
MAE(Mean Absolute Error)又称为 L 1 L_1 L1 Loss,计算所有样本预测值与实际值之差的绝对值的平均值。公式为:
其中,
y
y
y为预测值,
y
^
\hat{y}
y^为标签值。
优点:对异常值不敏感,单位与原始数据一致,易于直观理解,计算简单。
缺点:可能不利于模型学习减少较大的预测偏差。
代码实现:
import torch
import torch.nn as nn
y = torch.Tensor([1,2,3])
label = torch.Tensor([3,5,1])
criterion = nn.L1Loss()
loss = criterion(y,label)
print(loss)
输出为tensor(2.3333)
首先我们先介绍一下相关概念。
信息熵:用来衡量信息的不确定性或信息的平均信息量。其公式为:
其中,
P
(
x
i
)
P(x_i)
P(xi)为随机事件
x
i
x_i
xi发生的概率。若事件发生的不确定性越大,则其熵越大,代表含有更多的信息量。
KL散度:是一种衡量一个概率分布P相对于另一个概率分布Q的非对称性差异,其公式为:
其中, p p p和 q q q是两种不同的分布, p ( x i ) p(x_i) p(xi)和 q ( x i ) q(x_i) q(xi)分别代表随机事件在 p p p和 q q q这两个分布中发生的概率。其具有以下特性:
交叉熵:用于衡量两个概率分布之间的差异,是对称的。
其中, p p p和 q q q是两个分布。交叉熵经常用作分类问题的损失函数,其中,P可以看作是标签的分布,Q可以看作是模型预测的分布。
交叉熵损失函数(Cross-Entropy Loss)是分类问题中常用的损失函数,其衡量的是模型预测的概率分布和标签的真实分布之间的差异。前面说过,计算两个分布之间的交叉熵公式为:
其中, P P P为标签的分布, Q Q Q为模型预测的分布。接下来我们举一个例子来说明。
分类 | 模型预测 | 标签 |
---|---|---|
汽车 | 0.05 | 0 |
猫 | 0.80 | 1 |
飞机 | 0.15 | 0 |
则公式为
因为在分类问题中,标签的分布中只有一个1,其他都为0。因此,在分类问题中,交叉熵损失函数可以简化为:
其中,
p
(
x
i
)
p(x_i)
p(xi)为模型预测的分类结果的概率值。例如,在上述例子中
p
(
x
i
)
p(x_i)
p(xi)的值为0.80。
代码实现:
import torch
import torch.nn as nn
logits = torch.tensor([[0.68,-0.8,0.75]]) #模型的输出
labels = torch.tensor([2]) #标签值为2
criterion = nn.CrossEntropyLoss()
loss = criterion(logits, labels)
print(loss.item())
最终的输出结果为0.8329725861549377。
BCE Loss(Binary Cross-Entropy Loss)是在二分类问题中常用的损失函数,其公式为:
其中,
y
y
y为标签值(0或者1),
p
p
p为模型预测为正样本(标签值为1)的概率。在计算Loss之前,首先要将模型的输出经过Sigmoid激活函数将概率值
p
p
p映射到[0,1]之间。
注意:与使用交叉熵损失做二分类不同的是,如果使用交叉熵损失,则最终模型的输出是一个向量,这个向量经过softmax操作后变成概率分布,代表是正样本的概率和负样本的概率,这些概率相加等于1;而使用BCE Loss时,模型的输出是一个数,然后经过sigmoid操作映射到[0,1]之间,映射后的值就代表模型预测该物品是正样本的概率。下面举一个例子来说明。
通过上述两个例子可以看出,当做二分类任务时,BCE和交叉熵的Loss最终函数形式是一样的,个人认为,这两种损失函数主要的不同在于模型最终的输出形式和最终的概率映射方式不同。
代码实现:
import torch
import torch.nn as nn
predicted_probabilities = torch.tensor([0.8]) # 模型预测的为正样本概率
#1表示正样本,0表示负样本
true_labels = torch.tensor([1])
# 将布尔值转换为浮点数,因为PyTorch的BCELoss期望浮点数标签
true_labels = true_labels.float()
criterion = nn.BCELoss()
loss = criterion(predicted_probabilities, true_labels)
print(loss.item())
代码输出为0.2231435328722。