常见损失函数详解
论文中最常用的 8 个损失函数,按回归和分类两大类组织总结。
一、回归损失函数
回归任务预测连续值,损失函数衡量预测值 y^\\hat{y}y^ 与真实值 yyy 之间的数值差距。
1. 均方误差 MSE / L2 Loss
公式:
MSE=1n∑i=1n(yi−y^i)2\\text{MSE} = \\frac{1}{n} \\sum_{i=1}^{n} (y_i – \\hat{y}_i)^2MSE=n1i=1∑n(yi−y^i)2
预测值与真实值之差的平方的均值。平方操作放大了大误差,使 MSE 对离群点非常敏感,但也因此梯度连续、收敛性好。是回归任务最基础的损失函数。
这里特别说明:
- MSE(均方误差)=1n∑i=1n(yi−y^i)2= \\frac{1}{n} \\sum_{i=1}^{n}(y_i – \\hat{y}_i)^2=n1∑i=1n(yi−y^i)2 —— 对误差平方求平均
- L2 范数 =∑i=1nxi2= \\sqrt{\\sum_{i=1}^{n} x_i^2}=∑i=1nxi2 —— 向量"长度"的平方根(欧氏距离)
- L2 Loss =∑i=1n(yi−y^i)2= \\sum_{i=1}^{n}(y_i – \\hat{y}_i)^2=∑i=1n(yi−y^i)2 —— 误差平方的总和(不平均、不开根号)
import torch
import torch.nn as nn
mse = nn.MSELoss()
y_true = torch.tensor([3.0, 5.0, 2.0, 8.0])
y_pred = torch.tensor([2.8, 5.2, 2.1, 7.5])
loss = mse(y_pred, y_true)
print(f"MSE: {loss.item():.4f}") # → 0.0850
2. 平均绝对误差 MAE / L1 Loss
公式:
MAE=1n∑i=1n∣yi−y^i∣\\text{MAE} = \\frac{1}{n} \\sum_{i=1}^{n} |y_i – \\hat{y}_i|MAE=n1i=1∑n∣yi−y^i∣
预测值与真实值之差的绝对值的均值。与 MSE 相比,MAE 对所有误差给予相同的线性权重,因此对离群点更鲁棒。缺点是在零误差处不可导。
import torch
import torch.nn as nn
mae = nn.L1Loss()
y_true = torch.tensor([3.0, 5.0, 100.0, 8.0]) # 100 是离群点
y_pred = torch.tensor([2.8, 5.2, 90.0, 7.5])
print(f"MAE: {mae(y_pred, y_true).item():.4f}") # → 2.8750
print(f"MSE: {nn.MSELoss()(y_pred, y_true).item():.4f}") # → 25.0625(被离群点放大近10倍)
二、分类损失函数
分类任务预测离散标签,损失函数衡量预测概率分布与真实标签之间的差异。
3. 二分类交叉熵 Binary Cross-Entropy
公式:
BCE=−1n∑i=1n[yilog(y^i)+(1−yi)log(1−y^i)]\\text{BCE} = -\\frac{1}{n} \\sum_{i=1}^{n} \\left[ y_i \\log(\\hat{y}_i) + (1 – y_i) \\log(1 – \\hat{y}_i) \\right]BCE=−n1i=1∑n[yilog(y^i)+(1−yi)log(1−y^i)]
其中 yi∈{0,1}y_i \\in \\{0, 1\\}yi∈{0,1},y^i\\hat{y}_iy^i 是预测为正类的概率。训练时推荐使用 BCEWithLogitsLoss(自带 Sigmoid + BCE,数值更稳定)。
import torch
import torch.nn as nn
bce = nn.BCEWithLogitsLoss() # 推荐:自带 sigmoid,数值稳定
logits = torch.tensor([2.2, –2.0, 1.6, –0.8]) # 原始 logits
labels = torch.tensor([1.0, 0.0, 1.0, 0.0])
print(f"BCE: {bce(logits, labels).item():.4f}") # → 0.1855
多标签分类(一个样本属于多个类别)也使用 BCE,对每个类别独立计算二分类交叉熵。
4. 多分类交叉熵 Cross-Entropy
公式:
CE=−1n∑i=1nlog(ey^i,ci∑j=1Cey^i,j)\\text{CE} = -\\frac{1}{n} \\sum_{i=1}^{n} \\log\\left( \\frac{e^{\\hat{y}_{i, c_i}}}{\\sum_{j=1}^{C} e^{\\hat{y}_{i, j}}} \\right)CE=−n1i=1∑nlog(∑j=1Cey^i,jey^i,ci)
其中 cic_ici 是第 iii 个样本的真实类别索引。只有真实类别对应的 logit 参与了梯度计算,鼓励模型将真实类别的概率推向 1。PyTorch 中 CrossEntropyLoss 自带 Softmax,输入必须是原始 logits(未经 Softmax),标签必须是整数索引。
import torch
import torch.nn as nn
ce = nn.CrossEntropyLoss()
logits = torch.tensor([[2.0, 0.5, –1.0], # 样本1 → 类别0
[0.1, 2.5, 0.3], # 样本2 → 类别1
[–0.5, 0.1, 3.0]]) # 样本3 → 类别2
labels = torch.tensor([0, 1, 2]) # 整数索引,非 one-hot
print(f"CE: {ce(logits, labels).item():.4f}") # → 0.3389
5. Focal Loss
公式:
Focal=−1n∑i=1nαt(1−pt)γlog(pt)\\text{Focal} = -\\frac{1}{n} \\sum_{i=1}^{n} \\alpha_t (1 – p_t)^{\\gamma} \\log(p_t)Focal=−n1i=1∑nαt(1−pt)γlog(pt)
其中 ptp_tpt 是正确类别的预测概率,γ\\gammaγ 是聚焦参数(典型值 2),αt\\alpha_tαt 是类别权重。核心思想:当 ptp_tpt 接近 1(易分类样本),(1−pt)γ(1-p_t)^\\gamma(1−pt)γ 趋近于 0,自动降低该样本的损失权重,让模型聚焦在难样本上。常用于目标检测(RetinaNet)和极度类别不平衡任务。
import torch
import torch.nn as nn
import torch.nn.functional as F
class FocalLoss(nn.Module):
def __init__(self, alpha=0.25, gamma=2.0):
super().__init__()
self.alpha = alpha
self.gamma = gamma
def forward(self, inputs, targets):
# inputs: 经过 sigmoid 的概率, targets: 0 或 1
bce = F.binary_cross_entropy(inputs, targets, reduction='none')
pt = torch.where(targets == 1, inputs, 1 – inputs)
focal_weight = (1 – pt) ** self.gamma
alpha_weight = torch.where(targets == 1, self.alpha, 1 – self.alpha)
return (alpha_weight * focal_weight * bce).mean()
# 模拟:100 个易分负样本 + 5 个难分正样本
fl = FocalLoss(alpha=0.25, gamma=2.0)
y_pred = torch.cat([torch.full((100,), 0.05), torch.full((5,), 0.3)])
y_true = torch.cat([torch.zeros(100), torch.ones(5)])
print(f"Focal Loss: {fl(y_pred, y_true).item():.4f}") # → ~0.004(易样本被降权)
print(f"BCE: {F.binary_cross_entropy(y_pred, y_true).item():.4f}") # → ~0.047
6. KL 散度 KL Divergence
公式:
DKL(P∥Q)=∑iP(i)logP(i)Q(i)D_{KL}(P \\parallel Q) = \\sum_{i} P(i) \\log\\frac{P(i)}{Q(i)}DKL(P∥Q)=i∑P(i)logQ(i)P(i)
衡量两个概率分布 PPP 和 QQQ 之间的差异。KL 散度不对称:DKL(P∥Q)≠DKL(Q∥P)D_{KL}(P \\parallel Q) \\neq D_{KL}(Q \\parallel P)DKL(P∥Q)=DKL(Q∥P)。当 PPP 为真实标签(常数)时,最小化 KL 散度等价于最小化交叉熵。常见于知识蒸馏(让学生分布逼近教师分布)和 VAE(让潜在分布逼近标准正态分布)。当两个分布完全一致的时候,KL散度等于0。
import torch
import torch.nn.functional as F
# 知识蒸馏:学生模型分布逼近教师模型
teacher = F.softmax(torch.tensor([[3.0, –1.0, 0.5]]) / 2.0, dim=1) # 温度 T=2
student = F.log_softmax(torch.tensor([[1.0, 0.5, 0.2]]) / 2.0, dim=1)
kl = F.kl_div(student, teacher, reduction='batchmean')
print(f"KL Divergence: {kl.item():.4f}") # → 0.0628
三、总结对比表
| 回归 | MSE | 1n∑(yi−y^i)2\\frac{1}{n}\\sum (y_i – \\hat{y}_i)^2n1∑(yi−y^i)2 | 敏感 | 通用回归 |
| 回归 | MAE | 1n∑∣yi−y^i∣\\frac{1}{n}\\sum |y_i – \\hat{y}_i|n1∑∣yi−y^i∣ | 鲁棒 | 鲁棒回归 |
| 分类 | BCE | −[ylogy^+(1−y)log(1−y^)]-[y\\log\\hat{y} + (1-y)\\log(1-\\hat{y})]−[ylogy^+(1−y)log(1−y^)] | — | 二分类、多标签分类 |
| 分类 | Cross-Entropy | −log(softmax(y^)true)-\\log(\\text{softmax}(\\hat{y})_{\\text{true}})−log(softmax(y^)true) | — | ResNet、ViT、BERT |
| 分类 | Focal Loss | −α(1−pt)γlog(pt)-\\alpha(1-p_t)^\\gamma \\log(p_t)−α(1−pt)γlog(pt) | — | RetinaNet、长尾分类 |
| 分类 | KL Divergence | ∑Plog(P/Q)\\sum P\\log(P/Q)∑Plog(P/Q) | — | 知识蒸馏、VAE |
网硕互联帮助中心




评论前必须登录!
注册