超参数 = 训练前设定的按钮,调得好差很多

学习率、Batch Size、早停、网格搜索、贝叶斯优化等调参实战技巧。

[toc]

超参数调优


1️⃣ 核心超参数一览

超参数影响典型范围建议
学习率 (lr)⭐⭐⭐ 最重要1e-5 ~ 1e-2先用 1e-3
Batch Size⭐⭐⭐ 训练速度+效果16 ~ 512能多大就多大
Epoch⭐⭐ 训练程度10 ~ 300看验证集早停
优化器⭐⭐⭐ 收敛方式Adam/SGD新手用 Adam
权重衰减 (WD)⭐⭐ 防止过拟合1e-5 ~ 1e-2默认 1e-4
Dropout⭐⭐ 防止过拟合0.1 ~ 0.5越大越防过拟合
网络层数⭐⭐⭐ 模型容量任务而定从简单开始
隐藏层维度⭐⭐ 模型容量64 ~ 4096能大则大但要防过拟合

2️⃣ 学习率 —— 最关键的超参数

学习率的影响

Loss
↑
|   太小 (1e-6)
|   → 缓慢下降,可能卡在局部最优
|
|   刚好 (1e-3)
|   → 快速稳定下降
|
|   太大 (1e-1)
|   → Loss 震荡甚至发散
|
└─────────────────────────→ Step

学习率查找器 (Learning Rate Finder)

import torch
from torch_lr_finder import LRFinder
 
model = MyModel()
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=1e-7)
 
lr_finder = LRFinder(model, optimizer, criterion, device="cuda")
lr_finder.range_test(train_loader, end_lr=10, num_iter=100)
lr_finder.plot()  # 找到 Loss 下降最快的区间
lr_finder.reset()

实用技巧

  1. 先用 LR Finder 找到合适的数量级
  2. 使用 余弦退火分段衰减 调度
  3. 使用 预热 (Warmup) 避免初期不稳定

3️⃣ Batch Size 的选择

影响因素

Batch Size优点缺点
小 (16~64)泛化能力好,省显存训练慢,梯度噪声大
大 (128~512+)训练快,梯度稳定泛化可能下降,吃显存

线性缩放法则 (Linear Scaling Rule)

当 Batch Size 翻倍时,学习率也应翻倍(保持方差一致)

# 假设 batch_size=64 时 lr=1e-3
# 增大到 batch_size=256 时,lr ≈ 4e-3

4️⃣ 调优方法论

from sklearn.model_selection import ParameterGrid
 
param_grid = {
    'lr': [1e-4, 3e-4, 1e-3],
    'batch_size': [32, 64, 128],
    'weight_decay': [0, 1e-4, 1e-3],
}
 
for params in ParameterGrid(param_grid):
    accuracy = train_and_evaluate(**params)
    print(params, accuracy)
import random
 
for _ in range(20):
    lr = 10 ** random.uniform(-4, -2)  # 对数均匀采样
    batch_size = 2 ** random.randint(4, 7)  # 16~128
    weight_decay = 10 ** random.uniform(-5, -2)
    
    accuracy = train_and_evaluate(lr, batch_size, weight_decay)

方法三:贝叶斯优化

# pip install optuna
import optuna
 
def objective(trial):
    lr = trial.suggest_float('lr', 1e-5, 1e-2, log=True)
    batch_size = trial.suggest_categorical('batch_size', [32, 64, 128])
    dropout = trial.suggest_float('dropout', 0.1, 0.5)
    
    accuracy = train_and_evaluate(lr, batch_size, dropout)
    return accuracy
 
study = optuna.create_study(direction='maximize')
study.optimize(objective, n_trials=50)
print(study.best_params)  # 最佳参数

5️⃣ 早停 (Early Stopping)

class EarlyStopping:
    def __init__(self, patience=7, min_delta=0):
        self.patience = patience
        self.min_delta = min_delta
        self.counter = 0
        self.best_loss = None
        self.early_stop = False
    
    def __call__(self, val_loss):
        if self.best_loss is None:
            self.best_loss = val_loss
        elif val_loss > self.best_loss - self.min_delta:
            self.counter += 1
            if self.counter >= self.patience:
                self.early_stop = True
        else:
            self.best_loss = val_loss
            self.counter = 0
 
# 使用
early_stopping = EarlyStopping(patience=5)
for epoch in range(EPOCHS):
    val_loss = train()
    early_stopping(val_loss)
    if early_stopping.early_stop:
        print(f"⏹️ 早停: epoch {epoch}")
        break

🎯 新手调优 checklist

步骤做什么
1️⃣先确保模型能过拟合一个小 batch(验证代码正确)
2️⃣用 LR Finder 找合适学习率
3️⃣固定 lr,调 batch_size
4️⃣微调 weight_decay 和 dropout
5️⃣加入学习率调度和早停
6️⃣尝试更深的网络或更大的隐藏层
7️⃣数据增强 → 进一步提升上限

🔗 下一篇

训练监控与可视化