训练参数基础:学习率、批量大小、迭代次数
说到空间模型的训练,这三个参数就像发动机的油门、载重和里程。调好了,车跑得又快又稳;调不好,要么原地打转,要么直接翻车。我刚开始接触大规模点云训练时,就吃过不少亏——学习率设太大,loss 直接炸到 NaN;批量大小设太小,GPU 利用率只有 10%,训一个 epoch 够喝三杯咖啡。今天咱们就把这三个基础参数掰开揉碎讲清楚。
学习率(Learning Rate)
学习率决定了模型参数每次更新的步长。说白了,就是告诉模型“你该往梯度方向跳多远”。
- 太大:参数振荡发散,loss 不降反升。我曾经在一个三维语义分割模型上将 lr 设为 0.1,结果前几个 batch loss 冲到了 1e5,直接放弃治疗。
- 太小:收敛极慢,可能卡在局部极小点。你想想看,每次只挪一小步,训几天都出不来。
- 合适:loss 平滑下降,验证精度稳步提升。
常见的初始学习率范围:
| 任务类型 | 推荐初始 lr | 常用优化器 |
|---|---|---|
| 点云分类(PointNet++ 类) | 1e-3 ~ 1e-2 | Adam / SGD + momentum |
| 三维目标检测(VoxelNet 类) | 1e-4 ~ 1e-3 | AdamW |
| 场景流估计 | 1e-4 ~ 5e-4 | Adam |
| NeRF 类空间表示 | 5e-4 ~ 5e-3 | Adam |
这里有个小技巧:先跑几个 batch 做学习率范围测试。找个很小的 lr(比如 1e-6),逐渐增大,观察 loss 变化。选择 loss 下降最快且不震荡的那个区间。
批量大小(Batch Size)
批量大小指每次更新参数时使用的样本数量。它影响三件事:梯度稳定性、内存占用、泛化能力。
- 小批量(16~64):梯度噪声大,但能跳出现阱。适合内存受限的场景,比如点云数据量很大时。
- 大批量(128~512+):梯度估计更准,训练速度快,但容易过拟合。嗯,这里要注意——批量大小翻倍时,学习率通常也要跟着线性增大(线性 scaling rule)。
- 极限大批量(1024+):需要特殊策略,比如 LARS 优化器,否则泛化性能会明显下降。我在一次点云分割比赛中试过 batch size=1024,结果验证集精度比 batch size=64 低了 2 个点。
内存与批量大小的关系也很直接:
# 假设输入点云为 (B, N, C),每点 16 字节,N=4096, C=3
# batch size=32 时,显存占用约:
# 32 * 4096 * 3 * 16 ≈ 6.3 MB(仅输入)
# 加上特征图、梯度、优化器状态,实际翻 5~10 倍
# 所以 batch size=32 往往需要 12~24 GB 显存
我建议:先用 GPU 能容纳的最大 batch size 开始,然后逐步减小,观察验证集上的表现。通常小一点反而泛化更好。
迭代次数(Epoch / Iteration)
迭代次数分为两种:epoch(完整遍历一次训练集)和 iteration(一个 batch 更新一次)。两者关系很简单:iterations_per_epoch = 样本总数 / batch size。
那到底要训多少个 epoch?这取决于模型大小和数据量。我的经验是:
- 小数据集(<1k 样本):50~200 epoch,配合早停(early stopping)。
- 中等数据集(1k~10k 样本):100~500 epoch。
- 大型数据集(>100k 样本):20~100 epoch。
另外,迭代次数与学习率调度强相关。比如 step decay:每 N 个 epoch 将 lr 乘以 0.1。我常用的调度策略:
# PyTorch 示例:余弦退火 + 线性 warmup
import torch.optim as optim
from torch.optim.lr_scheduler import CosineAnnealingLR, LinearLR
optimizer = optim.AdamW(model.parameters(), lr=1e-3)
warmup = LinearLR(optimizer, start_factor=0.1, total_iters=5)
cosine = CosineAnnealingLR(optimizer, T_max=95)
scheduler = torch.optim.lr_scheduler.SequentialLR(
optimizer, schedulers=[warmup, cosine], milestones=[5])
三者之间的微妙关系
这三个参数不是孤立的。调整一个,往往需要连带调整另外两个。下面这张图我画了多次才理清思路:
实战调参 checklist
我自己总结了一套快速调参流程,用起来挺顺手的:
- 固定 batch size:先设为 GPU 能承受的最大值,比如 64。
- 找合适 lr:用学习率范围测试,找到 loss 下降最快的区间,选中间值。
- 调节 batch size:在 16~128 之间尝试,观察验证精度。通常小 batch 泛化更好,但别忘了同步调 lr。
- 定迭代次数:不加早停,先看 loss 曲线什么时候平缓,之后再加 20% 作为安全余量。
- 联合微调:比如将 lr 减半、batch 加倍,看效果是否更好。
核心原则:学习率是“油门”,批量大小是“载重”,迭代次数是“里程”。油门踩大了载重不够会飘,载重太重了油门得跟上。三者平衡,才能又快又稳到终点。
嗯,基本就是这些。下次你在训练空间模型时,先别急着改网络结构,花半小时把这仨参数摸一遍,往往能省下几天的时间。我当年要是早懂这个道理,也不至于对着 NaN 的 loss 发呆一整天了。