超参数调优策略
本节定位
很多训练问题最后都会绕回一句话:
- 参数没调好
但“调参”常常被做得很随意,好像只能靠运气。
其实更稳的做法是:
把调参当成实验设计问题,而不是盲目撞点。
这节课会把这件事讲实。
学习目标
- 理解哪些超参数最值得先调
- 理解学习率、batch size、正则化等参数分别在影响什么
- 通过可运行示例建立“实验记录和排序比较”的调参直觉
- 学会设计更稳的调参顺序
一、为什么调参不能靠乱试?
1.1 因为参数之间经常互相影响
例如:
- 学习率和 batch size 会一起影响稳定性
- dropout 和 weight decay 会一起影响泛化
1.2 如果没有顺序,实验很快失控
你会遇到:
- 同时改太多参数
- 不知道 是哪项起作用
- 结果不可复现
1.3 一个类比
调参像做烘焙。
如果你一次同时改:
- 温度
- 时间
- 糖量
- 面粉量
你很难知道最后成败到底是谁导致的。
二、最值得优先看的超参数有哪些?
2.1 学习率
通常是第一优先项。
它太大容易震荡,太小又学不动。
2.2 batch size
会影响:
- 梯度稳定性
- 显存占用
- 训练速度
2.3 正则化
例如:
- dropout
- weight decay
它们更偏向控制泛化能力。
2.4 训练轮数 / 早停
它们和是否过拟合关系很大。
三、先跑一个最小调参记录示例
experiments = [
{"lr": 1e-3, "batch_size": 32, "val_acc": 0.84, "train_time_min": 18},
{"lr": 3e-4, "batch_size": 32, "val_acc": 0.88, "train_time_min": 20},
{"lr": 1e-4, "batch_size": 64, "val_acc": 0.86, "train_time_min": 16},
]
def score(exp):
return round(exp["val_acc"] - exp["train_time_min"] * 0.001, 4)
ranked = sorted(
[{**exp, "score": score(exp)} for exp in experiments],
key=lambda x: x["score"],
reverse=True,
)
for item in ranked:
print(item)
3.1 这个例子想表达什么?
调参不是只看一个最终准确率。
你通常还要一起看:
- 训练时间
- 资源成本
- 是否稳定
3.2 为什么实验记录这么重要?
因为没有记录,你就很难回答:
- 哪个参数真的更好
- 这次变化是不是偶然
四、一个更稳的调参顺序
4.1 先固定大部分,只调一两项关键参数
通常建议先看:
- 学习率
- batch size
4.2 确认训练能稳定跑后,再看泛化控制
例如:
- dropout
- weight decay
4.3 最后再做更细的局部搜索
这样能让实验更可解释。
五、最容易踩的坑
5.1 误区一:一次改很多参数
这会让结果难解释。
5.2 误区二:只看训练集表现
调参更该关注:
- 验证集
- 泛化
5.3 误区三:觉得调参就是黑魔法
只要实验设计清楚,
它其实是很工程化的工作。
小结
这节最重要的是建立一个调参判断:
超参数调优不是盲猜,而是围绕学习率、batch size 和泛化控制做有顺序、有记录的实验设计。
只要这个习惯建立起来,后面很多训练问题都会更容易排查。
练习
- 给示例再加两组实验,看看排序是否变化。
- 为什么说学习率通常是最值得优先调的参数?
- 想一想:如果模型训练特别慢,你会怎么让调参更省成本?
- 用自己的话解释:为什么“一次只改少量参数”会更稳?