学习率调优(上):学习率的作用、学习率对收敛的影响、固定学习率的陷阱

聊到模型训练,有个参数你绕不开——学习率。我见过不少新手,一上来就调网络结构、改损失函数,结果模型死活不收敛。最后查了半天,发现就是学习率设错了。说实话,学习率是整定过程中最基础、也最容易出问题的一环。

学习率到底在干什么?

简单说,学习率控制着模型参数更新的步长。梯度下降的公式大家应该都熟:

θ_new = θ_old - η * ∇L(θ_old)

这里的 η 就是学习率。它决定了每次沿着梯度方向走多远。步子太大容易扯着蛋,步子太小又走不动——嗯,就是这么个道理。

核心理解:学习率不是越大越好,也不是越小越好。它是在「收敛速度」和「收敛稳定性」之间找平衡。

学习率对收敛的影响

我在项目中遇到过这样一个案例:训练一个图像分类模型,初始学习率设成了 0.1。结果 loss 曲线像过山车一样上下震荡,就是不往下走。我当时还以为是数据有问题,排查了半天。后来把学习率降到 0.01,loss 立马就稳了。

为什么会这样?我们来看几种典型情况:

学习率设置 收敛表现 典型现象
过大(如 η > 1.0) 不收敛,甚至发散 loss 爆炸,出现 NaN
偏大(如 η = 0.1) 震荡收敛 loss 上下波动,收敛慢
适中(如 η = 0.01) 稳定收敛 loss 平滑下降
偏小(如 η = 0.0001) 收敛极慢 loss 下降缓慢,像蜗牛爬
过小(如 η < 1e-6) 几乎不收敛 loss 基本不变

你想想看,如果学习率太大,参数更新时直接跨过了最优点,甚至跳到了更差的位置。这就是震荡的根源。反过来,学习率太小,参数每次只挪动一点点,训练几百个 epoch 还在原地打转。

固定学习率的陷阱

很多初学者喜欢用固定学习率,觉得省事。我一开始也这么干过。但实际训练中,固定学习率有几个明显的坑:

  • 前期太慢,后期震荡:训练初期,参数离最优解很远,需要大步快走。但固定学习率不会自动调整,前期就显得磨叽。到了后期,参数接近最优点,固定学习率又容易导致在最优解附近来回震荡,就是进不去。
  • 对初始值敏感:固定学习率下,初始值选不好,模型可能直接废掉。我曾经试过用 0.1 的固定学习率训练一个深层网络,结果 loss 直接飞到了 1e10。嗯,那次教训挺深刻的。
  • 无法适应不同阶段:训练的不同阶段,最优学习率是不一样的。固定学习率等于一刀切,很难兼顾全局。

避坑指南:我曾经在一个 NLP 项目里用了固定学习率 0.001,训练了 200 个 epoch,loss 从 2.3 降到了 0.8 就再也不动了。后来换成余弦退火策略,同样的 epoch 数,loss 降到了 0.3。固定学习率的瓶颈,往往就在后期。

知识体系:学习率调优的核心逻辑

下面这张图,是我自己整理的学习率调优知识框架。你看一眼,心里就有数了:

学习率调优知识体系 学习率 (η) 核心作用 控制步长 影响收敛 对收敛的影响 过大 → 震荡/发散 适中 → 稳定收敛 过小 → 收敛极慢 固定学习率的陷阱 前期慢,后期震荡 对初始值敏感 无法适应不同阶段

一个简单的实验对比

为了让你更直观地理解,我写了个小脚本。用固定学习率训练一个简单的线性回归模型,分别试试 η=0.1、η=0.01、η=0.001 的效果:

import numpy as np
import matplotlib.pyplot as plt

# 生成数据
np.random.seed(42)
X = 2 * np.random.rand(100, 1)
y = 4 + 3 * X + np.random.randn(100, 1)

# 梯度下降
def train(lr, epochs=50):
    theta = np.random.randn(2, 1)
    losses = []
    for _ in range(epochs):
        gradients = 2/100 * X.T.dot(X.dot(theta) - y)
        theta -= lr * gradients
        loss = np.mean((X.dot(theta) - y)**2)
        losses.append(loss)
    return losses

losses_01 = train(0.1)
losses_001 = train(0.01)
losses_0001 = train(0.001)

# 结果:lr=0.1 震荡明显,lr=0.01 平滑下降,lr=0.001 下降缓慢

跑完之后你会发现,η=0.1 那条线像心电图一样上下跳,η=0.001 那条线几乎平躺,只有 η=0.01 稳稳地降到了最低点。这就是固定学习率的典型表现——你很难找到一个值,同时满足前期和后期。

个人经验:我一般会先用 0.01 或 0.001 作为初始试探值。观察 loss 曲线:如果震荡明显,就降一个数量级;如果下降太慢,就升一个数量级。说白了,学习率调优就是个「试错 + 观察」的过程。

好了,这一节我们聊了学习率的作用、它对收敛的影响,以及固定学习率的几个典型陷阱。下一节我会接着讲学习率衰减策略——那才是真正解决这些问题的利器。

可可精品资料库