4. 训练过程可视化:Loss曲线分析、Accuracy曲线分析、学习率调度可视化、过拟合与欠拟合诊断

训练一个模型,就像看着一个孩子长大。你得盯着他的成绩单,看他是不是在进步,有没有走偏。我个人习惯,训练时必开可视化面板。没有曲线,我根本不敢说自己了解模型的状态。

这一章,咱们就聊聊怎么从曲线里读出模型的「心事」。说白了,就是通过Loss、Accuracy、学习率这些曲线,诊断模型到底是欠拟合、过拟合,还是刚刚好。

4.1 Loss曲线:模型的学习日记

Loss曲线是最直接的反馈。它告诉你,模型在训练集上犯的错是不是越来越小。

核心原则:Loss下降,说明模型在学习。Loss震荡或上升,说明出问题了。

4.1.1 正常的Loss曲线长什么样?

一个健康的训练过程,Loss曲线应该是这样的:

  • 快速下降期:训练刚开始,模型啥都不懂,Loss从高位快速下降。这很正常。
  • 缓慢收敛期:过了几百步,下降速度变慢,曲线趋于平滑。模型开始精调参数了。
  • 平稳期:最后Loss在一个小范围内波动,不再明显下降。说明模型已经收敛。

我在项目中遇到过,有个同事看到Loss下降慢了,就急着调学习率。其实没必要,只要曲线还在下降,哪怕很慢,也是好事。

4.1.2 异常Loss曲线诊断

曲线形态 可能原因 我的建议
Loss 不下降,一直很高 学习率太小、模型容量不够、数据没归一化 先调大学习率试试,不行就换大模型
Loss 突然飙升 梯度爆炸、数据出现异常值、学习率太大 赶紧暂停,检查梯度范数,考虑梯度裁剪
Loss 剧烈震荡 batch size 太小、学习率太大、数据噪声多 增大 batch size,或者用学习率预热
Loss 先降后升 过拟合开始、学习率调度不当 加入正则化,或者降低学习率

注意:千万不要只看训练Loss。训练Loss低不代表模型好。你得结合验证集Loss一起看。

4.2 Accuracy曲线:模型的实际表现

Loss是内部指标,Accuracy是外部表现。有时候Loss降了,Accuracy没涨,那可能是模型在「死记硬背」。

4.2.1 训练集 vs 验证集 Accuracy

我建议你同时画两条Accuracy曲线:训练集和验证集。对比着看,信息量很大。

  • 两条曲线同步上升:理想状态。模型在学真本事。
  • 训练集高,验证集低:典型的过拟合。模型把训练数据背下来了,但没理解规律。
  • 两条曲线都低:欠拟合。模型太简单,学不动。
  • 验证集突然下降:可能数据分布变了,或者模型开始「遗忘」之前学的东西。

小技巧:如果验证集Accuracy在某个epoch后开始下降,而训练集还在上升,这就是「早停」的信号。我曾经因为这个判断失误,多训了50个epoch,结果模型反而变差了。

4.3 学习率调度可视化

学习率是训练过程中最敏感的超参数。调得好,事半功倍;调不好,事倍功半。

4.3.1 常见的学习率调度策略

策略 特点 适用场景
固定学习率 简单,但容易陷入局部最优 小数据集、简单任务
Step Decay 每隔N个epoch减半 分类任务,效果稳定
Cosine Annealing 余弦下降,带重启 大规模训练,能跳出局部最优
ReduceLROnPlateau Loss不降了,就降低学习率 自适应,省心

我个人习惯用Cosine Annealing加预热。前期学习率小,让模型稳定起步;中期大学习率快速探索;后期再降下来精细调整。效果比固定学习率好不少。

4.3.2 可视化学习率变化

把学习率的变化画出来,和Loss曲线放在一起看。你会发现,学习率下降时,Loss往往会跟着波动一下。这是正常的。但如果波动太大,说明学习率降得太快了。

经验之谈:学习率调度不是越复杂越好。我见过有人用10种策略组合,结果调参调了两个月。先试试ReduceLROnPlateau,简单有效。

4.4 过拟合与欠拟合诊断

这是训练过程中最常遇到的问题。怎么判断?看曲线对比。

4.4.1 过拟合的典型特征

  • 训练Loss持续下降,验证Loss先降后升
  • 训练Accuracy接近100%,验证Accuracy停滞或下降
  • 模型在训练集上表现完美,但测试集上表现差

我曾经在一个图像分类项目里,模型在训练集上达到了99%的准确率,但验证集只有72%。一看曲线,训练Loss都快到0了,验证Loss却在上升。典型的过拟合。后来加了Dropout和数据增强,才把差距缩小到5%以内。

4.4.2 欠拟合的典型特征

  • 训练Loss和验证Loss都高,且不再下降
  • 训练Accuracy和验证Accuracy都低
  • 模型在训练集上就表现不好

欠拟合相对好解决。加层数、加宽度、减少正则化、增大学习率,总有一款适合你。

4.4.3 诊断流程图

下面这张图,是我自己总结的诊断流程。每次训练出问题,我就按这个走一遍。

过拟合与欠拟合诊断流程图 过拟合与欠拟合诊断流程图 训练完成,查看曲线 训练Loss vs 验证Loss 两者都高 欠拟合 训练低,验证高 过拟合 两者都低 正常,继续训练 解决方案: 增加模型容量 减少正则化,增大学习率 解决方案: 增加正则化(Dropout/L2) 数据增强,早停 提示:过拟合和欠拟合可以同时存在 比如模型在某些类别上过拟合,某些类别上欠拟合

4.5 实战:用TensorBoard可视化训练过程

说了这么多理论,咱们来点实际的。TensorBoard是我最常用的可视化工具。怎么用?

4.5.1 记录Loss和Accuracy

from torch.utils.tensorboard import SummaryWriter

writer = SummaryWriter('runs/experiment_1')

for epoch in range(num_epochs):
    train_loss = train_one_epoch(model, train_loader)
    val_loss, val_acc = evaluate(model, val_loader)
    
    writer.add_scalar('Loss/train', train_loss, epoch)
    writer.add_scalar('Loss/val', val_loss, epoch)
    writer.add_scalar('Accuracy/val', val_acc, epoch)
    
writer.close()

4.5.2 记录学习率

for epoch in range(num_epochs):
    current_lr = scheduler.get_last_lr()[0]
    writer.add_scalar('Learning_rate', current_lr, epoch)
    
    # 训练代码...
    scheduler.step()

我的习惯:每次实验都新建一个文件夹,把超参数、模型结构、训练曲线都存进去。这样回头复盘时,一眼就能看出哪个实验跑偏了。

4.6 总结:可视化诊断清单

每次训练完,我都会对照这个清单检查一遍:

  1. Loss曲线:是否平滑下降?有没有异常震荡或上升?
  2. Accuracy曲线:训练集和验证集是否同步?差距大不大?
  3. 学习率曲线:变化是否合理?有没有导致Loss剧烈波动?
  4. 过拟合判断:验证Loss是否先降后升?
  5. 欠拟合判断:两条Loss曲线是否都居高不下?

嗯,这套流程我用了好几年,基本没出过大错。你试试看,肯定能帮你省下不少调试时间。