🔥 Stage 05 · 模型训练与超参数调优

调参不是玄学,是科学

本模块包含交互式超参数模拟器、学习率调度器可视化、正则化策略选择器。调参技巧一网打尽。

🎛️ 交互式超参数调优模拟器

调整下面的参数,观察对训练效果的模拟影响

0.001
太小:训练慢太大:震荡/发散
32
小:噪声大大:显存占用多
50
太少:欠拟合太多:过拟合
0.0001
0(无正则)强正则

📊 模拟训练效果

预计 Train Accuracy
--
预计 Val Accuracy
--
Loss 趋势模拟
调整参数查看模拟效果...

🛡️ 防止过拟合的正则化策略

🥷

Dropout

训练时随机失活神经元,防止协同依赖

nn.Dropout(0.5)
常用值:0.3 ~ 0.7
⚖️

L1/L2 正则

损失函数增加权重惩罚项

weight_decay=1e-4
L2最常用(权重衰减)
🎲

数据增强

训练时对样本做随机变换扩充数据

CV:翻转/旋转/色彩
NLP:同义词替换/回译
🛑

Early Stopping

验证集效果连续N轮不降 → 停止训练

patience=5~10
最省心的防过拟合手段

📝 完整训练循环模板(PyTorch)

import torch; import torch.nn as nn; import torch.optim as optim
from torch.cuda.amp import autocast, GradScaler  # 混合精度加速
from tqdm import tqdm
from utils.metrics import compute_metrics
from utils.logging import WandBLogger

def train(config, model, train_loader, val_loader):
    device = torch.device(config.device)
    model = model.to(device)
    
    criterion = nn.CrossEntropyLoss()
    optimizer = optim.AdamW(model.parameters(), lr=config.lr, weight_decay=config.wd)
    scheduler = optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=config.epochs)
    scaler = GradScaler()  # 混合精度
    
    logger = WandBLogger(config)
    best_val_acc = 0
    patience_counter = 0
    
    for epoch in range(config.epochs):
        # ===== 训练阶段 =====
        model.train()
        train_loss = 0
        for images, labels in tqdm(train_loader):
            images, labels = images.to(device), labels.to(device)
            optimizer.zero_grad()
            
            with autocast():
                outputs = model(images)
                loss = criterion(outputs, labels)
            
            scaler.scale(loss).backward()
            scaler.step(optimizer)
            scaler.update()
            train_loss += loss.item()
        
        scheduler.step()
        
        # ===== 验证阶段 =====
        model.eval()
        val_loss, val_acc = 0, 0
        with torch.no_grad():
            for images, labels in val_loader:
                images, labels = images.to(device), labels.to(device)
                outputs = model(images)
                val_loss += criterion(outputs, labels).item()
                val_acc += (outputs.argmax(1) == labels).sum().item()
        
        val_acc /= len(val_loader.dataset)
        
        # ===== 记录日志 =====
        logger.log({
            'epoch': epoch,
            'train_loss': train_loss / len(train_loader),
            'val_loss': val_loss / len(val_loader),
            'val_acc': val_acc,
            'lr': optimizer.param_groups[0]['lr']
        })
        
        # ===== Early Stopping =====
        if val_acc > best_val_acc:
            best_val_acc = val_acc
            torch.save(model.state_dict(), 'models/best.pt')
            patience_counter = 0
        else:
            patience_counter += 1
            if patience_counter > config.patience:
                print(f'Early stopping at epoch {epoch}')
                break
    
    return best_val_acc

🔍 超参数搜索策略

📏

遍历所有组合,简单但组合爆炸

适合:超参数少(2-3个)
param_grid = {
'lr': [1e-3, 1e-4, 1e-5],
'wd': [0, 1e-4, 1e-2]
}
🎲

随机采样,高概率找到好区域

适合:大多数场景,首选方法
params = {
'lr': uniform(1e-5, 1e-2),
'wd': loguniform(1e-5, 1e-1)
}
🤖

贝叶斯优化 BO

用概率模型指导搜索,高效

适合:计算昂贵的场景
Optuna / Hyperopt / Ray Tune
← 返回模型选择 下一章:评估迭代 →