3D模型训练时,损失曲线长期震荡、评估指标停滞或中途出现NaN,意味着优化过程没有真正收敛。与2D图像任务相比,3D点云、体素和网格数据更容易受到梯度噪声、稀疏特征和显存限制的影响,因此学习率调度与优化器选择往往成为决定训练成败的关键。

一、先判断不收敛的表征:数据、损失与优化信号
3D模型不收敛通常表现为三类:训练损失震荡剧烈,验证指标持续变差,或者参数梯度范数出现异常。排查时不能只盯着网络结构,而应先把数据输入、损失函数和优化器配置纳入同一检查框架。
数据层面,点云坐标如果没有做中心化和尺度归一化,体素分辨率过大会导致有效体素占比极低,这些都会让梯度方向不稳定。举例来说,将ShapeNet点云坐标直接输入PointNet而不做归一化,初始损失可能一直停滞在较高位置。此时即使降低学习率,训练仍然难以进入有效下降通道。因此建议在数据加载阶段统计全局均值与方差,对坐标做零均值单位方差变换。对于体素任务,还要检查稀疏体素占比,若低于千分之一,应改用稀疏卷积或降低体素分辨率。
损失函数与评估指标不匹配也是常见诱因。例如点云分割中训练使用交叉熵,评估却使用IoU,交叉熵可能已经下降但IoU没有提升,这并不一定是优化器问题。需要分清是训练损失不下降,还是验证指标不上升。前者更偏向优化过程,后者则可能涉及泛化与数据分布。
二、学习率调度策略:从预热到退火
学习率过大是3D模型训练不收敛的首要原因之一。在训练初期,模型参数接近随机初始化,梯度方向变化剧烈,此时如果直接使用目标学习率,参数更新幅度会非常大,容易把模型推到高损失区域。学习率预热(warmup)通过在若干步内从较小值线性增加到目标学习率,能显著降低初期震荡。
对于基于Transformer的3D骨干网络或大批量训练,warmup几乎是必须项。具体实现上,PyTorch提供LinearLR或手动调整学习率。以下代码将前5个epoch的学习率从目标值的十分之一线性提升,再切换到余弦退火。
import torch
from torch.optim import AdamW
from torch.optim.lr_scheduler import CosineAnnealingLR, LinearLR, SequentialLR
model = PointNetClassifier(num_classes=40)
optimizer = AdamW(model.parameters(), lr=3e-4, weight_decay=0.05)
warmup_epochs = 5
total_epochs = 120
warmup = LinearLR(optimizer, start_factor=0.1, end_factor=1.0, total_iters=warmup_epochs)
cosine = CosineAnnealingLR(optimizer, T_max=total_epochs - warmup_epochs)
scheduler = SequentialLR(optimizer, schedulers=[warmup, cosine], milestones=[warmup_epochs])
for epoch in range(total_epochs):
train_one_epoch(model, train_loader, optimizer)
val_loss = evaluate(model, val_loader)
scheduler.step()
print(f"epoch {epoch} lr {optimizer.param_groups[0]['lr']:.2e}, val_loss {val_loss:.4f}")
需要留意,在旧版PyTorch中SequentialLR调度器可能不存在,可以用自定义lambda函数替代。warmup步数通常根据总步数确定,点云分类任务建议设置为总步数的百分之五左右。从损失曲线看,如果前若干步出现损失突然上升,可以适当延长warmup。
训练中后期则要依赖衰减策略。余弦退火能在每个周期末尾把学习率降到接近零,帮助模型进入平坦的损失区域,泛化表现通常优于固定步长衰减。对于小数据集或容易过拟合的3D任务,余弦退火加多次重启(CosineAnnealingWarmRestarts)能获得更好的探索能力。若训练损失长期不动但学习率仍较大,可以使用ReduceLROnPlateau,在验证指标停止改善时自动降低学习率。
三、优化器选择:SGD、Adam、AdamW与LAMB
3D模型训练中,优化器选择需要结合梯度稀疏性、批量大小和模型结构。Adam及其变体对稀疏梯度更友好,点云网络中存在大量未被激活的ReLU单元,使用SGD时这些参数的梯度更新较慢。Adam通过二阶矩估计调整每个参数的学习率,使其在稀疏梯度下仍能保持稳定更新。不过原生Adam将权重衰减与梯度更新耦合在一起,会削弱L2正则化效果,导致泛化能力下降。
AdamW把权重衰减从梯度计算中解耦,直接对参数本身施加衰减。对于点云Transformer或可变形卷积等模型,AdamW通常比Adam更稳定,也更容易调参。权重衰减在3D任务中建议从0.01到0.05开始搜索。如果使用SGD,则需要搭配动量,学习率通常比Adam高一个数量级,例如从0.01开始,同时配合warmup和余弦退火。
大批量训练3D模型时,例如使用分布式数据并行把全局批量推高到数千,普通Adam或SGD可能难以收敛,此时可以尝试LAMB或LARS优化器。LAMB通过逐层自适应地控制更新幅度,在批量很大时仍能维持稳定。以下代码展示AdamW与SGD的参数配置差异。
import torch.optim as optim
# AdamW 配置,适合点云Transformer或稀疏梯度场景
optimizer_adamw = optim.AdamW(
model.parameters(),
lr=3e-4,
betas=(0.9, 0.999),
eps=1e-8,
weight_decay=0.05
)
# SGD 配置,适合需要更强泛化的小批量训练
optimizer_sgd = optim.SGD(
model.parameters(),
lr=0.01,
momentum=0.9,
nesterov=True,
weight_decay=1e-4
)
从经验上看,点云分类与分割任务优先使用AdamW,学习率在1e-4到1e-3区间搜索;神经辐射场训练常用Adam,学习率从5e-4开始逐步衰减;网格重建或符号距离场训练中,SGD加动量在低频几何结构上更容易收敛到光滑解。无论选择哪种优化器,都需要定期记录梯度范数,若梯度范数突然超过100,应启用梯度裁剪。
四、不收敛排查流程与快速实验矩阵
当训练不收敛时,建议按固定顺序排查。第一步确认数据加载正确,标签没有错位,坐标已经归一化。第二步使用小批量数据测试,如果模型在少量样本上都不能过拟合,说明网络实现或损失函数存在问题。第三步观察前200步损失曲线,如果损失没有下降或直接变为NaN,优先降低学习率并加入warmup。第四步检查优化器的权重衰减、beta和eps参数是否适合当前批量大小。
梯度裁剪是处理3D模型梯度爆炸的有效手段。点云数据中的异常点或体素中的高频结构会带来极端梯度,在反向传播后对梯度范数做裁剪可以避免参数跳变。以下代码给出一个常见的训练循环片段,其中包含梯度裁剪和动态学习率记录。
import torch.nn as nn
scaler = torch.cuda.amp.GradScaler(enabled=use_amp)
max_grad_norm = 1.0
for data, target in train_loader:
data, target = data.cuda(), target.cuda()
optimizer.zero_grad()
with torch.cuda.amp.autocast(enabled=use_amp):
output = model(data)
loss = criterion(output, target)
scaler.scale(loss).backward()
scaler.unscale_(optimizer)
nn.utils.clip_grad_norm_(model.parameters(), max_grad_norm)
scaler.step(optimizer)
scaler.update()
if torch.isnan(loss):
print("loss is NaN, reduce learning rate and check input scale")
break
注意代码中使用了混合精度,如果模型对数值稳定性敏感,可以暂时关闭自动混合精度,排除这一变量。另一个常见问题是学习率调度器触发时机错误,例如在每个batch都调用scheduler.step,而不是每个epoch。这样会把学习率提前衰减到极小,导致损失长期不变。检查调度器调用层级,确保warmup如果按epoch定义,则每个epoch只步进一次;如果按step定义,则需要使用StepLR或OneCycleLR的对应接口。
快速实验矩阵可以帮助在有限算力下定位问题。可以设计四组对照:AdamW加warmup加余弦退火、SGD加动量加余弦退火、AdamW加warmup加StepLR、关闭warmup只使用余弦退火。每组只训练20个epoch,比较损失下降速度和验证指标。若只有关闭warmup的组不收敛,说明初期更新过于剧烈;若SGD组明显慢于AdamW组,说明稀疏梯度是主要瓶颈。基于该矩阵可在较短时间内确定更合适的优化配置。
实际3D任务中,一个配置不一定在所有数据集上都收敛。因此建议将学习率、warmup步数、权重衰减和梯度裁剪阈值写入配置管理,用若干组小规模实验搜索后,再扩展到完整训练。训练稳定后再逐步提高批量或引入混合精度,能有效降低排查成本。