2025损失函数大全:从入门到实战的避坑指南

1次阅读
没有评论

共计 1981 个字符,预计需要花费 5 分钟才能阅读完成。

image.webp

为什么损失函数这么重要?

刚开始学机器学习时,我以为只要选个模型架构,数据喂进去就能自动训练出好结果——直到第一次遇到模型死活不收敛的情况。后来才发现, 损失函数(Loss Function)才是训练过程的隐形导演 ,它决定了模型如何评估预测误差,并通过反向传播告诉参数该往哪个方向调整。

2025 损失函数大全:从入门到实战的避坑指南

常见的新手踩坑场景包括:

  • 做分类任务却用了回归的 MSE 损失,导致概率输出异常
  • 类别不平衡数据直接套用交叉熵,少数类完全被忽视
  • 数据有噪声时使用 L2 损失,模型被异常值带偏

五大主流损失函数对比表

损失函数(中 / 英) 数学公式 梯度特性 适用任务
均方误差 /MSE $\frac{1}{n}\sum(y-\hat{y})^2$ 梯度随误差线性增大 回归任务
平均绝对误差 /MAE $\frac{1}{n}\sum y-\hat{y} $
Huber 损失 $\begin{cases}0.5(y-\hat{y})^2 & y-\hat{y} ≤δ \ δ
交叉熵 /Cross-Entropy $-\sum y\log(\hat{y})$ 概率误差越大概率更新越大 分类任务
合页损失 /Hinge $\max(0, 1-y\cdot\hat{y})$ 仅在边界附近更新 SVM 分类

代码实战:PyTorch & TensorFlow 实现

PyTorch 自定义 Huber 损失

import torch
import torch.nn as nn

class HuberLoss(nn.Module):
    def __init__(self, delta=1.0):
        super().__init__()
        self.delta = delta

    def forward(self, y_pred, y_true):
        error = y_true - y_pred
        abs_error = torch.abs(error)

        # 核心逻辑:分段计算损失
        quadratic = torch.min(abs_error, self.delta)
        linear = abs_error - quadratic
        loss = 0.5 * quadratic**2 + self.delta * linear

        return loss.mean()

# 训练循环示例
loss_fn = HuberLoss(delta=1.5)
optimizer = torch.optim.SGD(model.parameters(), lr=0.01)

for x, y in dataloader:
    pred = model(x)
    loss = loss_fn(pred, y)
    optimizer.zero_grad()
    loss.backward()  # 自动计算梯度
    optimizer.step()

TensorFlow 加权交叉熵

import tensorflow as tf

class WeightedCE(tf.keras.losses.Loss):
    def __init__(self, pos_weight=2.0):
        super().__init__()
        self.pos_weight = pos_weight

    def call(self, y_true, y_pred):
        # 对正样本加权
        loss = - (self.pos_weight * y_true * tf.math.log(y_pred) + 
                 (1-y_true) * tf.math.log(1-y_pred))
        return tf.reduce_mean(loss)

# 使用示例
model.compile(
    optimizer='adam',
    loss=WeightedCE(pos_weight=5)  # 适用于正样本稀少场景
)

性能优化关键考量

  1. 学习率与损失函数的搭配
  2. MSE 的梯度随误差增大而线性增长,建议使用较小的学习率
  3. MAE 的梯度恒定,可以适当增大学习率加速收敛

  4. 异常值处理策略

  5. 当数据存在 5% 以上的异常值时,Huber 损失比 MSE 收敛更稳定
  6. 极端场景(如金融风控)可考虑分位数损失(Quantile Loss)

  7. 分类任务的特例

  8. 多标签分类需改用 Binary Cross-Entropy
  9. 类别超过 1000 时,尝试 Label Smoothing 技术

新手避坑三连

问题 1:类别不平衡导致模型偏向多数类

  • 解决方案
  • 使用带权重的交叉熵(见上方代码)
  • 采用 Focal Loss 自动降低易分类样本的权重

问题 2:回归任务出现梯度爆炸

  • 解决方案
  • 改用 Huber 或 MAE 损失
  • 对输出层做 Batch Normalization

问题 3:二分类模型的输出概率不校准

  • 解决方案
  • 检查是否错误使用了多分类交叉熵
  • 在 sigmoid 后添加 temperature 参数调整

思考题:为什么 MAE 对异常值更鲁棒?

想象有两个预测点:
– 点 A 误差 =10,点 B 误差 =100
– 使用 MSE 时,点 B 的梯度是点 A 的 100 倍($2×100$ vs $2×10$)
– 而 MAE 对两点的梯度都是±1

这种特性使得 MAE 不会对异常值过度反应,但代价是收敛速度较慢——有没有两全其美的方法?(提示:结合 Huber 和动态调整 δ 的策略)

正文完
 0
评论(没有评论)