楼层: 首页/ 软件技术/ Python 机器学习与深度学习/ 模型调优、正则化与迁移学习
14

模型调优、正则化与迁移学习

Hyperparameter Tuning & Transfer Learning

跑通 baseline 只是开始,把指标再涨 2 个点靠的是调参和技巧。

超参数搜索:网格 / 随机 / 贝叶斯

方法说明
GridSearchCV穷举,参数少(3×3×3=27 组合)用。
RandomizedSearchCV随机采样,参数空间大时比网格高效。
Optuna(贝叶斯)根据历史结果智能选下一组,最少实验次数找最优。当前主流。
import optuna def objective(trial): params = { "n_estimators": trial.suggest_int("n_estimators", 100, 500), "max_depth": trial.suggest_int("max_depth", 3, 10), "learning_rate": trial.suggest_float("learning_rate", 0.01, 0.3, log=True), } model = XGBRegressor(**params) score = cross_val_score(model, X, y, cv=5, scoring="neg_mean_squared_error").mean() return score study = optuna.create_study(direction="maximize") study.optimize(objective, n_trials=50) print("最优参数:", study.best_params)

正则化全家桶

方法原理
L1 权重衰减损失 + α·|w|,稀疏化。
L2 权重衰减损失 + α·w²,让参数小。AdamW 的 weight_decay 参数。
Dropout训练随机关神经元,相当于多模型集成。
早停验证 loss 不降就停。
数据增强图像翻转/裁剪/NLP 同义词替换。
标签平滑one-hot 改成 0.9/0.05,防过度自信。

迁移学习

from torchvision import models model = models.resnet18(weights=models.ResNet18_Weights.DEFAULT) # 冻结特征提取部分 for p in model.parameters(): p.requires_grad = False # 只换最后一层 model.fc = nn.Linear(model.fc.in_features, 5) # 5 类 # 先训 fc,再解冻前面几层用更小学习率微调

学习曲线:诊断偏差方差

from sklearn.model_selection import learning_curve import matplotlib.pyplot as plt train_sizes, train_scores, val_scores = learning_curve( model, X_train, y_train, cv=5, train_sizes=np.linspace(0.1, 1.0, 10), scoring="accuracy", n_jobs=-1 ) train_mean = train_scores.mean(axis=1) val_mean = val_scores.mean(axis=1) plt.plot(train_sizes, train_mean, label="训练") plt.plot(train_sizes, val_mean, label="验证") plt.xlabel("训练样本数"); plt.ylabel("准确率") plt.legend(); plt.title("学习曲线") plt.show() # 两条线距离大 = 过拟合(高方差) # 两条线都低 = 欠拟合(高偏差) # 两条线接近且高 = 刚好

迁移学习代码模板

from torchvision import models import torch.nn as nn # 第 1 步:加载预训练模型 model = models.resnet18(weights=models.ResNet18_Weights.DEFAULT) # 第 2 步:冻结所有层 for param in model.parameters(): param.requires_grad = False # 第 3 步:替换最后一层(你的任务可能是 5 类) num_ftrs = model.fc.in_features model.fc = nn.Linear(num_ftrs, 5) # 第 4 步:只训最后一层(小学习率) opt = optim.Adam(model.fc.parameters(), lr=1e-3) # 训练几轮后,如果效果还不够,解冻前面几层用更小学习率微调 for param in model.layer4.parameters(): param.requires_grad = True opt = optim.Adam(model.parameters(), lr=1e-5) # 差异化学习率:顶层大、底层小

学习率怎么找:LR Finder

# 快速找最优学习率:从很小开始,每步乘 1.1,画 loss vs lr 曲线 # 选 loss 下降最快那段的拐点值 from torch_lr_finder import LRFinder lr_finder = LRFinder(model, opt, criterion, device=device) lr_finder.range_test(train_loader, end_lr=10, num_iter=100) lr_finder.plot() # 图上 loss 刚开始下降的拐点就是好的学习率(一般 1e-3 ~ 1e-2)

本章面试题

面试 · 调优

Q1. 学习率太大/太小分别会怎样?

查看答案

太大 loss 震荡甚至发散(变 NaN);太小收敛慢、卡局部最优。一般 1e-3 起步,配合 warmup 和余弦退火。

Q2. batch size 大小影响?

查看答案

大 batch 梯度准、快,但泛化差、内存爆;小 batch 有噪声,反而正则化、泛化好。常用 32/64/128。

Q3. 迁移学习为什么有效?

查看答案

底层特征(边缘、纹理)在大数据上学好可迁移,顶层特征再微调适配新任务。