PyTorch无内置ModelCheckpoint,需手动监控验证Loss并用torch.save()保存最优权重;判断最优不能仅看Loss,应结合早停与过拟合风险,初始化best_val_loss为inf,每次验证后更新。

PyTorch里没有ModelCheckpoint,得自己写
PyTorch不像Keras那样内置 ModelCheckpoint 回调,所谓“配合ModelCheckpoint”是常见误解。实际要靠手动监控验证Loss、用 torch.save() 保存权重,再加一层逻辑判断是否为当前最优。
怎么判断“最优权重”:只看验证Loss够吗?
只比验证Loss容易踩坑——比如Loss微降但模型已过拟合,或早停没设好导致保存了震荡低谷点。更稳妥的做法是:
- 记录
best_val_loss初始值设为float('inf') - 每次验证后,用
if val_loss 更新并保存 - 可加容忍阈值(如
val_loss )避免浮点抖动误触发 - 强烈建议同时保存
epoch和val_loss到 checkpoint 字典里,方便后续排查
保存时该用 state_dict 还是整个模型?
必须用 model.state_dict(),别存整个模型对象。原因很实际:
- 存整个模型(
torch.save(model, ...))会把类定义、非参数属性甚至临时缓存一并序列化,加载时依赖原代码结构,换环境极易报AttributeError: 'XXX' object has no attribute 'yyy' -
state_dict只存参数张量,轻量、可移植、兼容性高;加载时只需新建模型实例再load_state_dict() - 记得保存优化器的
state_dict(如optimizer.state_dict()),否则恢复训练会丢动量等状态
保存路径和文件名怎么设计才不混乱?
别用固定名字如 best_model.pth —— 多次实验会覆盖。推荐带关键信息的命名:
- 包含模型名、数据集缩写、时间戳或seed,例如:
resnet18_cifar10_best_20240520_1423.pth - 路径统一放在
./checkpoints/下,训练前用os.makedirs('./checkpoints', exist_ok=True)确保目录存在 - 每次保存前先
torch.save(...),再删掉上一个最佳文件(可选),避免磁盘被旧checkpoint占满
最常被忽略的是:保存时没检查 val_loss 是否真在下降——比如验证集没 shuffle、batch size 不一致、或者用了 train 模式跑 eval,结果保存的“最优”其实是错的。动手前先 print 两轮 val_loss 看趋势,比调参还重要。











