机器学习基础:过拟合与欠拟合的识别与解决方法实战

1次阅读
没有评论

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

image.webp

1. 背景与核心概念

1.1 过拟合(Overfitting)现象

当模型在训练集上表现优异(如准确率 98%),但在测试集上表现显著下降(如准确率 60%)时,称为过拟合。本质是模型过度记忆了训练数据中的噪声和局部特征,导致泛化能力差。典型场景:

机器学习基础:过拟合与欠拟合的识别与解决方法实战

  • 模型参数量远大于训练样本数
  • 训练迭代轮数(Epoch)过多

1.2 欠拟合(Underfitting)现象

模型在训练集和测试集上表现均不佳(如训练准确率 50%),说明未能学习到数据的基本规律。常见原因:

  • 模型复杂度不足(如用线性模型拟合非线性数据)
  • 特征工程不充分

2. 解决方案技术对比

2.1 过拟合解决方案:正则化对比

方法 L1 正则化(Lasso) L2 正则化(Ridge)
数学形式 损失函数 + λ∑ w
作用效果 产生稀疏权重,自动特征选择 平滑权重分布,抑制极端值
适用场景 高维特征且存在大量冗余特征 特征间存在共线性时

2.2 欠拟合解决方案:模型复杂度对比

模型类型 单层感知机 深度神经网络
参数量 输入维度 × 输出维度 多层隐藏层,参数量指数级增长
拟合能力 只能拟合线性决策边界 可逼近任意连续函数

3. PyTorch 实战代码

3.1 过拟合解决方案实现

import torch
import torch.nn as nn

# 带 L2 正则化和 Dropout 的神经网络
class RegularizedNN(nn.Module):
    def __init__(self, input_dim):
        super().__init__()
        self.layers = nn.Sequential(nn.Linear(input_dim, 128),  # [batch, input_dim] → [batch, 128]
            nn.ReLU(),
            nn.Dropout(0.5),  # Dropout 随机失活 50% 神经元
            nn.Linear(128, 64),
            nn.ReLU(),
            nn.Linear(64, 1)
        )

    def forward(self, x):
        return self.layers(x)

# L2 正则化实现(权重衰减)model = RegularizedNN(input_dim=10)
optimizer = torch.optim.Adam(model.parameters(), lr=0.001, weight_decay=1e-4)  # weight_decay 即 L2 系数 

3.2 欠拟合解决方案实现

# 增加网络深度的解决方案
class DeepNN(nn.Module):
    def __init__(self, input_dim):
        super().__init__()
        self.deep_layers = nn.Sequential(nn.Linear(input_dim, 256),  # 扩展第一层神经元数量
            nn.ReLU(),
            nn.Linear(256, 128),       # 新增隐藏层
            nn.ReLU(),
            nn.Linear(128, 64),
            nn.ReLU(),
            nn.Linear(64, 1)
        )

    def forward(self, x):
        return self.deep_layers(x)

4. 关键训练指标监控

for epoch in range(100):
    model.train()
    for X, y in train_loader:
        optimizer.zero_grad()
        pred = model(X)
        loss = F.mse_loss(pred, y)
        loss.backward()
        optimizer.step()

    # 验证集评估
    model.eval()
    with torch.no_grad():
        val_pred = model(val_X)
        val_loss = F.mse_loss(val_pred, val_y)
    print(f"Epoch {epoch}: Train Loss {loss.item():.4f} | Val Loss {val_loss.item():.4f}")

5. 三大实践避坑指南

  1. 过早停止正则化
  2. 错误现象:在验证集损失刚开始上升时就停止 L2 正则化
  3. 正确做法:观察早停窗口(如连续 5 个 epoch 未改善)再调整

  4. 盲目增加网络深度

  5. 错误现象:直接使用 10 层网络导致梯度消失
  6. 正确做法:先尝试 2 - 3 个隐藏层,配合 BatchNorm 使用

  7. 忽略数据本身问题

  8. 错误现象:将测试集表现差单纯归因于过拟合
  9. 正确做法:检查训练 / 测试集分布是否一致(可用 PCA 可视化)

6. 延伸思考问题

  1. 当验证集准确率波动较大时,如何区分是过拟合还是数据噪声导致?
  2. 对于小样本数据集(如医疗影像),如何在有限数据下平衡模型复杂度?
  3. 如何设计实验证明当前模型处于欠拟合状态?(提示:学习曲线分析)

实验效果验证建议

  • 过拟合实验:固定模型结构,逐步减少训练数据量(从 10k→1k 样本),观察验证集准确率下降幅度
  • 欠拟合实验:使用复杂生成数据(如 sin(x)+ 噪声),比较线性回归与神经网络的拟合曲线差异
正文完
 0
评论(没有评论)